From 6b441d384402c8994e15cdf91e14834c1862b74c Mon Sep 17 00:00:00 2001 From: viktorb-ledger <94441294+viktorb-ledger@users.noreply.github.com> Date: Thu, 17 Feb 2022 15:42:52 +0100 Subject: [PATCH] Add segwit tests (#854) * Remove BitcoinLikeTransactionBuilder::addInput * Add send to P2WPKH and P2WSH tests * An attempt to fix "ComputeOperationUidWithValidTransaction" --- .../wallet/bitcoin/bitcoin_like_wallet.djinni | 13 +- core/src/api/BitcoinLikeTransaction.hpp | 4 +- .../src/api/BitcoinLikeTransactionBuilder.hpp | 11 +- .../jni/jni/BitcoinLikeTransactionBuilder.cpp | 12 -- .../BitcoinLikeTransactionBuilder.cpp | 16 +-- .../BitcoinLikeTransactionBuilder.h | 2 - core/test/fixtures/txes_to_wpkh._fixtures.cpp | 31 +++++ core/test/fixtures/txes_to_wpkh_fixtures.h | 41 ++++++ ...veSegwit.CreateStandardP2WPKHWithOneOutput | 10 ++ ...cyToP2WSH.CreateStandardP2WSHWithOneOutput | 10 ++ ...veSegwit.CreateStandardP2WPKHWithOneOutput | 10 ++ ...itToP2WSH.CreateStandardP2WSHWithOneOutput | 10 ++ .../bitcoin_P2WPKH_transaction_tests.cpp | 127 +++++++++++++++--- .../bitcoin_P2WSH_transaction_tests.cpp | 126 ++++++++++++++--- .../transactions/coin_selection_P2PKH.cpp | 6 +- .../transactions/transaction_test_helper.cpp | 83 ++++++++++++ .../transactions/transaction_test_helper.h | 27 +++- core/test/tezos/tezos_account.cpp | 17 ++- core/test/tezos/transaction_test.hpp | 8 +- 19 files changed, 469 insertions(+), 95 deletions(-) create mode 100644 core/test/fixtures/txes_to_wpkh._fixtures.cpp create mode 100644 core/test/fixtures/txes_to_wpkh_fixtures.h create mode 100644 core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToNativeSegwit.CreateStandardP2WPKHWithOneOutput create mode 100644 core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToP2WSH.CreateStandardP2WSHWithOneOutput create mode 100644 core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToNativeSegwit.CreateStandardP2WPKHWithOneOutput create mode 100644 core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToP2WSH.CreateStandardP2WSHWithOneOutput diff --git a/core/idl/wallet/bitcoin/bitcoin_like_wallet.djinni b/core/idl/wallet/bitcoin/bitcoin_like_wallet.djinni index 35df0921ac..7df9fe5e45 100644 --- a/core/idl/wallet/bitcoin/bitcoin_like_wallet.djinni +++ b/core/idl/wallet/bitcoin/bitcoin_like_wallet.djinni @@ -181,11 +181,11 @@ BitcoinLikeTransaction = interface +c { # through the full ledger stack # @return the OLD Correlation ID, if it was set (empty string if it was unset) setCorrelationId(correlationId : string) : string; - # Sign all inputs for given transaction. + # Sign all inputs for given transaction. # Build DER encoded signature from RSV data. # @return SIGNING_SUCCEED if succeed case else refers to BitcoinLikeSignatureState enumeration setSignatures(signatures: list, override: bool): BitcoinLikeSignatureState; - # Sign all inputs for given transaction. + # Sign all inputs for given transaction. # @return SIGNING_SUCCEED if succeed case else refers to BitcoinLikeSignatureState enumeration setDERSignatures(signatures: list, override: bool): BitcoinLikeSignatureState; } @@ -235,13 +235,6 @@ BitcoinLikePickingStrategy = enum { } BitcoinLikeTransactionBuilder = interface +c { - # Add the given input to the final transaction. - # @param transactionhash The hash of the transaction in where the UTXO can be located. - # @params index Index of the UTXO in the previous transaction - # @params sequence Sequence number to add at the end of the input serialization. This can be used for RBF transaction - # @return A reference on the same builder in order to chain calls. - addInput(transactionHash: string, index: i32, sequence: i32): BitcoinLikeTransactionBuilder; - # Add the given output to the final transaction. # @return A reference on the same builder in order to chain calls. addOutput(amount: Amount, script: BitcoinLikeScript): BitcoinLikeTransactionBuilder; @@ -303,7 +296,7 @@ BitcoinLikeTransactionBuilder = interface +c { reset(); # Set the correlation id which can be used to debug transaction errors - # through the full ledger stack + # through the full ledger stack # @return A reference on the same builder in order to chain calls. setCorrelationId(correlationId : string) : BitcoinLikeTransactionBuilder; diff --git a/core/src/api/BitcoinLikeTransaction.hpp b/core/src/api/BitcoinLikeTransaction.hpp index 2a027c615f..886f3e580b 100644 --- a/core/src/api/BitcoinLikeTransaction.hpp +++ b/core/src/api/BitcoinLikeTransaction.hpp @@ -92,14 +92,14 @@ class LIBCORE_EXPORT BitcoinLikeTransaction { virtual std::string setCorrelationId(const std::string & correlationId) = 0; /** - * Sign all inputs for given transaction. + * Sign all inputs for given transaction. * Build DER encoded signature from RSV data. * @return SIGNING_SUCCEED if succeed case else refers to BitcoinLikeSignatureState enumeration */ virtual BitcoinLikeSignatureState setSignatures(const std::vector & signatures, bool override) = 0; /** - * Sign all inputs for given transaction. + * Sign all inputs for given transaction. * @return SIGNING_SUCCEED if succeed case else refers to BitcoinLikeSignatureState enumeration */ virtual BitcoinLikeSignatureState setDERSignatures(const std::vector> & signatures, bool override) = 0; diff --git a/core/src/api/BitcoinLikeTransactionBuilder.hpp b/core/src/api/BitcoinLikeTransactionBuilder.hpp index 530ea68413..e1ba02f968 100644 --- a/core/src/api/BitcoinLikeTransactionBuilder.hpp +++ b/core/src/api/BitcoinLikeTransactionBuilder.hpp @@ -30,15 +30,6 @@ class LIBCORE_EXPORT BitcoinLikeTransactionBuilder { public: virtual ~BitcoinLikeTransactionBuilder() {} - /** - * Add the given input to the final transaction. - * @param transactionhash The hash of the transaction in where the UTXO can be located. - * @params index Index of the UTXO in the previous transaction - * @params sequence Sequence number to add at the end of the input serialization. This can be used for RBF transaction - * @return A reference on the same builder in order to chain calls. - */ - virtual std::shared_ptr addInput(const std::string & transactionHash, int32_t index, int32_t sequence) = 0; - /** * Add the given output to the final transaction. * @return A reference on the same builder in order to chain calls. @@ -123,7 +114,7 @@ class LIBCORE_EXPORT BitcoinLikeTransactionBuilder { /** * Set the correlation id which can be used to debug transaction errors - * through the full ledger stack + * through the full ledger stack * @return A reference on the same builder in order to chain calls. */ virtual std::shared_ptr setCorrelationId(const std::string & correlationId) = 0; diff --git a/core/src/jni/jni/BitcoinLikeTransactionBuilder.cpp b/core/src/jni/jni/BitcoinLikeTransactionBuilder.cpp index 4b55733c64..d633a9528c 100644 --- a/core/src/jni/jni/BitcoinLikeTransactionBuilder.cpp +++ b/core/src/jni/jni/BitcoinLikeTransactionBuilder.cpp @@ -25,18 +25,6 @@ CJNIEXPORT void JNICALL Java_co_ledger_core_BitcoinLikeTransactionBuilder_00024C } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) } -CJNIEXPORT jobject JNICALL Java_co_ledger_core_BitcoinLikeTransactionBuilder_00024CppProxy_native_1addInput(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jstring j_transactionHash, jint j_index, jint j_sequence) -{ - try { - DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); - const auto& ref = ::djinni::objectFromHandleAddress<::ledger::core::api::BitcoinLikeTransactionBuilder>(nativeRef); - auto r = ref->addInput(::djinni::String::toCpp(jniEnv, j_transactionHash), - ::djinni::I32::toCpp(jniEnv, j_index), - ::djinni::I32::toCpp(jniEnv, j_sequence)); - return ::djinni::release(::djinni_generated::BitcoinLikeTransactionBuilder::fromCpp(jniEnv, r)); - } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) -} - CJNIEXPORT jobject JNICALL Java_co_ledger_core_BitcoinLikeTransactionBuilder_00024CppProxy_native_1addOutput(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_amount, jobject j_script) { try { diff --git a/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.cpp b/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.cpp index 02ffca6e00..9bb7622569 100644 --- a/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.cpp +++ b/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.cpp @@ -48,7 +48,7 @@ namespace ledger { )); // Max ui512 BitcoinLikeTransactionBuilder::BitcoinLikeTransactionBuilder(const BitcoinLikeTransactionBuilder &cpy) - : _request(std::make_shared(cpy._currency.bitcoinLikeNetworkParameters.value().Dust)) { + : _request(std::make_shared(cpy._currency.bitcoinLikeNetworkParameters.value().Dust)) { _currency = cpy._currency; _build = cpy._build; _request = cpy._request; @@ -60,7 +60,7 @@ namespace ledger { const std::shared_ptr &context, const api::Currency ¤cy, const std::shared_ptr &logger, const BitcoinLikeTransactionBuildFunction &buildFunction) : - _request(std::make_shared(currency.bitcoinLikeNetworkParameters.value().Dust)) { + _request(std::make_shared(currency.bitcoinLikeNetworkParameters.value().Dust)) { _currency = currency; _build = buildFunction; _context = context; @@ -68,14 +68,6 @@ namespace ledger { _request.wipe = false; } - std::shared_ptr - BitcoinLikeTransactionBuilder::addInput(const std::string &transactionHash, int32_t index, int32_t sequence) { - _request.inputs.push_back(BitcoinLikeTransactionInputDescriptor{ - transactionHash, static_cast(index), static_cast(sequence)}); - - return shared_from_this(); - } - std::shared_ptr BitcoinLikeTransactionBuilder::addOutput(const std::shared_ptr &amount, const std::shared_ptr &script) { @@ -106,7 +98,7 @@ namespace ledger { std::shared_ptr BitcoinLikeTransactionBuilder::pickInputs(api::BitcoinLikePickingStrategy strategy, int32_t sequence, optional maxUtxo) { //Fix: use uniform initialization - + BitcoinUtxoPickerParams new_utxo_picker{strategy, sequence, maxUtxo}; _request.utxoPicker = Option(std::move(new_utxo_picker)); return shared_from_this(); @@ -167,7 +159,7 @@ namespace ledger { void BitcoinLikeTransactionBuilder::reset() { _request = BitcoinLikeTransactionBuildRequest(std::make_shared( - _currency.bitcoinLikeNetworkParameters.value().Dust) + _currency.bitcoinLikeNetworkParameters.value().Dust) ); } diff --git a/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.h b/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.h index a2c213cd2d..6cecd565df 100644 --- a/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.h +++ b/core/src/wallet/bitcoin/transaction_builders/BitcoinLikeTransactionBuilder.h @@ -100,8 +100,6 @@ namespace ledger { const std::shared_ptr& logger, const BitcoinLikeTransactionBuildFunction& buildFunction); BitcoinLikeTransactionBuilder(const BitcoinLikeTransactionBuilder& cpy); - std::shared_ptr - addInput(const std::string &transactionHash, int32_t index, int32_t sequence) override; std::shared_ptr addOutput(const std::shared_ptr &amount, const std::shared_ptr &script) override; diff --git a/core/test/fixtures/txes_to_wpkh._fixtures.cpp b/core/test/fixtures/txes_to_wpkh._fixtures.cpp new file mode 100644 index 0000000000..57034c6467 --- /dev/null +++ b/core/test/fixtures/txes_to_wpkh._fixtures.cpp @@ -0,0 +1,31 @@ +#include "txes_to_wpkh_fixtures.h" + +namespace ledger { + namespace testing { + namespace txes_to_wpkh { + core::api::ExtendedKeyAccountCreationInfo XPUB_INFO( + 0, {"main"}, {"84'/0'/0'"}, {"xpub6C2qnauSiRRR8UG9PXraYrfBtXZHzFRNgwJgwG7ZDp7SbWAdMSiMFoYDukTw4ExE95H4VkgECnhDe2uyLawoqUkoSHEDnoDafC2R44dXs7p"} + ); + // xpub from https://github.com/LedgerHQ/xpub-scan/blob/master/.github/workflows/regression_tests/datasets.json + const std::vector TXes = + { + "{\"hash\":\"4b3a5535d24d882233bb991a2e6fa111e64294aadcd140960cdceada2fae1bb8\",\"received_at\":\"2020-06-26T13:58:11Z\",\"lock_time\":0,\"block\":{\"hash\":\"00000000000000000003f12608c713d887fc216753ba70b264cc54379415928b\",\"height\":636436,\"time\":\"2020-06-26T14:29:17Z\"},\"inputs\":[{\"input_index\":0,\"output_hash\":\"70dcda8357d590f0cfb6cd504731d427db76fe03616f57c7af8366106af67092\",\"output_index\":1,\"value\":37471,\"address\":\"3MVXMz1zCEBScDM1pMsifuYavjzEjxCfM6\",\"script_signature\":\"160014682a7e09d3f88f56f6e9ed0a9511f064b79ab722\",\"sequence\":0,\"txinwitness\":[\"30450221009575c1fc1890db00b7cc33426954b19e516d19b03fd9fc924579e718f8437e4902203f0f5b8763c389548c910bbd7cd72a8d0bb1f35ba67f5b53f9ca1620bc86139801\",\"0378b2de4c77eaa8c1285ff73837a4b7abe9babf30e1cbc522329e0e15db2c03bc\"]}],\"outputs\":[{\"output_index\":0,\"value\":27278,\"address\":\"bc1qr500ysrg653aaplftaac753srtt2jwtfvcr5vt\",\"script_hex\":\"00141d1ef24068d523de87e95f7b8f52301ad6a93969\"},{\"output_index\":1,\"value\":9017,\"address\":\"3Nq7i7JRT7rzoKhhnxE3F8hbp1FpjN9jmV\",\"script_hex\":\"a914e7e2cc7a5d070144867183cd27b13db3b074883b87\"}],\"fees\":1176,\"amount\":36295,\"confirmations\":86334}", + "{\"hash\":\"673f7e1155dd2cf61c961cedd24608274c0f20cfaeaa1154c2b5ef94ec7b81d1\",\"received_at\":\"2021-09-08T12:45:21Z\",\"lock_time\":0,\"block\":{\"hash\":\"00000000000000000003fa8ebda5058dca475e65a8aaf692dc5a7449cf6e5a89\",\"height\":699622,\"time\":\"2021-09-08T12:58:43Z\"},\"inputs\":[{\"input_index\":0,\"output_hash\":\"4b3a5535d24d882233bb991a2e6fa111e64294aadcd140960cdceada2fae1bb8\",\"output_index\":0,\"value\":27278,\"address\":\"bc1qr500ysrg653aaplftaac753srtt2jwtfvcr5vt\",\"script_signature\":\"\",\"sequence\":0,\"txinwitness\":[\"304402205e18af8a590bdfd5c9e4f2e349b105ec5efb56b5fd3cf07e69786ef979d53ff4022069f8fd41fb6e9edee10d80f5bd8144a72ee1c609d93512487e362733103f78d201\",\"026f85f41f6a4ba5a1fc6819ffcfd9013e2ccd372b94e31fe867362035b38f1652\"]}],\"outputs\":[{\"output_index\":0,\"value\":1000,\"address\":\"bc1qrewjj96rjfzc9z2al0hvs2jtdc58nkgvrr6fgv\",\"script_hex\":\"00141e5d291743924582895dfbeec82a4b6e2879d90c\"},{\"output_index\":1,\"value\":25402,\"address\":\"bc1qz2z9dnhzwhveqemt9utryeucqnjuupenmfzsxv\",\"script_hex\":\"0014128456cee275d990676b2f1632679804e5ce0733\"}],\"fees\":876,\"amount\":26402,\"confirmations\":23148}", + "{\"hash\":\"5464631456754e6b410d5d9eb7cff4f82d1dc9aec0e2ec8fe759df6118e0112f\",\"received_at\":\"2021-11-20T12:48:08Z\",\"lock_time\":0,\"block\":{\"hash\":\"0000000000000000000b96dc8d6e75dc3eb4f995a10545f84ad1b8f1de4b9893\",\"height\":710566,\"time\":\"2021-11-20T12:52:04Z\"},\"inputs\":[{\"input_index\":0,\"output_hash\":\"4fadad2c103014ebaa3073ea63ff060b27d2d30b4e7f956727b97a44d1cf8ad7\",\"output_index\":0,\"value\":67218,\"address\":\"bc1qr500ysrg653aaplftaac753srtt2jwtfvcr5vt\",\"script_signature\":\"\",\"sequence\":4294967295,\"txinwitness\":[\"304402201668900493e07d2a4c2cf2b9c98a2b3ad1afc83da34cf727098077f34111209202202da599d4368331def39c95eab86480a9e9772fe4a393ad97d7174358becf422a01\",\"026f85f41f6a4ba5a1fc6819ffcfd9013e2ccd372b94e31fe867362035b38f1652\"]}],\"outputs\":[{\"output_index\":0,\"value\":60000,\"address\":\"1MD43R5k9qoAch5nUxk3BxNkVxpGbDS8iw\",\"script_hex\":\"76a914ddaa0bd7223bd2b5e61e8e7541fc22b9197440d288ac\"},{\"output_index\":1,\"value\":6780,\"address\":\"bc1q98csrhfkzrvkeee0k6jn70xdl2ghtewlkxva87\",\"script_hex\":\"001429f101dd3610d96ce72fb6a53f3ccdfa9175e5df\"}],\"fees\":438,\"amount\":66780,\"confirmations\":12204}", + "{\"hash\":\"4fadad2c103014ebaa3073ea63ff060b27d2d30b4e7f956727b97a44d1cf8ad7\",\"received_at\":\"2021-11-20T12:43:20Z\",\"lock_time\":0,\"block\":{\"hash\":\"0000000000000000000b96dc8d6e75dc3eb4f995a10545f84ad1b8f1de4b9893\",\"height\":710566,\"time\":\"2021-11-20T12:52:04Z\"},\"inputs\":[{\"input_index\":0,\"output_hash\":\"6b1c1bab2ce9a3429c4ddbbecf70d5ca2ac9a27634ebc8dd2dff347073eb1e39\",\"output_index\":0,\"value\":67554,\"address\":\"bc1qrd58306xwnpxegh76tp8gns4jxvjm7zxv3zzlc\",\"script_signature\":\"\",\"sequence\":4294967295,\"txinwitness\":[\"3045022100c27cd772986b8b82af189be7260a1e436e1a0573f8e908570b0fc55cd33541f4022059c575c3738acc502651ac0806816e91c9775cc253ee1f6798c2cf87901bb6c501\",\"0242dedafae7bdaf0c2b0ec74d2e1d83f874c11ad71e4a00031301e3aeb3322a6f\"]}],\"outputs\":[{\"output_index\":0,\"value\":67218,\"address\":\"bc1qr500ysrg653aaplftaac753srtt2jwtfvcr5vt\",\"script_hex\":\"00141d1ef24068d523de87e95f7b8f52301ad6a93969\"}],\"fees\":336,\"amount\":67218,\"confirmations\":12204}" + }; + std::shared_ptr inflate(const std::shared_ptr& pool, const std::shared_ptr& wallet) { + auto account + = std::dynamic_pointer_cast( + uv::wait(wallet->newAccountWithExtendedKeyInfo(XPUB_INFO))); + for (const std::string& tx : TXes) { + std::vector operations; + const auto parsedTx = ledger::core::JSONUtils::parse(tx); + account->interpretTransaction(*parsedTx, operations, true); + account->bulkInsert(operations); + } + return account; + } + } + } +} diff --git a/core/test/fixtures/txes_to_wpkh_fixtures.h b/core/test/fixtures/txes_to_wpkh_fixtures.h new file mode 100644 index 0000000000..bf2b70b28c --- /dev/null +++ b/core/test/fixtures/txes_to_wpkh_fixtures.h @@ -0,0 +1,41 @@ +#ifndef LEDGER_FIXTURES_TXES_TO_WPKH +#define LEDGER_FIXTURES_TXES_TO_WPKH +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ledger { + namespace testing { + namespace txes_to_wpkh { + extern core::api::ExtendedKeyAccountCreationInfo XPUB_INFO; + + std::shared_ptr inflate(const std::shared_ptr& pool, const std::shared_ptr& wallet); + } + } +} + +#endif // LEDGER_FIXTURES_TXES_TO_WPKH diff --git a/core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToNativeSegwit.CreateStandardP2WPKHWithOneOutput b/core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToNativeSegwit.CreateStandardP2WPKHWithOneOutput new file mode 100644 index 0000000000..d324c930a6 --- /dev/null +++ b/core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToNativeSegwit.CreateStandardP2WPKHWithOneOutput @@ -0,0 +1,10 @@ +GET https://explorers.api.live.ledger.com/blockchain/v2/btc/blocks/current +0 +1 +{"hash":"00000000000000000008db19835048ecdd79d0974f4bd1a1d5492a5502f1d61c","height":722923,"time":"2022-02-12T11:49:27Z","txs":[]} + +GET https://explorers.api.live.ledger.com/timestamp +0 +1 +{"timestamp":1644666863} + diff --git a/core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToP2WSH.CreateStandardP2WSHWithOneOutput b/core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToP2WSH.CreateStandardP2WSHWithOneOutput new file mode 100644 index 0000000000..d324c930a6 --- /dev/null +++ b/core/test/integration/http_cache/BitcoinMakeTransactionFromLegacyToP2WSH.CreateStandardP2WSHWithOneOutput @@ -0,0 +1,10 @@ +GET https://explorers.api.live.ledger.com/blockchain/v2/btc/blocks/current +0 +1 +{"hash":"00000000000000000008db19835048ecdd79d0974f4bd1a1d5492a5502f1d61c","height":722923,"time":"2022-02-12T11:49:27Z","txs":[]} + +GET https://explorers.api.live.ledger.com/timestamp +0 +1 +{"timestamp":1644666863} + diff --git a/core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToNativeSegwit.CreateStandardP2WPKHWithOneOutput b/core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToNativeSegwit.CreateStandardP2WPKHWithOneOutput new file mode 100644 index 0000000000..d324c930a6 --- /dev/null +++ b/core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToNativeSegwit.CreateStandardP2WPKHWithOneOutput @@ -0,0 +1,10 @@ +GET https://explorers.api.live.ledger.com/blockchain/v2/btc/blocks/current +0 +1 +{"hash":"00000000000000000008db19835048ecdd79d0974f4bd1a1d5492a5502f1d61c","height":722923,"time":"2022-02-12T11:49:27Z","txs":[]} + +GET https://explorers.api.live.ledger.com/timestamp +0 +1 +{"timestamp":1644666863} + diff --git a/core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToP2WSH.CreateStandardP2WSHWithOneOutput b/core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToP2WSH.CreateStandardP2WSHWithOneOutput new file mode 100644 index 0000000000..d324c930a6 --- /dev/null +++ b/core/test/integration/http_cache/BitcoinMakeTransactionFromNativeSegwitToP2WSH.CreateStandardP2WSHWithOneOutput @@ -0,0 +1,10 @@ +GET https://explorers.api.live.ledger.com/blockchain/v2/btc/blocks/current +0 +1 +{"hash":"00000000000000000008db19835048ecdd79d0974f4bd1a1d5492a5502f1d61c","height":722923,"time":"2022-02-12T11:49:27Z","txs":[]} + +GET https://explorers.api.live.ledger.com/timestamp +0 +1 +{"timestamp":1644666863} + diff --git a/core/test/integration/transactions/bitcoin_P2WPKH_transaction_tests.cpp b/core/test/integration/transactions/bitcoin_P2WPKH_transaction_tests.cpp index db4ffb02bf..de1e0a36f2 100644 --- a/core/test/integration/transactions/bitcoin_P2WPKH_transaction_tests.cpp +++ b/core/test/integration/transactions/bitcoin_P2WPKH_transaction_tests.cpp @@ -28,15 +28,17 @@ * */ #include "../BaseFixture.h" -#include "../../fixtures/medium_xpub_fixtures.h" #include #include #include "transaction_test_helper.h" #include #include +#include "../../fixtures/medium_xpub_fixtures.h" +#include "../../fixtures/txes_to_wpkh_fixtures.h" + using namespace std; -struct BitcoinMakeP2WPKHTransaction : public BitcoinMakeBaseTransaction { +struct BitcoinMakeTransactionFromNativeSegwitToNativeSegwit : public BitcoinMakeBaseTransaction { void SetUpConfig() override { testData.configuration = DynamicObject::newInstance(); testData.configuration->putString(api::Configuration::KEYCHAIN_ENGINE,api::KeychainEngines::BIP173_P2WPKH); @@ -44,34 +46,127 @@ struct BitcoinMakeP2WPKHTransaction : public BitcoinMakeBaseTransaction { testData.configuration->putString(api::Configuration::KEYCHAIN_DERIVATION_SCHEME,"84'/'/'//
"); testData.walletName = randomWalletName(); testData.currencyName = "bitcoin"; - testData.inflate_btc = ledger::testing::medium_xpub::inflate; + testData.inflate_btc = ledger::testing::txes_to_wpkh::inflate; } }; -TEST_F(BitcoinMakeP2WPKHTransaction, CreateStandardP2WPKHWithOneOutput) { - auto address = "bc1qshh6mmfq8fucahzxe4zc7pc5zdhk6zkt4uv8md"; - auto builder = tx_builder(); +TEST_F(BitcoinMakeTransactionFromNativeSegwitToNativeSegwit, VerifyHrpAndDerivationPath) { + auto address = "bc1q6qs00n9x2mgyrgaspdx32f73vykmkkh5r2a9sm"; auto freshAddress = uv::wait(account->getFreshPublicAddresses())[0]; auto hrp = Bech32Factory::newBech32Instance("btc").getValue()->getBech32Params().hrp; auto freshAddressStr = freshAddress->asBitcoinLikeAddress()->toBech32(); auto derivationPath = freshAddress->getDerivationPath().value_or(""); - EXPECT_EQ(derivationPath, "0/0"); + EXPECT_EQ(derivationPath, "0/1"); auto bechAddress = freshAddress->toString(); EXPECT_EQ(bechAddress, address); EXPECT_EQ(freshAddressStr.substr(0, hrp.size()), hrp); EXPECT_EQ(freshAddressStr, address); +} + +TEST_F(BitcoinMakeTransactionFromNativeSegwitToNativeSegwit, CreateStandardP2WPKHWithOneOutput) { + auto address = "bc1qshh6mmfq8fucahzxe4zc7pc5zdhk6zkt4uv8md"; + + auto balance = uv::wait(account->getBalance()); + std::cerr << balance->toLong() << std::endl; + + std::vector input_descrs = { + { + "673f7e1155dd2cf61c961cedd24608274c0f20cfaeaa1154c2b5ef94ec7b81d1", + 1, + std::make_shared(BigInt(25402)) + } + }; + std::vector output_descrs = { + { + address, + hex::toByteArray("001485efaded203a798edc46cd458f0714136f6d0acb"), + std::make_shared(BigInt(100)) + }, + { + "", // This is a change output. Don't use it explicitely in building + hex::toByteArray("00141017b1e1ca8632828f22a4d6c5260f3492b1dd08"), + // yes, change goes to legacy address + std::make_shared(BigInt(16396)) + } + }; + + std::shared_ptr generatedTx + = createTransaction(output_descrs); + + std::cerr << hex::toString(generatedTx->serialize()) << std::endl; + + EXPECT_TRUE(verifyTransaction(generatedTx, input_descrs, output_descrs)); + + std::vector tx_bin = generatedTx->serialize(); + std::cerr << hex::toString(generatedTx->serialize()) << std::endl; + + auto parsedTx + = BitcoinLikeTransactionBuilder::parseRawUnsignedTransaction(wallet->getCurrency(), + tx_bin, 0); + + EXPECT_TRUE(verifyTransactionOutputs(parsedTx, output_descrs)); + // Values in inputs are missing after parsing. Here we can test only outputs. + + EXPECT_EQ(tx_bin, parsedTx->serialize()); +} + +struct BitcoinMakeTransactionFromLegacyToNativeSegwit : public BitcoinMakeBaseTransaction { + void SetUpConfig() override { + testData.configuration = DynamicObject::newInstance(); + testData.walletName = randomWalletName(); + testData.currencyName = "bitcoin"; + testData.inflate_btc = ledger::testing::medium_xpub::inflate; + } +}; + +TEST_F(BitcoinMakeTransactionFromLegacyToNativeSegwit, CreateStandardP2WPKHWithOneOutput) { + auto address = "bc1qshh6mmfq8fucahzxe4zc7pc5zdhk6zkt4uv8md"; + auto balance = uv::wait(account->getBalance()); - // TODO: send BTC on address bc1qshh6mmfq8fucahzxe4zc7pc5zdhk6zkt4uv8md to implement the rest of tests ? - EXPECT_EQ(balance->toLong(), 0); - - // TODO: In the meantime ... - // Reference: https://github.com/bitcoin/bitcoin/blob/master/src/test/data/tx_valid.json - auto mockTx = "0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100cfb07164b36ba64c1b1e8c7720a56ad64d96f6ef332d3d37f9cb3c96477dc44502200a464cd7a9cf94cd70f66ce4f4f0625ef650052c7afcfe29d7d7e01830ff91ed012103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc7100000000"; - auto parsedTx = BitcoinLikeTransactionApi::parseRawSignedTransaction(wallet->getCurrency(), hex::toByteArray(mockTx), 0); - EXPECT_EQ(mockTx, hex::toString(parsedTx->serialize())); + std::cerr << "Balance before test: " << balance->toLong() << std::endl; + + std::vector input_descrs = { + { + "a207285f69f5966f47c93ea0b76c1d751912823ed5f58ad23d8e5600260f39f6", + 0, + std::make_shared(BigInt(100000)) + } + }; + std::vector output_descrs = { + { + address, + hex::toByteArray("001485efaded203a798edc46cd458f0714136f6d0acb"), + std::make_shared(BigInt(100)) + }, + { + "", // This is a change output. Don't use it explicitely in building + hex::toByteArray("76a914d642b9c546d114dc634e65f72283e3458032a3d488ac"), + // yes, change goes to legacy address + std::make_shared(BigInt(86114)) + } + }; + + std::shared_ptr generatedTx + = createTransaction(output_descrs); + + std::cerr << "generated tx: " << std::endl + << hex::toString(generatedTx->serialize()) << std::endl; + + EXPECT_TRUE(verifyTransaction(generatedTx, input_descrs, output_descrs)); + + std::vector tx_bin = generatedTx->serialize(); + + auto parsedTx + = BitcoinLikeTransactionBuilder::parseRawUnsignedTransaction(wallet->getCurrency(), + tx_bin, 0); + + EXPECT_TRUE(verifyTransactionOutputs(parsedTx, output_descrs)); + // Values in inputs are missing after parsing. Here we can test only outputs. + + EXPECT_EQ(tx_bin, parsedTx->serialize()); } -TEST_F(BitcoinMakeP2WPKHTransaction, ParseSignedTx) { +TEST_F(BitcoinMakeTransactionFromLegacyToNativeSegwit, ParseSignedTx) { auto hash = "c3dd55c86d02ad9d4b0e748c219fd15b79f21c6d5e38f5fe84a453a7f9e37494"; auto sender = "bc1qh4kl0a0a3d7su8udc2rn62f8w939prqpl34z86"; std::vector receivers {"bc1qh4kl0a0a3d7su8udc2rn62f8w939prqpl34z86", "bc1qry3crfssh8w6guajms7upclgqsfac4fs4g7nwj"}; diff --git a/core/test/integration/transactions/bitcoin_P2WSH_transaction_tests.cpp b/core/test/integration/transactions/bitcoin_P2WSH_transaction_tests.cpp index 659050568c..a62aec9013 100644 --- a/core/test/integration/transactions/bitcoin_P2WSH_transaction_tests.cpp +++ b/core/test/integration/transactions/bitcoin_P2WSH_transaction_tests.cpp @@ -28,42 +28,132 @@ * */ #include "../BaseFixture.h" -#include "../../fixtures/medium_xpub_fixtures.h" #include #include #include "transaction_test_helper.h" #include #include +#include "../../fixtures/medium_xpub_fixtures.h" +#include "../../fixtures/txes_to_wpkh_fixtures.h" + using namespace std; -struct BitcoinMakeP2WSHTransaction : public BitcoinMakeBaseTransaction { +struct BitcoinMakeTransactionFromNativeSegwitToP2WSH : public BitcoinMakeBaseTransaction { + void SetUpConfig() override { + testData.configuration = DynamicObject::newInstance(); + testData.configuration->putString(api::Configuration::KEYCHAIN_ENGINE,api::KeychainEngines::BIP173_P2WPKH); + //https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki + testData.configuration->putString(api::Configuration::KEYCHAIN_DERIVATION_SCHEME,"84'/'/'//
"); + testData.walletName = randomWalletName(); + testData.currencyName = "bitcoin"; + testData.inflate_btc = ledger::testing::txes_to_wpkh::inflate; + } +}; + +TEST_F(BitcoinMakeTransactionFromNativeSegwitToP2WSH, CreateStandardP2WSHWithOneOutput) { + auto address = "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"; + + auto balance = uv::wait(account->getBalance()); + std::cerr << balance->toLong() << std::endl; + + std::vector input_descrs = { + { + "673f7e1155dd2cf61c961cedd24608274c0f20cfaeaa1154c2b5ef94ec7b81d1", + 1, + std::make_shared(BigInt(25402)) + } + }; + std::vector output_descrs = { + { + address, + hex::toByteArray("00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262"), + std::make_shared(BigInt(100)) + }, + { + "", // This is a change output. Don't use it explicitely in building + hex::toByteArray("00141017b1e1ca8632828f22a4d6c5260f3492b1dd08"), + // yes, change goes to legacy address + std::make_shared(BigInt(16396)) + } + }; + + std::shared_ptr generatedTx + = createTransaction(output_descrs); + + std::cerr << hex::toString(generatedTx->serialize()) << std::endl; + + EXPECT_TRUE(verifyTransaction(generatedTx, input_descrs, output_descrs)); + + std::vector tx_bin = generatedTx->serialize(); + std::cerr << hex::toString(generatedTx->serialize()) << std::endl; + + auto parsedTx + = BitcoinLikeTransactionBuilder::parseRawUnsignedTransaction(wallet->getCurrency(), + tx_bin, 0); + + EXPECT_TRUE(verifyTransactionOutputs(parsedTx, output_descrs)); + // Values in inputs are missing after parsing. Here we can test only outputs. + + EXPECT_EQ(tx_bin, parsedTx->serialize()); +} + +struct BitcoinMakeTransactionFromLegacyToP2WSH : public BitcoinMakeBaseTransaction { void SetUpConfig() override { testData.configuration = DynamicObject::newInstance(); - testData.configuration->putString(api::Configuration::KEYCHAIN_ENGINE,api::KeychainEngines::BIP173_P2WSH); testData.walletName = randomWalletName(); testData.currencyName = "bitcoin"; testData.inflate_btc = ledger::testing::medium_xpub::inflate; } }; -TEST_F(BitcoinMakeP2WSHTransaction, CreateStandardP2WSHWithOneOutput) { - auto builder = tx_builder(); - auto freshAddress = uv::wait(account->getFreshPublicAddresses())[0]; - auto hrp = Bech32Factory::newBech32Instance("btc").getValue()->getBech32Params().hrp; - auto freshAddressStr = freshAddress->asBitcoinLikeAddress()->toBech32(); - EXPECT_EQ(freshAddressStr.substr(0, hrp.size()), hrp); +TEST_F(BitcoinMakeTransactionFromLegacyToP2WSH, CreateStandardP2WSHWithOneOutput) { + auto address = "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3"; + auto balance = uv::wait(account->getBalance()); - // TODO: send BTC on address bc1q7kggee5ry2xpr0nul42grqul6ygyll5afj34xxehaftcc0pty4sqvud0h2 to implement the rest of tests ? - EXPECT_EQ(balance->toLong(), 0); - - // TODO: In the meantime ... - // Reference: https://github.com/bitcoin/bitcoin/blob/master/src/test/data/tx_valid.json - auto mockTx = "0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000"; - auto parsedTx = BitcoinLikeTransactionApi::parseRawSignedTransaction(wallet->getCurrency(), hex::toByteArray(mockTx), 0); - EXPECT_EQ(mockTx, hex::toString(parsedTx->serialize())); + std::cerr << "Balance before test: " << balance->toLong() << std::endl; + + std::vector input_descrs = { + { + "a207285f69f5966f47c93ea0b76c1d751912823ed5f58ad23d8e5600260f39f6", + 0, + std::make_shared(BigInt(100000)) + } + }; + std::vector output_descrs = { + { + address, + hex::toByteArray("00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262"), + std::make_shared(BigInt(100)) + }, + { + "", // This is a change output. Don't use it explicitely in building + hex::toByteArray("76a914d642b9c546d114dc634e65f72283e3458032a3d488ac"), + // yes, change goes to legacy address + std::make_shared(BigInt(86114)) + } + }; + + std::shared_ptr generatedTx + = createTransaction(output_descrs); + + std::cerr << "generated tx: " << std::endl + << hex::toString(generatedTx->serialize()) << std::endl; + + EXPECT_TRUE(verifyTransaction(generatedTx, input_descrs, output_descrs)); + + std::vector tx_bin = generatedTx->serialize(); + + auto parsedTx + = BitcoinLikeTransactionBuilder::parseRawUnsignedTransaction(wallet->getCurrency(), + tx_bin, 0); + + EXPECT_TRUE(verifyTransactionOutputs(parsedTx, output_descrs)); + // Values in inputs are missing after parsing. Here we can test only outputs. + + EXPECT_EQ(tx_bin, parsedTx->serialize()); } -TEST_F(BitcoinMakeP2WSHTransaction, ParseSignedTx) { +TEST_F(BitcoinMakeTransactionFromLegacyToP2WSH, ParseSignedTx) { auto hash = "94236be7808bc824ae3c531ee4cdf26559d6cf40cb6541f38153c54701fb0ea7"; auto sender = "bc1qsqe7gwppjngklwjd2lp8kde0cpglerldadudcua3efr7a0tf3ucs995hxa"; std::vector receivers {"bc1qmxalhet27lzt07tq5uxhagg8z4538k095f4s5u2znh67p972v5mswsecmn", "bc1qhfrga6jkrvnrq8jv7606xj77fttqeq08puze7pzu4xnejvgqffxs96j3cx"}; diff --git a/core/test/integration/transactions/coin_selection_P2PKH.cpp b/core/test/integration/transactions/coin_selection_P2PKH.cpp index cdfce548d9..0a98f0a615 100644 --- a/core/test/integration/transactions/coin_selection_P2PKH.cpp +++ b/core/test/integration/transactions/coin_selection_P2PKH.cpp @@ -131,7 +131,7 @@ TEST_F(CoinSelectionP2PKH, HighestFirstNotEnough) { builder->pickInputs(api::BitcoinLikePickingStrategy::HIGHEST_FIRST_LIMIT_UTXO, 0xFFFFFFFF, optional(2)); builder->setFeesPerByte(api::Amount::fromLong(currency, 0)); auto f = builder->build(); - EXPECT_THROW(uv::wait(f), Exception); + EXPECT_THROW(uv::wait(f), Exception); } TEST_F(CoinSelectionP2PKH, LimitUtxoPickStrategy) { @@ -161,7 +161,7 @@ TEST_F(CoinSelectionP2PKH, LimitUtxoPickStrategy) { EXPECT_EQ(tx->getOutputs().at(0)->getValue()->toLong(), 50000000); } {//test 3 - EXPECT_THROW(build(100000000), Exception); + EXPECT_THROW(build(100000000), Exception); } {//test 4 auto tx = build(10000000); @@ -185,7 +185,7 @@ TEST_F(CoinSelectionP2PKH, maxSpendable) { EXPECT_EQ(120000000, uv::wait( account->getMaxSpendable(api::BitcoinLikePickingStrategy::LIMIT_UTXO, optional(3)))->toLong()); EXPECT_EQ(150000000, uv::wait( - account->getMaxSpendable(api::BitcoinLikePickingStrategy::LIMIT_UTXO, optional(7)))->toLong()); + account->getMaxSpendable(api::BitcoinLikePickingStrategy::LIMIT_UTXO, optional(7)))->toLong()); } TEST_F(CoinSelectionP2PKH, PickAllUTXO) { diff --git a/core/test/integration/transactions/transaction_test_helper.cpp b/core/test/integration/transactions/transaction_test_helper.cpp index 913e9cc400..8ecd41622b 100644 --- a/core/test/integration/transactions/transaction_test_helper.cpp +++ b/core/test/integration/transactions/transaction_test_helper.cpp @@ -31,6 +31,9 @@ #include "transaction_test_helper.h" +#include "api/BitcoinLikeInput.hpp" +#include "api/BitcoinLikeOutput.hpp" + //Examples taken from https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki //Serialized signed segwit transactions, first has 2 inputs with witnesses, second has 2 inputs and only one of them has a witness const std::vector rawSegwitTxs { @@ -41,3 +44,83 @@ const std::vector rawSegwitTxs { //01000000000101db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477010000001716001479091972186c449eb1ded22b78e40d009bdf0089feffffff02b8b4eb0b000000001976a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac0008af2f000000001976a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac02473044022047ac8e878352d3ebbde1c94ce3a10d057c24175747116f8288e5d794d12d482f0220217f36a485cae903c713331d877c1f64677e3622ad4010726870540656fe9dcb012103ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a2687392040000 //KO: P2WPKH (normally not used, to check) //01000000000102fff7f7881a8099afa6940d42d1e7f6362bec38171ea3edf433541db4e4ad969f00000000494830450221008b9d1dc26ba6a9cb62127b02742fa9d754cd3bebf337f7a55d114c8e5cdd30be022040529b194ba3f9281a99f2b1c0a19c0489bc22ede944ccf4ecbab4cc618ef3ed01eeffffffef51e1b804cc89d182d279655c3aa89e815b1b309fe287d9b2b55d57b90ec68a0100000000ffffffff02202cb206000000001976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac9093510d000000001976a9143bde42dbee7e4dbe6a21b2d50ce2f0167faa815988ac000247304402203609e17b84f6a7d30c80bfa610b5b4542f32a8a0d5447a12fb1366d7f01cc44a0220573a954c4518331561406f90300e8f3358f51928d43c212a8caed02de67eebee0121025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee635711000000 + +std::shared_ptr BitcoinMakeBaseTransaction::createTransaction(const std::vector& outputs) { + auto builder = tx_builder(); + + for (const OutputDescr& od : outputs) { + if (od._addr.empty()) + continue; + + builder->sendToAddress( + std::make_shared( + currency, + 0, + std::dynamic_pointer_cast(od._amount)->backend()), + od._addr); + } + + builder->pickInputs(api::BitcoinLikePickingStrategy::DEEP_OUTPUTS_FIRST, 0xFFFFFFFF, optional()); + builder->setFeesPerByte(api::Amount::fromLong(currency, 61)); + + auto f = builder->build(); + std::shared_ptr tx = uv::wait(f); + return tx; +} + +bool BitcoinMakeBaseTransaction::verifyTransactionInputs(std::shared_ptr tx, + const std::vector& inputs) { + if (inputs.size() != tx->getInputs().size()) + return false; + + std::set inputs_matched; + for (size_t i = 0; i < inputs.size(); ++i) { + for(size_t j = 0; j < inputs.size(); ++j) { + if (inputs_matched.end() != inputs_matched.find(j)) { + continue; + } + + std::shared_ptr txin = tx->getInputs()[j]; + if (txin->getValue()->toBigInt()->compare(inputs[i]._amount) == 0 + && txin->getPreviousTxHash().value_or("no hash") == inputs[i]._tx_hash + && txin->getPreviousOutputIndex().value_or(-1) == inputs[i]._out_idx) { + inputs_matched.insert(j); + break; + } + } + } + + return inputs.size() == inputs_matched.size(); +} + +bool BitcoinMakeBaseTransaction::verifyTransactionOutputs(std::shared_ptr tx, + const std::vector& outputs) { + if (outputs.size() != tx->getOutputs().size()) + return false; + + std::set outputs_matched; + for (size_t i = 0; i < outputs.size(); ++i) { + for(size_t j = 0; j < outputs.size(); ++j) { + if (outputs_matched.end() != outputs_matched.find(j)) { + continue; + } + + std::shared_ptr txout = tx->getOutputs()[j]; + if (txout->getValue()->toBigInt()->compare(outputs[i]._amount) == 0 + && txout->getScript() == outputs[i]._script) { + outputs_matched.insert(j); + break; + } + std::cerr << hex::toString(txout->getScript()) << std::endl; + } + } + + return outputs.size() == outputs_matched.size(); +} + +bool BitcoinMakeBaseTransaction::verifyTransaction(std::shared_ptr tx, + const std::vector& inputs, + const std::vector& outputs) { + return verifyTransactionInputs(tx, inputs) && verifyTransactionOutputs(tx, outputs); +} + diff --git a/core/test/integration/transactions/transaction_test_helper.h b/core/test/integration/transactions/transaction_test_helper.h index d9d0988a56..ec1de8b97f 100644 --- a/core/test/integration/transactions/transaction_test_helper.h +++ b/core/test/integration/transactions/transaction_test_helper.h @@ -48,7 +48,6 @@ #include #include "../BaseFixture.h" - using namespace ledger::core; struct TransactionTestData { @@ -69,11 +68,23 @@ struct TransactionTestData { struct BitcoinMakeBaseTransaction : public BaseFixture { + struct InputDescr { + std::string _tx_hash; + int32_t _out_idx; + std::shared_ptr _amount; + }; + + struct OutputDescr { + std::string _addr; // for tx building + std::vector _script; // for tx verification + std::shared_ptr _amount; + }; + void SetUp() override { BaseFixture::SetUp(); SetUpConfig(); recreate(); - } + }; virtual void recreate() { pool = newDefaultPool(); @@ -92,6 +103,18 @@ struct BitcoinMakeBaseTransaction : public BaseFixture { std::shared_ptr tx_builder() { return std::dynamic_pointer_cast(account->buildTransaction(false)); } + + std::shared_ptr createTransaction(const std::vector& outputs); + + bool verifyTransactionInputs(std::shared_ptr tx, + const std::vector& inputs); + bool verifyTransactionOutputs(std::shared_ptr tx, + const std::vector& outputs); + + bool verifyTransaction(std::shared_ptr tx, + const std::vector& inputs, + const std::vector& outputs); + std::shared_ptr pool; std::shared_ptr wallet; std::shared_ptr account; diff --git a/core/test/tezos/tezos_account.cpp b/core/test/tezos/tezos_account.cpp index 3567fb83f4..865d180bb3 100644 --- a/core/test/tezos/tezos_account.cpp +++ b/core/test/tezos/tezos_account.cpp @@ -169,15 +169,24 @@ TEST_F(TezosAccount, InterpetTransactionWithCorrectUidWithoutOriginatedAccount) } } +struct TezosAccountWithFixedPoolName : public TezosAccount { + virtual void recreate() { + SetUpConfig(); + pool = newDefaultPool("my_ppol"); + wallet = uv::wait(pool->createWallet(testData.walletName, testData.currencyName, testData.configuration)); + account = testData.inflate_xtz(pool, wallet); + currency = wallet->getCurrency(); + } +}; -TEST_F(TezosAccount, ComputeOperationUidWithValidTransaction) { +TEST_F(TezosAccountWithFixedPoolName, ComputeOperationUidWithValidTransaction) { auto strTx = "036e766ee0733ef0fb6385f2034cfbd437247afad4b301ebce1b929a67ce4a0b8d6c00902c5d86590a2452f0ccf9c1fa55ae679de27d398e0aee94cb03a75100882700011ebab3538f6ca4223ee98b565846e47d273d112900"; auto txBytes = hex::toByteArray(strTx); auto tx = std::dynamic_pointer_cast(api::TezosLikeTransactionBuilder::parseRawUnsignedTransaction( ledger::core::currencies::TEZOS, txBytes, api::TezosConfigurationDefaults::TEZOS_PROTOCOL_UPDATE_BABYLON)); tx->setRawTx(std::vector{}); auto accAddress = ledger::core::TezosLikeAddress::fromBase58(account->getAccountAddress(), currency); - + // when sender { auto txTest = std::make_shared(*tx); @@ -195,11 +204,11 @@ TEST_F(TezosAccount, ComputeOperationUidWithValidTransaction) { } -TEST_F(TezosAccount, ComputeOperationUidWithInvalidTransaction) { +TEST_F(TezosAccountWithFixedPoolName, ComputeOperationUidWithInvalidTransaction) { auto strTx = "036e766ee0733ef0fb6385f2034cfbd437247afad4b301ebce1b929a67ce4a0b8d6c00902c5d86590a2452f0ccf9c1fa55ae679de27d398e0aee94cb03a75100882700011ebab3538f6ca4223ee98b565846e47d273d112900"; auto txBytes = hex::toByteArray(strTx); auto tx = std::dynamic_pointer_cast(api::TezosLikeTransactionBuilder::parseRawUnsignedTransaction( ledger::core::currencies::TEZOS, txBytes, api::TezosConfigurationDefaults::TEZOS_PROTOCOL_UPDATE_BABYLON)); tx->setRawTx(std::vector{}); EXPECT_ANY_THROW(account->computeOperationUid(tx)); -} \ No newline at end of file +} diff --git a/core/test/tezos/transaction_test.hpp b/core/test/tezos/transaction_test.hpp index 0602413e64..79f28e28c1 100644 --- a/core/test/tezos/transaction_test.hpp +++ b/core/test/tezos/transaction_test.hpp @@ -19,17 +19,17 @@ namespace ledger { namespace testing { namespace tezos { - - + + struct TezosMakeBaseTransaction : public BaseFixture { void SetUp() override; - void recreate(); + virtual void recreate(); void TearDown() override; - + struct Callback: public api::StringCallback { Callback(std::shared_ptr dispatcher): _dispatcher(dispatcher) {}