From 9c23cd40cf92d2a2a42b5d06689422162c32b950 Mon Sep 17 00:00:00 2001 From: Behrang Norouzinia Date: Sun, 15 Oct 2023 14:51:23 +0330 Subject: [PATCH 1/3] Improve gas usage by using ifnot --- contracts/wallet_v5.fc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/wallet_v5.fc b/contracts/wallet_v5.fc index f7d8c10..c63e2ac 100644 --- a/contracts/wallet_v5.fc +++ b/contracts/wallet_v5.fc @@ -128,7 +128,7 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) ;; Authenticate extension by its address. int packed_sender_addr = pack_address(parse_std_addr(full_msg_slice~load_msg_addr())); var (_, success?) = extensions.udict_get?(256, packed_sender_addr); - if ~(success?) { + ifnot (success?) { ;; Note that some random contract may have deposited funds with this prefix, ;; so we accept the funds silently instead of throwing an error (wallet v4 does the same). return (); From d6aaba618ec0951b2f938165f7732bfe46366372 Mon Sep 17 00:00:00 2001 From: Behrang Norouzinia Date: Sun, 15 Oct 2023 18:22:00 +0330 Subject: [PATCH 2/3] Optimize usage of set_data --- contracts/wallet_v5.fc | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/contracts/wallet_v5.fc b/contracts/wallet_v5.fc index c63e2ac..841d84d 100644 --- a/contracts/wallet_v5.fc +++ b/contracts/wallet_v5.fc @@ -13,7 +13,7 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) () set_actions(cell action_list) impure asm "c5 POP"; ;; Dispatches already authenticated request. -() dispatch_request(slice cs, int stored_seqno, int stored_subwallet, int public_key, cell extensions) impure inline { +() dispatch_request(slice cs, cell extensions) impure inline { ;; Recurse into extended actions until we reach standard actions while (cs~load_uint(1)) { @@ -31,19 +31,18 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) ;; Add extension if (op == 0x1c40db9f) { - (extensions, int success?) = extensions.udict_add_builder?(256, packed_addr, begin_cell().store_int(wc,8)); + int success? = extensions~udict_add_builder?(256, packed_addr, begin_cell().store_int(wc, 8)); throw_unless(39, success?); } ;; Remove extension if (op == 0x5eaef4a4) { - (extensions, int success?) = extensions.udict_delete?(256, packed_addr); + int success? = extensions~udict_delete?(256, packed_addr); throw_unless(40, success?); } + var data_prefix = get_data().begin_parse().preload_bits(32 + 80 + 256); set_data(begin_cell() - .store_uint(stored_seqno, 32) - .store_uint(stored_subwallet, 80) - .store_uint(public_key, 256) + .store_slice(data_prefix) .store_dict(extensions) .end_cell()); } @@ -59,7 +58,7 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) } ;; Verifies signed request, prevents replays and proceeds with `dispatch_request`. -() process_signed_request(slice body, int stored_seqno, int stored_subwallet, int public_key, cell extensions) impure inline { +() process_signed_request(slice body, slice data_suffix, int stored_seqno, int stored_subwallet, int public_key, cell extensions) impure inline { var signature = body~load_bits(512); var cs = body; var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(80), cs~load_uint(32), cs~load_uint(32)); @@ -75,23 +74,23 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) stored_seqno = stored_seqno + 1; set_data(begin_cell() .store_uint(stored_seqno, 32) - .store_uint(stored_subwallet, 80) - .store_uint(public_key, 256) - .store_dict(extensions) + .store_slice(data_suffix) .end_cell()); commit(); - dispatch_request(cs, stored_seqno, stored_subwallet, public_key, extensions); + dispatch_request(cs, extensions); } () recv_external(slice body) impure { var ds = get_data().begin_parse(); - var (stored_seqno, stored_subwallet, public_key, extensions) = (ds~load_uint(32), ds~load_uint(80), ds~load_uint(256), ds~load_dict()); + var stored_seqno = ds~load_uint(32); + var data_suffix = ds; + var (stored_subwallet, public_key, extensions) = (ds~load_uint(80), ds~load_uint(256), ds~load_dict()); ds.end_parse(); int auth_kind = body~load_uint(32); if (auth_kind == 0x7369676E) { ;; "sign" - process_signed_request(body, stored_seqno, stored_subwallet, public_key, extensions); + process_signed_request(body, data_suffix, stored_seqno, stored_subwallet, public_key, extensions); } else { ;; FIXME: probably need to throw here? return (); @@ -121,7 +120,9 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) } var ds = get_data().begin_parse(); - var (stored_seqno, stored_subwallet, public_key, extensions) = (ds~load_uint(32), ds~load_uint(80), ds~load_uint(256), ds~load_dict()); + var stored_seqno = ds~load_uint(32); + var data_suffix = ds; + var (stored_subwallet, public_key, extensions) = (ds~load_uint(80), ds~load_uint(256), ds~load_dict()); ds.end_parse(); if (auth_kind == 0x6578746E) { ;; "extn" @@ -133,11 +134,11 @@ int pack_address(int wc, int hash) impure asm "SWAP INC XOR"; ;; hash ^ (wc+1) ;; so we accept the funds silently instead of throwing an error (wallet v4 does the same). return (); } - dispatch_request(body, stored_seqno, stored_subwallet, public_key, extensions); + dispatch_request(body, extensions); } if (auth_kind == 0x7369676E) { ;; "sign" ;; Process the rest of the slice just like the signed request. - process_signed_request(body, stored_seqno, stored_subwallet, public_key, extensions); + process_signed_request(body, data_suffix, stored_seqno, stored_subwallet, public_key, extensions); } } From a80ceb5f8d6a26e122f1761a0a4af52de6db53a2 Mon Sep 17 00:00:00 2001 From: Behrang Norouzinia Date: Sun, 15 Oct 2023 19:01:49 +0330 Subject: [PATCH 3/3] Fix typo in test names --- tests/wallet-v5-extensions.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/wallet-v5-extensions.spec.ts b/tests/wallet-v5-extensions.spec.ts index f6df833..4ef11d7 100644 --- a/tests/wallet-v5-extensions.spec.ts +++ b/tests/wallet-v5-extensions.spec.ts @@ -79,7 +79,7 @@ describe('Wallet V5 extensions auth', () => { seqno = 0; }); - it('Do a transfer form extension', async () => { + it('Do a transfer from extension', async () => { await walletV5.sendInternalSignedMessage(sender, { value: toNano(0.1), body: createBody(packActionsList([new ActionAddExtension(sender.address!)])) @@ -118,7 +118,7 @@ describe('Wallet V5 extensions auth', () => { expect(receiverBalanceAfter).toEqual(receiverBalanceBefore + forwardValue - fee); }); - it('Do two transfers form extension and add other extension', async () => { + it('Do two transfers from extension and add other extension', async () => { await walletV5.sendInternalSignedMessage(sender, { value: toNano(0.1), body: createBody(packActionsList([new ActionAddExtension(sender.address!)])) @@ -187,7 +187,7 @@ describe('Wallet V5 extensions auth', () => { ); }); - it('Add and remove other extension form extension', async () => { + it('Add and remove other extension from extension', async () => { await walletV5.sendInternalSignedMessage(sender, { value: toNano(0.1), body: createBody(packActionsList([new ActionAddExtension(sender.address!)]))