From 6c0508cce48a717b8a746fec3738a145930628f0 Mon Sep 17 00:00:00 2001 From: Yehor Popovych Date: Thu, 30 May 2024 19:00:49 +0100 Subject: [PATCH] added account check. fixed ui tests --- src/commands/signtx/operations/stx_op_p2pk.c | 8 +++-- src/commands/signtx/stx_output.h | 5 +++ src/common/bip32_ext.h | 8 +++++ tests/helpers/data.js | 6 ++++ tests/transaction-tests.js | 37 +++++++++++++++++--- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/commands/signtx/operations/stx_op_p2pk.c b/src/commands/signtx/operations/stx_op_p2pk.c index d698b045..13025c06 100644 --- a/src/commands/signtx/operations/stx_op_p2pk.c +++ b/src/commands/signtx/operations/stx_op_p2pk.c @@ -306,12 +306,16 @@ bool stx_operation_p2pk_should_show_output_confirm_screen( BIP32_HARDENED(BIP32_ERGO_COIN), BIP32_PATH_VALIDATE_ADDRESS_E5)) return true; - // if change index is < 20 then we approve it automatically - if (ctx->transaction.ui.output.bip32_path.path[4] < 20) return false; // Check was it already approved then approve automatically if (stx_bip32_path_is_equal(&ctx->transaction.ui.output.bip32_path, &ctx->transaction.last_approved_change)) return false; + // if account is the same and change index is < 20 then we approve it automatically + if (stx_bip32_path_same_account(&ctx->transaction.ui.output.bip32_path, + &ctx->bip32) && + ctx->transaction.ui.output.bip32_path.path[4] < 20) + return false; + } return true; } diff --git a/src/commands/signtx/stx_output.h b/src/commands/signtx/stx_output.h index ff0b3abc..8f83b111 100644 --- a/src/commands/signtx/stx_output.h +++ b/src/commands/signtx/stx_output.h @@ -87,4 +87,9 @@ static inline bool stx_output_info_is_finished(const sign_transaction_output_inf static inline bool stx_bip32_path_is_equal(const sign_transaction_bip32_path_t* p1, const sign_transaction_bip32_path_t* p2) { return bip32_path_is_equal(p1->path, p1->len, p2->path, p2->len); +} + +static inline bool stx_bip32_path_same_account(const sign_transaction_bip32_path_t* p1, + const sign_transaction_bip32_path_t* p2) { + return bip32_path_same_account(p1->path, p1->len, p2->path, p2->len); } \ No newline at end of file diff --git a/src/common/bip32_ext.h b/src/common/bip32_ext.h index efbdbab3..9436c997 100644 --- a/src/common/bip32_ext.h +++ b/src/common/bip32_ext.h @@ -27,4 +27,12 @@ static inline bool bip32_path_is_equal(const uint32_t *bip32_path_1, uint8_t bip32_path_2_len) { return bip32_path_1_len == bip32_path_2_len && memcmp(bip32_path_1, bip32_path_2, bip32_path_1_len) == 0; +} + +static inline bool bip32_path_same_account(const uint32_t *bip32_path_1, + uint8_t bip32_path_1_len, + const uint32_t *bip32_path_2, + uint8_t bip32_path_2_len) { + return bip32_path_1_len >= 3 && bip32_path_2_len >= 3 && + memcmp(bip32_path_1, bip32_path_2, 3) == 0; } \ No newline at end of file diff --git a/tests/helpers/data.js b/tests/helpers/data.js index 82479b15..398a84e1 100644 --- a/tests/helpers/data.js +++ b/tests/helpers/data.js @@ -13,6 +13,7 @@ class ExtendedAddress { this.network = network; this.address = address; this.path = DerivationPath.new(path[0], [path[1]]); + this.index = path[1]; } toBase58() { @@ -47,6 +48,11 @@ class TestData { Address.from_base58("9eo8hALVQTaAuu8m95JhR8rhXuAMsLacaxM8X4omp724Smt8ior"), [0, 2] ); + this.changeAddress22 = new ExtendedAddress( + network, + Address.from_base58("9fRejXDJxxdJ1KVRH6HdxDj1S1duKmUNGG7CjztN2YjHnooxYAX"), + [0, 22] + ); } } diff --git a/tests/transaction-tests.js b/tests/transaction-tests.js index f63a8872..b5ada157 100644 --- a/tests/transaction-tests.js +++ b/tests/transaction-tests.js @@ -6,7 +6,8 @@ const { TEST_DATA } = require('./helpers/data'); const { AuthTokenFlows } = require('./helpers/flow'); const { UnsignedTransactionBuilder } = require('./helpers/transaction'); -const signTxFlowCount = [5, 5]; +const signTxFlowCount = [4, 4]; +const signTxFlowCount22 = [signTxFlowCount[0]+1, signTxFlowCount[1]+1]; function signTxFlows({ model, device }, auth, from, to, change, tokens = undefined) { const flows = [ @@ -50,6 +51,9 @@ function signTxFlows({ model, device }, auth, from, to, change, tokens = undefin flows[0].splice(1, 0, { header: 'Application', body: getApplication(device) }); flows[1].splice(1, 1); } + if (change.index <= 19) { + flows.splice(3, 1); + } return flows; }; @@ -124,6 +128,31 @@ describe("Transaction Tests", function () { } ); + new AuthTokenFlows("can sign tx change 22", () => { + const from = TEST_DATA.address0; + const to = TEST_DATA.address1; + const change = TEST_DATA.changeAddress22; + const builder = new UnsignedTransactionBuilder() + .input(from, TxId.zero(), 0) + .dataInput(from.address, TxId.zero(), 0) + .output('100000000', to.address) + .fee('1000000') + .change(change); + return { from, to, change, builder }; + }, signTxFlowCount22).do( + function () { + const unsignedTransaction = this.builder.build(); + return this.test.device.signTx(unsignedTransaction, toNetwork(TEST_DATA.network)) + }, + function (signatures) { + let flows = signTxFlows(this.test, this.auth, this.from, this.to, this.change); + expect(this.flows).to.be.deep.equal(flows); + expect(signatures).to.have.length(1); + const ergoBox = this.builder.ergoBuilder.inputs.get(0); + verifySignatures(this.builder.ergoTransaction, signatures, ergoBox); + } + ); + new AuthTokenFlows("can sign tx with additional registers", () => { const from = TEST_DATA.address0; const to = TEST_DATA.address1; @@ -299,7 +328,7 @@ describe("Transaction Tests", function () { { header: 'Token [1] Value', body: 'Burning: 1000' } ]; let flows = signTxFlows(this.test, this.auth, this.from, this.to, this.change); - flows[4].splice(4, 0, ...tokens); + flows[flows.length-1].splice(4, 0, ...tokens); expect(this.flows).to.be.deep.equal(flows); expect(signatures).to.have.length(1); } @@ -331,7 +360,7 @@ describe("Transaction Tests", function () { { header: 'Token [1] Value', body: '1000' } ]; let flows = signTxFlows(this.test, this.auth, this.from, this.to, this.change, tokens); - flows[4].splice(4, 0, ...[ + flows[flows.length-1].splice(4, 0, ...[ { header: 'Token [1]', body: ellipsize(this.test.model, this.tokenId.to_str()) }, { header: 'Token [1] Value', body: 'Minting: 1000' } ]); @@ -372,7 +401,7 @@ describe("Transaction Tests", function () { { header: 'Token [1] Value', body: '1000' } ]; let flows = signTxFlows(this.test, this.auth, this.from, this.to, this.change, tokens); - flows[4].splice(4, 0, ...[ + flows[flows.length-1].splice(4, 0, ...[ { header: 'Token [1]', body: ellipsize(this.test.model, this.tokenId.to_str()) }, { header: 'Token [1] Value', body: 'Burning: 1000' }, { header: 'Token [2]', body: ellipsize(this.test.model, this.tokenId2.to_str()) },