Skip to content

Commit

Permalink
NFT standard refund account storage based on actual size (#300)
Browse files Browse the repository at this point in the history
* NFT standard refund account storage based on the actual size
  • Loading branch information
ailisp authored Nov 15, 2022
1 parent 3f170ec commit 43ca465
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 56 deletions.
4 changes: 2 additions & 2 deletions examples/__tests__/standard-nft/test_approval.ava.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ test("Simple approve", async (t) => {
msg: null,
},
{
attachedDeposit: "450000000000000000000",
attachedDeposit: "550000000000000000000",
}
);
t.assert(res.result.status.SuccessValue);
Expand All @@ -165,7 +165,7 @@ test("Approve call", async (t) => {
account_id: approvalReceiver.accountId,
msg: "return-now",
},
{ attachedDeposit: "450000000000000000000", gas: "300 Tgas" }
{ attachedDeposit: "550000000000000000000", gas: "300 Tgas" }
);
t.is(res, "cool");

Expand Down
22 changes: 14 additions & 8 deletions near-contract-standards/lib/non_fungible_token/impl.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions near-contract-standards/lib/non_fungible_token/utils.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 1 addition & 11 deletions near-contract-standards/lib/non_fungible_token/utils.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 28 additions & 10 deletions near-contract-standards/src/non_fungible_token/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ import {
} from "near-sdk-js";
import { TokenMetadata } from "./metadata";
import {
refund_approved_account_ids,
refund_storage_deposit,
refund_deposit,
refund_deposit_to_account,
assert_at_least_one_yocto,
IntoStorageKey,
Option,
bytes_for_approved_account_id,
assert_one_yocto,
refund_approved_account_ids_iter,
} from "./utils";
import { NftMint, NftTransfer } from "./events";
import { NonFungibleTokenResolver } from "./core/resolver";
Expand Down Expand Up @@ -199,15 +197,18 @@ export class NonFungibleToken
const next_approval_id_by_id = expect_approval(this.next_approval_id_by_id);
const approved_account_ids = approvals_by_id.get(token_id) ?? {};
const approval_id = next_approval_id_by_id.get(token_id) ?? 1n;
const old_approval_id = approved_account_ids[account_id];
const old_approved_account_ids_size =
serialize(approved_account_ids).length;
approved_account_ids[account_id] = approval_id;
const new_approved_account_ids_size =
serialize(approved_account_ids).length;

approvals_by_id.set(token_id, approved_account_ids);

next_approval_id_by_id.set(token_id, approval_id + 1n);

const storage_used =
old_approval_id === null ? bytes_for_approved_account_id(account_id) : 0;
new_approved_account_ids_size - old_approved_account_ids_size;
refund_deposit(BigInt(storage_used));

if (msg) {
Expand Down Expand Up @@ -242,15 +243,23 @@ export class NonFungibleToken
);

const approved_account_ids = approvals_by_id.get(token_id);
const old_approved_account_ids_size =
serialize(approved_account_ids).length;
let new_approved_account_ids_size;

if (approved_account_ids[account_id]) {
delete approved_account_ids[account_id];
refund_approved_account_ids_iter(predecessorAccountId, [account_id]);

if (Object.keys(approved_account_ids).length === 0) {
approvals_by_id.remove(token_id);
new_approved_account_ids_size = serialize(approved_account_ids).length;
} else {
approvals_by_id.set(token_id, approved_account_ids);
new_approved_account_ids_size = 0;
}
refund_storage_deposit(
predecessorAccountId,
new_approved_account_ids_size - old_approved_account_ids_size
);
}
}

Expand All @@ -270,7 +279,10 @@ export class NonFungibleToken

const approved_account_ids = approvals_by_id.get(token_id);
if (approved_account_ids) {
refund_approved_account_ids(predecessorAccountId, approved_account_ids);
refund_storage_deposit(
predecessorAccountId,
serialize(approved_account_ids).length
);

approvals_by_id.remove(token_id);
}
Expand Down Expand Up @@ -708,7 +720,10 @@ export class NonFungibleToken
}
} else {
if (approved_account_ids) {
refund_approved_account_ids(previous_owner_id, approved_account_ids);
refund_storage_deposit(
previous_owner_id,
serialize(approved_account_ids).length
);
}
return true;
}
Expand All @@ -718,7 +733,10 @@ export class NonFungibleToken
if (this.approvals_by_id) {
const receiver_approvals = this.approvals_by_id.get(token_id);
if (receiver_approvals) {
refund_approved_account_ids(receiver_id, receiver_approvals);
refund_storage_deposit(
receiver_id,
serialize(receiver_approvals).length
);
}
if (approved_account_ids) {
this.approvals_by_id.set(token_id, approved_account_ids);
Expand Down
22 changes: 2 additions & 20 deletions near-contract-standards/src/non_fungible_token/utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import { near, assert, Bytes, AccountId } from "near-sdk-js";

export function bytes_for_approved_account_id(account_id: AccountId): number {
// The extra 4 bytes are coming from Borsh serialization to store the length of the string.
return account_id.length + 4 + 8;
}

export function refund_approved_account_ids_iter(
export function refund_storage_deposit(
account_id: AccountId,
approved_account_ids: AccountId[]
storage_released: number
): void {
const storage_released = approved_account_ids
.map(bytes_for_approved_account_id)
.reduce((a, b) => a + b);
const promise_id = near.promiseBatchCreate(account_id);
near.promiseBatchActionTransfer(
promise_id,
Expand All @@ -20,16 +12,6 @@ export function refund_approved_account_ids_iter(
near.promiseReturn(promise_id);
}

export function refund_approved_account_ids(
account_id: AccountId,
approved_account_ids: { [approvals: AccountId]: bigint }
) {
refund_approved_account_ids_iter(
account_id,
Array.from(Object.keys(approved_account_ids))
);
}

export function refund_deposit_to_account(
storage_used: bigint,
account_id: AccountId
Expand Down

0 comments on commit 43ca465

Please sign in to comment.