diff --git a/internal/adapters/dataproviders/bitcoin/common.go b/internal/adapters/dataproviders/bitcoin/common.go index c9d5796d..54cb1b9a 100644 --- a/internal/adapters/dataproviders/bitcoin/common.go +++ b/internal/adapters/dataproviders/bitcoin/common.go @@ -87,12 +87,12 @@ func buildMerkleBranch(merkleTree []*chainhash.Hash, txCount uint32, txIndex uin } } -func serializePartialMerkleTree(txHash *chainhash.Hash, block *btcutil.Block, witness bool) ([]byte, error) { +func serializePartialMerkleTree(txHash *chainhash.Hash, block *btcutil.Block) ([]byte, error) { var err error filter := bloom.NewFilter(1, 0, 0, wire.BloomUpdateAll) filter.AddHash(txHash) - msg, indices := NewMerkleBlock(block, filter, witness) + msg, indices := bloom.NewMerkleBlock(block, filter) if len(indices) > 1 { return nil, fmt.Errorf("block matches more than one transaction (%v)", len(indices)) } diff --git a/internal/adapters/dataproviders/bitcoin/rpc.go b/internal/adapters/dataproviders/bitcoin/rpc.go index 3243be0f..92a2e3a1 100644 --- a/internal/adapters/dataproviders/bitcoin/rpc.go +++ b/internal/adapters/dataproviders/bitcoin/rpc.go @@ -109,7 +109,7 @@ func (rpc *bitcoindRpc) GetRawTransaction(hash string) ([]byte, error) { } var buf bytes.Buffer - if err = rawTx.MsgTx().Serialize(&buf); err != nil { + if err = rawTx.MsgTx().SerializeNoWitness(&buf); err != nil { return nil, err } return buf.Bytes(), nil @@ -122,12 +122,7 @@ func (rpc *bitcoindRpc) GetPartialMerkleTree(hash string) ([]byte, error) { } block := btcutil.NewBlock(rawBlock) - for _, t := range block.Transactions() { - if t.Hash().String() == hash && t.HasWitness() { - return serializePartialMerkleTree(parsedTxHash, block, true) - } - } - return serializePartialMerkleTree(parsedTxHash, block, false) + return serializePartialMerkleTree(parsedTxHash, block) } func (rpc *bitcoindRpc) GetHeight() (*big.Int, error) { @@ -139,8 +134,6 @@ func (rpc *bitcoindRpc) GetHeight() (*big.Int, error) { } func (rpc *bitcoindRpc) BuildMerkleBranch(txHash string) (blockchain.MerkleBranch, error) { - var wid *chainhash.Hash - isWitness := false rawBlock, parsedTxHash, err := rpc.getTxBlock(txHash) if err != nil { return blockchain.MerkleBranch{}, err @@ -149,16 +142,11 @@ func (rpc *bitcoindRpc) BuildMerkleBranch(txHash string) (blockchain.MerkleBranc block := btcutil.NewBlock(rawBlock) txs := make([]*btcutil.Tx, 0) for _, t := range block.MsgBlock().Transactions { - parsedTx := btcutil.NewTx(t) - if parsedTx.Hash().String() == txHash && parsedTx.HasWitness() { - isWitness = true - wid = parsedTx.WitnessHash() - } - txs = append(txs, parsedTx) + txs = append(txs, btcutil.NewTx(t)) } var cleanStore []*chainhash.Hash - store := merkle.BuildMerkleTreeStore(txs, isWitness) + store := merkle.BuildMerkleTreeStore(txs, false) for _, node := range store { if node != nil { cleanStore = append(cleanStore, node) @@ -166,7 +154,7 @@ func (rpc *bitcoindRpc) BuildMerkleBranch(txHash string) (blockchain.MerkleBranc } index := slices.IndexFunc(cleanStore, func(h *chainhash.Hash) bool { - return h != nil && (h.IsEqual(parsedTxHash) || h.IsEqual(wid)) + return h != nil && h.IsEqual(parsedTxHash) }) if index == -1 { return blockchain.MerkleBranch{}, fmt.Errorf("transaction %s not found in merkle tree", txHash) @@ -226,7 +214,7 @@ func (rpc *bitcoindRpc) GetCoinbaseInformation(txHash string) (blockchain.BtcCoi } txs = append(txs, btcutil.NewTx(tx)) } - pmt, err := serializePartialMerkleTree(&coinbaseTxHash, btcutil.NewBlock(block), false) + pmt, err := serializePartialMerkleTree(&coinbaseTxHash, btcutil.NewBlock(block)) if err != nil { return blockchain.BtcCoinbaseTransactionInformation{}, err } diff --git a/internal/adapters/dataproviders/bitcoin/rpc_test.go b/internal/adapters/dataproviders/bitcoin/rpc_test.go index dfc78da6..6fc57a7e 100644 --- a/internal/adapters/dataproviders/bitcoin/rpc_test.go +++ b/internal/adapters/dataproviders/bitcoin/rpc_test.go @@ -32,7 +32,7 @@ const ( const ( mainnetTestBlockHash = "0000000000000000000aca0460feaf0661f173b75d4cc824b57233aa7c6b7bc3" - mainnetTestTxHash = "c7f58fcae16340963f14326ee3eb677abf53f8c07f165a031d72be6b2c4b35b2" + mainnetTestTxHash = "e28bec3d29efce36405197d1255cfebde06ba9c193d8192d3825d6e9213b03ed" mainnetWitnessTestTxHash = "85c2fc50c70ceda8cb9f62aacc65a67b76411e442096d86649c95d7e9a28af8c" mainnetBlockFile = "block-696394-mainnet.txt" ) @@ -159,9 +159,10 @@ func TestBitcoindRpc_GetRawTransaction_FromBlock(t *testing.T) { legacyTxIndex = 1 ) + // the witness part was removed from this txs const ( - coinbaseTx = "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff5f034aa00a1c2f5669614254432f4d696e656420627920797a33313936303538372f2cfabe6d6dc0a3751203a336deb817199448996ebcb2a0e537b1ce9254fa3e9c3295ca196b100000000000000010c56e6700d262d24bd851bb829f9f0000ffffffff0401b3cc25000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3a040c866ad2fdb8b59b32dd17059edaeef11d295e279a74ab97125d2500371ce90000000000000000266a24b9e11b6dab3e2ca50c1a6b01cf80eccb9d291aab8b095d653e348aa9d94a73964ff5cf1b0000000000000000266a24aa21a9ed04f0bac0104f4fa47bec8058f2ebddd292dd85027ab0d6d95288d31f12c5a4b80120000000000000000000000000000000000000000000000000000000000000000000000000" - segwitTx = "020000000001015cc3af292dd2e81c21582b0666879869112ebc97ebb4a3a6bd2cfe8a30f92b940100000000fdffffff02a0cd8700000000001976a91409e6abdfa8852101e9b9ba77efa6f4a9617cb5ec88ac1cf8df0d000000001600144b6cf6cf48ec8aa8dfa1e10395f829c8a504dcb80247304402207acaf018536ce71f69b3e964a19337779eff9e8921b7c99a1cb26e0001329c3e02201cfd03cdf29fa3625c7b77d82d0950f3f3b6ba1d5a6fcae0633899741a14cafd012103414dfd31acabbbe2135534bd359a6b120d02ddfac80847da0946d1f58850311c47a00a00" + coinbaseTx = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5f034aa00a1c2f5669614254432f4d696e656420627920797a33313936303538372f2cfabe6d6dc0a3751203a336deb817199448996ebcb2a0e537b1ce9254fa3e9c3295ca196b100000000000000010c56e6700d262d24bd851bb829f9f0000ffffffff0401b3cc25000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3a040c866ad2fdb8b59b32dd17059edaeef11d295e279a74ab97125d2500371ce90000000000000000266a24b9e11b6dab3e2ca50c1a6b01cf80eccb9d291aab8b095d653e348aa9d94a73964ff5cf1b0000000000000000266a24aa21a9ed04f0bac0104f4fa47bec8058f2ebddd292dd85027ab0d6d95288d31f12c5a4b800000000" + segwitTx = "02000000015cc3af292dd2e81c21582b0666879869112ebc97ebb4a3a6bd2cfe8a30f92b940100000000fdffffff02a0cd8700000000001976a91409e6abdfa8852101e9b9ba77efa6f4a9617cb5ec88ac1cf8df0d000000001600144b6cf6cf48ec8aa8dfa1e10395f829c8a504dcb847a00a00" legacyTx = "0200000001c48719db38d7286213202ef512b180e389ed8f863bd5116b658b7b1913dd9fd7080000006a4730440220753eed9c595e55d95bbdeb3dd7ed1fe2f3a6838f68c840304db5e7b8d99616b902204a3143b47ee93f1f75b79dea9919eea9d211b08fd53578fd676bad73971d2f23012102380b75bccbe06860dd573c1a6278690b6efb4ec7c14795d1ee4858bf8c718dd6ffffffff055b552e000000000017a9142e62d87b097cee76ede80d01671036795898a392878d320200000000001600143932ea911f6f00b168a2c094c07cdb120ae5f31bf2cf27000000000017a91484910e6a662c1c114b45af3bef8bdb5c3cb7e302876e043300000000001976a914f1ebdd044ba61d8c8575cc52556cba834dde727388ace3d54208000000001976a9142287780623e361a71cfaaece32e34e29c43b09f388ac00000000" ) @@ -284,17 +285,17 @@ func TestBitcoindRpc_BuildMerkleBranch(t *testing.T) { require.NoError(t, witnessErr) assert.Equal(t, blockchain.MerkleBranch{ Hashes: [][32]byte{ - {202, 209, 6, 128, 197, 197, 163, 175, 47, 177, 10, 21, 77, 20, 72, 72, 131, 121, 88, 230, 49, 100, 110, 20, 79, 151, 50, 101, 226, 41, 41, 101}, - {77, 24, 29, 182, 74, 66, 127, 130, 228, 136, 234, 187, 23, 100, 239, 128, 169, 12, 177, 96, 126, 213, 17, 64, 214, 194, 169, 236, 158, 178, 132, 231}, - {122, 108, 123, 152, 101, 7, 240, 31, 193, 116, 169, 48, 128, 204, 67, 149, 28, 121, 218, 242, 130, 217, 90, 252, 10, 77, 77, 39, 153, 8, 28, 44}, - {11, 62, 45, 81, 209, 148, 243, 39, 5, 199, 125, 90, 5, 82, 151, 11, 24, 25, 226, 210, 7, 196, 193, 48, 98, 221, 121, 15, 101, 110, 105, 58}, - {167, 182, 98, 239, 12, 122, 232, 82, 62, 136, 57, 198, 175, 0, 211, 223, 82, 87, 43, 122, 235, 226, 24, 154, 81, 15, 241, 78, 121, 76, 96, 82}, - {211, 117, 223, 57, 134, 244, 54, 236, 187, 61, 117, 98, 2, 124, 89, 205, 189, 22, 190, 29, 197, 194, 68, 106, 103, 96, 127, 38, 127, 226, 155, 91}, - {200, 230, 212, 225, 203, 32, 124, 219, 80, 204, 156, 59, 126, 35, 11, 34, 19, 50, 65, 93, 54, 55, 3, 60, 178, 37, 1, 69, 136, 221, 220, 239}, - {189, 13, 95, 161, 30, 246, 40, 118, 221, 191, 214, 114, 197, 142, 158, 21, 199, 113, 85, 153, 133, 133, 153, 144, 31, 29, 69, 167, 25, 155, 38, 81}, - {30, 162, 139, 139, 159, 215, 199, 91, 237, 155, 15, 39, 148, 226, 191, 117, 0, 141, 185, 53, 231, 172, 56, 154, 238, 85, 29, 227, 85, 252, 12, 255}, - {72, 1, 142, 131, 233, 175, 74, 228, 245, 69, 89, 179, 175, 225, 148, 40, 99, 156, 135, 228, 165, 16, 126, 147, 191, 122, 224, 199, 191, 155, 166, 64}, - {152, 164, 241, 22, 94, 106, 235, 155, 115, 150, 126, 205, 206, 46, 232, 198, 44, 210, 93, 85, 58, 255, 205, 164, 118, 103, 139, 245, 200, 55, 14, 249}, + {80, 13, 208, 226, 229, 205, 193, 227, 225, 239, 119, 77, 193, 76, 43, 168, 230, 26, 1, 48, 54, 253, 218, 78, 113, 65, 122, 41, 29, 38, 119, 248}, + {35, 117, 153, 121, 181, 74, 52, 157, 198, 126, 119, 134, 72, 50, 50, 30, 131, 227, 178, 54, 25, 170, 112, 250, 55, 217, 244, 34, 139, 13, 191, 251}, + {100, 222, 145, 234, 129, 135, 15, 66, 246, 18, 188, 107, 95, 180, 105, 49, 12, 32, 93, 144, 193, 5, 115, 213, 148, 115, 23, 90, 83, 159, 174, 11}, + {78, 9, 161, 73, 176, 134, 182, 94, 12, 64, 254, 209, 220, 203, 97, 254, 205, 139, 44, 224, 65, 109, 64, 227, 98, 119, 14, 2, 242, 211, 157, 57}, + {83, 244, 193, 13, 23, 19, 237, 210, 69, 201, 114, 243, 245, 149, 179, 54, 40, 116, 207, 65, 185, 68, 219, 122, 55, 109, 34, 160, 110, 94, 131, 60}, + {130, 82, 5, 217, 245, 246, 144, 252, 194, 224, 4, 202, 5, 194, 169, 254, 142, 125, 235, 140, 150, 199, 163, 137, 162, 182, 239, 221, 250, 112, 43, 112}, + {65, 232, 143, 221, 200, 199, 173, 242, 246, 127, 151, 181, 54, 171, 127, 167, 131, 29, 10, 255, 52, 37, 123, 65, 246, 190, 208, 189, 225, 251, 249, 202}, + {182, 25, 68, 77, 235, 60, 181, 139, 169, 54, 138, 235, 188, 38, 87, 59, 216, 4, 50, 71, 161, 71, 246, 58, 124, 14, 180, 168, 46, 209, 65, 65}, + {69, 111, 13, 194, 93, 216, 68, 1, 101, 240, 131, 152, 34, 9, 74, 121, 251, 101, 1, 205, 115, 127, 76, 33, 67, 219, 83, 183, 34, 95, 125, 2}, + {13, 139, 52, 219, 135, 232, 179, 145, 111, 223, 227, 136, 201, 12, 147, 249, 30, 34, 41, 128, 144, 62, 214, 57, 252, 196, 229, 128, 136, 98, 83, 183}, + {22, 85, 158, 56, 49, 196, 24, 106, 225, 109, 143, 164, 106, 193, 100, 188, 171, 81, 231, 70, 160, 3, 7, 147, 226, 80, 59, 114, 2, 254, 137, 138}, }, Path: big.NewInt(10), }, witnessBranch) @@ -309,37 +310,37 @@ func TestBitcoindRpc_BuildMerkleBranch(t *testing.T) { require.NoError(t, legacyErr) assert.Equal(t, blockchain.MerkleBranch{ Hashes: [][32]byte{ - {137, 102, 35, 174, 4, 121, 246, 50, 90, 243, 230, 171, 188, 182, 183, 75, 191, 149, 81, 56, 0, 111, 18, 236, 254, 15, 228, 164, 206, 219, 84, 101}, - {156, 91, 227, 106, 182, 149, 132, 255, 186, 154, 54, 182, 48, 48, 61, 149, 172, 114, 107, 184, 255, 229, 102, 46, 203, 181, 210, 238, 212, 170, 11, 52}, - {82, 2, 198, 200, 130, 81, 112, 25, 107, 119, 103, 99, 30, 148, 200, 230, 133, 162, 62, 161, 103, 150, 103, 64, 59, 219, 28, 60, 36, 65, 176, 222}, - {175, 142, 172, 188, 138, 186, 62, 56, 29, 45, 32, 12, 145, 23, 64, 114, 233, 144, 163, 174, 84, 227, 247, 27, 185, 148, 125, 220, 65, 8, 114, 12}, - {123, 220, 166, 223, 255, 27, 14, 38, 164, 42, 113, 248, 101, 42, 29, 243, 5, 14, 190, 19, 244, 195, 46, 198, 157, 216, 152, 26, 253, 61, 96, 21}, - {117, 231, 53, 138, 107, 79, 64, 171, 87, 103, 225, 7, 193, 174, 116, 54, 182, 129, 43, 76, 213, 179, 14, 133, 137, 158, 155, 68, 112, 238, 111, 54}, - {172, 101, 233, 61, 146, 94, 28, 43, 204, 218, 120, 21, 239, 34, 169, 144, 145, 234, 135, 56, 145, 165, 165, 219, 7, 84, 249, 115, 191, 95, 156, 183}, - {249, 45, 23, 27, 143, 58, 131, 195, 10, 205, 55, 171, 225, 154, 124, 88, 202, 207, 50, 63, 143, 115, 189, 73, 237, 251, 231, 241, 167, 184, 138, 197}, - {203, 13, 22, 187, 45, 252, 231, 123, 189, 32, 137, 238, 167, 8, 142, 30, 234, 130, 66, 201, 160, 221, 24, 109, 88, 46, 242, 115, 26, 190, 127, 8}, - {112, 243, 236, 215, 155, 86, 49, 31, 112, 198, 40, 60, 71, 154, 246, 0, 237, 35, 184, 90, 148, 121, 31, 66, 246, 195, 199, 189, 143, 238, 57, 122}, - {175, 73, 148, 36, 83, 68, 95, 216, 191, 100, 102, 139, 4, 1, 211, 121, 42, 72, 152, 79, 92, 246, 68, 179, 116, 211, 158, 42, 125, 174, 232, 47}, - {87, 19, 169, 48, 133, 4, 206, 201, 212, 192, 224, 109, 238, 124, 190, 42, 70, 188, 85, 141, 66, 165, 105, 242, 252, 246, 131, 33, 236, 71, 102, 107}, + {135, 238, 6, 224, 124, 24, 74, 200, 74, 27, 37, 35, 43, 44, 127, 246, 228, 20, 127, 238, 125, 111, 49, 84, 183, 128, 247, 107, 202, 214, 211, 166}, + {103, 85, 48, 129, 146, 247, 167, 199, 24, 36, 61, 6, 170, 57, 230, 208, 100, 110, 183, 28, 106, 197, 160, 174, 181, 168, 187, 117, 252, 186, 13, 230}, + {188, 246, 123, 201, 232, 76, 99, 248, 74, 146, 140, 22, 16, 11, 182, 123, 213, 43, 193, 230, 3, 206, 65, 7, 16, 71, 12, 112, 234, 161, 22, 241}, + {230, 59, 158, 254, 204, 131, 165, 217, 113, 218, 137, 229, 38, 38, 146, 142, 214, 204, 83, 48, 141, 52, 154, 137, 68, 67, 237, 189, 65, 109, 63, 43}, + {26, 58, 71, 140, 19, 140, 216, 86, 46, 179, 179, 205, 112, 231, 140, 177, 88, 218, 86, 60, 150, 103, 169, 84, 107, 0, 24, 77, 225, 36, 58, 57}, + {240, 180, 13, 33, 230, 26, 169, 40, 21, 51, 234, 193, 97, 10, 52, 143, 173, 194, 22, 196, 5, 154, 251, 4, 132, 168, 136, 119, 154, 194, 172, 55}, + {85, 116, 78, 207, 38, 216, 198, 137, 255, 208, 176, 58, 89, 94, 225, 127, 42, 82, 84, 186, 74, 163, 124, 56, 6, 104, 63, 91, 197, 33, 45, 226}, + {171, 42, 57, 157, 70, 22, 160, 131, 61, 100, 19, 64, 189, 165, 136, 115, 144, 178, 88, 49, 54, 86, 240, 102, 163, 241, 78, 106, 214, 254, 189, 153}, + {228, 251, 50, 25, 248, 207, 101, 227, 197, 180, 227, 140, 40, 114, 246, 99, 40, 176, 27, 31, 102, 60, 121, 201, 210, 1, 200, 10, 10, 145, 25, 35}, + {120, 151, 221, 211, 187, 111, 123, 119, 19, 210, 218, 166, 197, 99, 238, 2, 118, 22, 119, 198, 184, 181, 10, 36, 177, 128, 127, 2, 75, 186, 30, 61}, + {61, 64, 181, 114, 24, 1, 204, 165, 24, 27, 171, 158, 84, 128, 127, 92, 31, 209, 164, 94, 152, 53, 37, 214, 108, 143, 26, 93, 151, 11, 243, 113}, + {12, 6, 109, 68, 13, 255, 55, 88, 126, 233, 74, 151, 206, 202, 141, 109, 121, 156, 236, 11, 92, 76, 96, 209, 100, 60, 26, 131, 2, 99, 102, 238}, }, - Path: big.NewInt(18), + Path: big.NewInt(6), }, legacyBranch) witnessBranch, witnessErr := rpc.BuildMerkleBranch(mainnetWitnessTestTxHash) require.NoError(t, witnessErr) assert.Equal(t, blockchain.MerkleBranch{ Hashes: [][32]byte{ - {157, 79, 110, 242, 184, 247, 118, 177, 32, 78, 45, 230, 94, 240, 122, 146, 14, 233, 242, 37, 235, 66, 0, 75, 107, 64, 137, 73, 7, 116, 140, 9}, - {190, 167, 136, 193, 228, 187, 128, 140, 249, 68, 248, 208, 74, 78, 217, 35, 109, 46, 55, 225, 69, 168, 223, 222, 238, 210, 245, 217, 101, 142, 11, 132}, - {82, 2, 198, 200, 130, 81, 112, 25, 107, 119, 103, 99, 30, 148, 200, 230, 133, 162, 62, 161, 103, 150, 103, 64, 59, 219, 28, 60, 36, 65, 176, 222}, - {175, 142, 172, 188, 138, 186, 62, 56, 29, 45, 32, 12, 145, 23, 64, 114, 233, 144, 163, 174, 84, 227, 247, 27, 185, 148, 125, 220, 65, 8, 114, 12}, - {123, 220, 166, 223, 255, 27, 14, 38, 164, 42, 113, 248, 101, 42, 29, 243, 5, 14, 190, 19, 244, 195, 46, 198, 157, 216, 152, 26, 253, 61, 96, 21}, - {117, 231, 53, 138, 107, 79, 64, 171, 87, 103, 225, 7, 193, 174, 116, 54, 182, 129, 43, 76, 213, 179, 14, 133, 137, 158, 155, 68, 112, 238, 111, 54}, - {172, 101, 233, 61, 146, 94, 28, 43, 204, 218, 120, 21, 239, 34, 169, 144, 145, 234, 135, 56, 145, 165, 165, 219, 7, 84, 249, 115, 191, 95, 156, 183}, - {249, 45, 23, 27, 143, 58, 131, 195, 10, 205, 55, 171, 225, 154, 124, 88, 202, 207, 50, 63, 143, 115, 189, 73, 237, 251, 231, 241, 167, 184, 138, 197}, - {203, 13, 22, 187, 45, 252, 231, 123, 189, 32, 137, 238, 167, 8, 142, 30, 234, 130, 66, 201, 160, 221, 24, 109, 88, 46, 242, 115, 26, 190, 127, 8}, - {112, 243, 236, 215, 155, 86, 49, 31, 112, 198, 40, 60, 71, 154, 246, 0, 237, 35, 184, 90, 148, 121, 31, 66, 246, 195, 199, 189, 143, 238, 57, 122}, - {175, 73, 148, 36, 83, 68, 95, 216, 191, 100, 102, 139, 4, 1, 211, 121, 42, 72, 152, 79, 92, 246, 68, 179, 116, 211, 158, 42, 125, 174, 232, 47}, - {87, 19, 169, 48, 133, 4, 206, 201, 212, 192, 224, 109, 238, 124, 190, 42, 70, 188, 85, 141, 66, 165, 105, 242, 252, 246, 131, 33, 236, 71, 102, 107}, + {108, 236, 234, 77, 106, 108, 163, 204, 4, 94, 67, 31, 86, 6, 2, 134, 199, 122, 75, 236, 253, 93, 176, 134, 32, 218, 177, 126, 181, 208, 122, 210}, + {53, 178, 35, 230, 188, 212, 205, 49, 167, 120, 157, 193, 246, 140, 101, 226, 49, 126, 83, 49, 230, 132, 93, 117, 13, 173, 26, 95, 52, 4, 151, 210}, + {245, 186, 211, 170, 68, 100, 250, 196, 134, 156, 81, 121, 144, 127, 48, 92, 106, 247, 59, 129, 94, 86, 251, 164, 120, 160, 140, 168, 236, 39, 99, 107}, + {17, 22, 165, 123, 175, 96, 197, 101, 168, 85, 191, 119, 46, 47, 54, 17, 45, 211, 190, 106, 152, 87, 58, 203, 160, 45, 208, 34, 217, 114, 106, 122}, + {153, 234, 33, 223, 242, 169, 208, 67, 204, 186, 216, 67, 225, 75, 71, 243, 102, 21, 174, 17, 166, 246, 253, 148, 43, 125, 233, 75, 148, 216, 27, 79}, + {240, 180, 13, 33, 230, 26, 169, 40, 21, 51, 234, 193, 97, 10, 52, 143, 173, 194, 22, 196, 5, 154, 251, 4, 132, 168, 136, 119, 154, 194, 172, 55}, + {85, 116, 78, 207, 38, 216, 198, 137, 255, 208, 176, 58, 89, 94, 225, 127, 42, 82, 84, 186, 74, 163, 124, 56, 6, 104, 63, 91, 197, 33, 45, 226}, + {171, 42, 57, 157, 70, 22, 160, 131, 61, 100, 19, 64, 189, 165, 136, 115, 144, 178, 88, 49, 54, 86, 240, 102, 163, 241, 78, 106, 214, 254, 189, 153}, + {228, 251, 50, 25, 248, 207, 101, 227, 197, 180, 227, 140, 40, 114, 246, 99, 40, 176, 27, 31, 102, 60, 121, 201, 210, 1, 200, 10, 10, 145, 25, 35}, + {120, 151, 221, 211, 187, 111, 123, 119, 19, 210, 218, 166, 197, 99, 238, 2, 118, 22, 119, 198, 184, 181, 10, 36, 177, 128, 127, 2, 75, 186, 30, 61}, + {61, 64, 181, 114, 24, 1, 204, 165, 24, 27, 171, 158, 84, 128, 127, 92, 31, 209, 164, 94, 152, 53, 37, 214, 108, 143, 26, 93, 151, 11, 243, 113}, + {12, 6, 109, 68, 13, 255, 55, 88, 126, 233, 74, 151, 206, 202, 141, 109, 121, 156, 236, 11, 92, 76, 96, 209, 100, 60, 26, 131, 2, 99, 102, 238}, }, Path: big.NewInt(16), }, witnessBranch) @@ -421,22 +422,22 @@ func TestBitcoindRpc_GetPartialMerkleTree(t *testing.T) { require.NoError(t, err) assert.Equal(t, []byte{ - 6, 4, 0, 0, 12, 58, 105, 110, 101, 15, 121, 221, 98, 48, 193, 196, 7, 210, 226, 25, 24, 11, 151, 82, 5, 90, - 125, 199, 5, 39, 243, 148, 209, 81, 45, 62, 11, 231, 132, 178, 158, 236, 169, 194, 214, 64, 17, 213, 126, 96, - 177, 12, 169, 128, 239, 100, 23, 187, 234, 136, 228, 130, 127, 66, 74, 182, 29, 24, 77, 101, 238, 142, 185, 83, - 221, 231, 68, 128, 143, 19, 65, 205, 234, 63, 12, 21, 150, 177, 4, 231, 65, 218, 211, 155, 236, 58, 187, 150, - 157, 88, 18, 101, 41, 41, 226, 101, 50, 151, 79, 20, 110, 100, 49, 230, 88, 121, 131, 72, 72, 20, 77, 21, 10, - 177, 47, 175, 163, 197, 197, 128, 6, 209, 202, 44, 28, 8, 153, 39, 77, 77, 10, 252, 90, 217, 130, 242, 218, 121, - 28, 149, 67, 204, 128, 48, 169, 116, 193, 31, 240, 7, 101, 152, 123, 108, 122, 82, 96, 76, 121, 78, 241, 15, 81, - 154, 24, 226, 235, 122, 43, 87, 82, 223, 211, 0, 175, 198, 57, 136, 62, 82, 232, 122, 12, 239, 98, 182, 167, 91, - 155, 226, 127, 38, 127, 96, 103, 106, 68, 194, 197, 29, 190, 22, 189, 205, 89, 124, 2, 98, 117, 61, 187, 236, 54, - 244, 134, 57, 223, 117, 211, 239, 220, 221, 136, 69, 1, 37, 178, 60, 3, 55, 54, 93, 65, 50, 19, 34, 11, 35, 126, - 59, 156, 204, 80, 219, 124, 32, 203, 225, 212, 230, 200, 81, 38, 155, 25, 167, 69, 29, 31, 144, 153, 133, 133, 153, - 85, 113, 199, 21, 158, 142, 197, 114, 214, 191, 221, 118, 40, 246, 30, 161, 95, 13, 189, 255, 12, 252, 85, 227, 29, - 85, 238, 154, 56, 172, 231, 53, 185, 141, 0, 117, 191, 226, 148, 39, 15, 155, 237, 91, 199, 215, 159, 139, 139, 162, - 30, 64, 166, 155, 191, 199, 224, 122, 191, 147, 126, 16, 165, 228, 135, 156, 99, 40, 148, 225, 175, 179, 89, 69, 245, - 228, 74, 175, 233, 131, 142, 1, 72, 249, 14, 55, 200, 245, 139, 103, 118, 164, 205, 255, 58, 85, 93, 210, 44, 198, - 232, 46, 206, 205, 126, 150, 115, 155, 235, 106, 94, 22, 241, 164, 152, 3, 255, 54, 0, + 6, 4, 0, 0, 12, 57, 157, 211, 242, 2, 14, 119, 98, 227, 64, 109, 65, 224, 44, 139, 205, 254, 97, 203, 220, 209, + 254, 64, 12, 94, 182, 134, 176, 73, 161, 9, 78, 251, 191, 13, 139, 34, 244, 217, 55, 250, 112, 170, 25, 54, 178, + 227, 131, 30, 50, 50, 72, 134, 119, 126, 198, 157, 52, 74, 181, 121, 153, 117, 35, 236, 9, 149, 2, 45, 233, 151, + 96, 179, 240, 141, 236, 56, 147, 12, 242, 219, 111, 154, 154, 44, 242, 70, 35, 34, 27, 217, 204, 193, 203, 173, + 92, 248, 119, 38, 29, 41, 122, 65, 113, 78, 218, 253, 54, 48, 1, 26, 230, 168, 43, 76, 193, 77, 119, 239, 225, 227, + 193, 205, 229, 226, 208, 13, 80, 11, 174, 159, 83, 90, 23, 115, 148, 213, 115, 5, 193, 144, 93, 32, 12, 49, 105, 180, + 95, 107, 188, 18, 246, 66, 15, 135, 129, 234, 145, 222, 100, 60, 131, 94, 110, 160, 34, 109, 55, 122, 219, 68, 185, + 65, 207, 116, 40, 54, 179, 149, 245, 243, 114, 201, 69, 210, 237, 19, 23, 13, 193, 244, 83, 112, 43, 112, 250, 221, + 239, 182, 162, 137, 163, 199, 150, 140, 235, 125, 142, 254, 169, 194, 5, 202, 4, 224, 194, 252, 144, 246, 245, 217, + 5, 82, 130, 202, 249, 251, 225, 189, 208, 190, 246, 65, 123, 37, 52, 255, 10, 29, 131, 167, 127, 171, 54, 181, 151, + 127, 246, 242, 173, 199, 200, 221, 143, 232, 65, 65, 65, 209, 46, 168, 180, 14, 124, 58, 246, 71, 161, 71, 50, 4, + 216, 59, 87, 38, 188, 235, 138, 54, 169, 139, 181, 60, 235, 77, 68, 25, 182, 2, 125, 95, 34, 183, 83, 219, 67, 33, 76, + 127, 115, 205, 1, 101, 251, 121, 74, 9, 34, 152, 131, 240, 101, 1, 68, 216, 93, 194, 13, 111, 69, 183, 83, 98, 136, 128, + 229, 196, 252, 57, 214, 62, 144, 128, 41, 34, 30, 249, 147, 12, 201, 136, 227, 223, 111, 145, 179, 232, 135, 219, 52, + 139, 13, 138, 137, 254, 2, 114, 59, 80, 226, 147, 7, 3, 160, 70, 231, 81, 171, 188, 100, 193, 106, 164, 143, 109, 225, + 106, 24, 196, 49, 56, 158, 85, 22, 3, 255, 54, 0, }, pmt) client.AssertExpectations(t) } @@ -451,37 +452,36 @@ func TestBitcoindRpc_GetPartialMerkleTree_MainnetBlock(t *testing.T) { { tx: "07f8b22fa9a3b32e20b59bb90727de05fb634749519ebcb6a887aeaf2c7eb041", pmt: "f30800000d" + - "000000000000000000000000000000000000000000000000000000000000000073" + + "41b07e2cafae87a8b6bc9e51494763fb05de2707b99bb5202eb3a3a92fb2f80773" + "1c671fafb5d234834c726657f29c9af030ccf7068f1ef732af4efd8e146da0a9d6" + - "075f4758821ceeef2c230cfd2497df2d1d1d02dd19e653d22b3dc271b3931b9aac" + - "9d2faa0e1814b3ac46067e68ee5fa59b9e5e9f5eb60c6d00a746848af913ce9302" + - "f52718a61abc3af42ed88a07341b19364cbac956a4519115837569da7bf6e51ea9" + - "c98d57b3f8d3a781fb160ca04ebed21e80444036b70446f04a7838366fee70449b" + - "9e89850eb3d54c2b81b63674aec107e16757ab404f6b8a35e775b79c5fbf73f954" + - "07dba5a5913887ea9190a922ef1578dacc2b1c5e923de965acc58ab8a7f1e7fbed" + - "49bd738f3f32cfca587c9ae1ab37cd0ac3833a8f1b172df9087fbe1a73f22e586d" + - "18dda0c94282ea1e8e08a7ee8920bd7be7fc2dbb160dcb7a39ee8fbdc7c3f6421f" + - "79945ab823ed00f69a473c28c6701f31569bd7ecf3702fe8ae7d2a9ed374b344f6" + - "5c4f98482a79d301048b6664bfd85f4453249449af6b6647ec2183f6fcf269a542" + - "8d55bc462abe7cee6de0c0d4c9ce048530a9135704ff1f0000", + "075f4758821ceeef2c230cfd2497df2d1d1d02dd19e653d22b3dc271b39394c2d2" + + "e51eae99af800c39575a11f3b4eb0fdf5d5deff0b9f5ff592566f4f1732b3f6d41" + + "bded4344899a348d3053ccd68e922626e589da71d9a583ccfe9e3be6393a24e14d" + + "18006b54a967963c56da58b18ce770cdb3b32e56d88c138c473a1a37acc29a7788" + + "a88404fb9a05c416c2ad8f340a61c1ea331528a91ae6210db4f0e22d21c55b3f68" + + "06387ca34aba54522a7fe15e593ab0d0ff89c6d826cf4e745599bdfed66a4ef1a3" + + "66f056363158b2907388a5bd4013643d83a016469d392aab2319910a0ac801d2c9" + + "793c661f1bb02863f672288ce3b4c5e365cff81932fbe43d1eba4b027f80b1240a" + + "b5b8c677167602ee63c5a6dad213777b6fbbd3dd977871f30b975d1a8f6cd62535" + + "985ea4d11f5c7f80549eab1b18a5cc011872b5403dee666302831a3c64d1604c5c" + + "0bec9c796d8dcace974ae97e5837ff0d446d060c04ff1f0000", }, { tx: "ddf5061f9707f0c959bf24278d557b264716672c1b601ec50112d6dfe160d9d3", pmt: "f30800000d" + - "ae0f1f5cf24d3875e8f301fe178d8efd527c668d176709cf27730572392c4ad9" + - "681d5442690792835378e68031a399bd8222e7b3d26b6ddadee237890087b516" + - "820f677871c76a1b0cadd7d3315a413511c66feaa6f87ec9e820cd1479c5a054" + - "f3ebc63fcc05543c5cf652d2aea6ab5f9be87cb91cd34bbadb9b04ba023f791a" + - "3dfb1303b5a550d33774cd2dbb37f8d2522935f218e8b13e1dfdc1a0e824fb38" + - "0d371f17a4c6328ec0860960bad8b6296483d55c155d216105ec0ade23da6c66" + - "ad9c51f5f731c8f08214a3dd7f6eddae5a55076295190723c462ecfbfbeaeffb" + - "ed89a4d28cdaec3e5039438d5134737dceeceff340d6920fab7518757d99e1c7" + - "f305a80c97b49df6c0d5dc28c47c1bfc595c47bc820354a94b2d2d8bd6f75466" + - "fbfb473898f2a5840d86338deae45a04f3912416b7e5526e37ce6842d43b05e7" + - "a5e0ed8adc181d8e026ed6dc27a31b8b2729b76902b4e1a8758f2c70bbc3a442" + - "0bf154f0aa8b60b415eaf70a9ada542f39b62baca6415c3611f8306e14a4d131" + - "6b6647ec2183f6fcf269a5428d55bc462abe7cee6de0c0d4c9ce048530a91357" + - "04dbd50300", + "c0746a357444e9948a18a612e02df5a99240e77f1ff75dd949d5b4038dcf36673a" + + "03c716cf722cff7d264c763088ceeb1665f26c6fdd5835d841eeee2f3ece4a203a" + + "24db8b7a51e4ab0e35a6b4151f6d7f1eef96f32e4fceaac61275219116186efb7f" + + "db763e821f99bd6af8d044cc6feadd7b4716e6938335a3e08548f5a0775dd36497" + + "1faab5cd089cd1fa713e8be658a67a704d39952218f6518e5045d269d3d960e1df" + + "d61201c51e601b2c671647267b558d2724bf59c9f007971f06f5dd0eab2677f52c" + + "996a3f941bef3ec57ebdf22429c37dee5ae68892df30f8acfc225c6fed56bdff34" + + "686135e68fda4b716713e60258b6971c03091f25115c008eec48a828c75ad7340f" + + "adbc368636b4014f6e8386c3990a35620cbddca933a72b02d990fb8a602fcda9e1" + + "e41120c25f4981362a9dfc7f7ed1f5188482b8ee3f532f0ee6234e44af99351ee4" + + "30f4ac0fa7b71fe9c601c78480b9a97fea305d3abca235a6668846093803e07c48" + + "dc9a75be90ed6edd4debb0b7b49bc057e093ad395eee666302831a3c64d1604c5c" + + "0bec9c796d8dcace974ae97e5837ff0d446d060c04dbd50300", }, { tx: "db0d1fe6384b5741ceb2e67f4b50372966e1bab2b50e91a597ca4170c5f281e9", diff --git a/internal/usecases/common.go b/internal/usecases/common.go index 7de6460b..9436012b 100644 --- a/internal/usecases/common.go +++ b/internal/usecases/common.go @@ -173,6 +173,8 @@ func SignConfiguration[C liquidity_provider.ConfigurationType]( return signedConfig, nil } +// RegisterCoinbaseTransaction registers the information of the coinbase transaction of the block of a specific transaction in the Rootstock Bridge. +// IMPORTANT: this function should not be called right now for security reasons. It is in the codebase for future compatibility but should not be used for now. func RegisterCoinbaseTransaction(btcRpc blockchain.BitcoinNetwork, bridgeContract blockchain.RootstockBridge, tx blockchain.BitcoinTransactionInformation) error { if !tx.HasWitness { return nil diff --git a/internal/usecases/pegin/register_pegin.go b/internal/usecases/pegin/register_pegin.go index c630baea..712811bf 100644 --- a/internal/usecases/pegin/register_pegin.go +++ b/internal/usecases/pegin/register_pegin.go @@ -39,7 +39,6 @@ func (useCase *RegisterPeginUseCase) Run(ctx context.Context, retainedQuote quot var err error var peginQuote *quote.PeginQuote var params blockchain.RegisterPeginParams - var userBtcTx blockchain.BitcoinTransactionInformation if retainedQuote.State != quote.PeginStateCallForUserSucceeded { return useCase.publishErrorEvent(ctx, retainedQuote, usecases.WrongStateError, true) @@ -51,7 +50,7 @@ func (useCase *RegisterPeginUseCase) Run(ctx context.Context, retainedQuote quot return useCase.publishErrorEvent(ctx, retainedQuote, usecases.QuoteNotFoundError, false) } - if userBtcTx, err = useCase.getUserBtcTransactionIfValid(ctx, retainedQuote); err != nil { + if err = useCase.validateTransaction(ctx, retainedQuote); err != nil { return err } @@ -62,10 +61,6 @@ func (useCase *RegisterPeginUseCase) Run(ctx context.Context, retainedQuote quot useCase.rskWalletMutex.Lock() defer useCase.rskWalletMutex.Unlock() - if err = usecases.RegisterCoinbaseTransaction(useCase.rpc.Btc, useCase.contracts.Bridge, userBtcTx); err != nil { - return useCase.publishErrorEvent(ctx, retainedQuote, err, errors.Is(err, blockchain.WaitingForBridgeError)) - } - return useCase.performRegisterPegin(ctx, params, retainedQuote) } @@ -119,15 +114,15 @@ func (useCase *RegisterPeginUseCase) buildRegisterPeginParams(peginQuote quote.P }, nil } -func (useCase *RegisterPeginUseCase) getUserBtcTransactionIfValid(ctx context.Context, retainedQuote quote.RetainedPeginQuote) (blockchain.BitcoinTransactionInformation, error) { +func (useCase *RegisterPeginUseCase) validateTransaction(ctx context.Context, retainedQuote quote.RetainedPeginQuote) error { var txInfo blockchain.BitcoinTransactionInformation var err error if txInfo, err = useCase.rpc.Btc.GetTransactionInfo(retainedQuote.UserBtcTxHash); err != nil { - return blockchain.BitcoinTransactionInformation{}, useCase.publishErrorEvent(ctx, retainedQuote, err, true) + return useCase.publishErrorEvent(ctx, retainedQuote, err, true) } else if txInfo.Confirmations < useCase.contracts.Bridge.GetRequiredTxConfirmations() { - return blockchain.BitcoinTransactionInformation{}, useCase.publishErrorEvent(ctx, retainedQuote, usecases.NoEnoughConfirmationsError, true) + return useCase.publishErrorEvent(ctx, retainedQuote, usecases.NoEnoughConfirmationsError, true) } - return txInfo, nil + return nil } func (useCase *RegisterPeginUseCase) performRegisterPegin(ctx context.Context, params blockchain.RegisterPeginParams, retainedQuote quote.RetainedPeginQuote) error { diff --git a/internal/usecases/pegin/register_pegin_test.go b/internal/usecases/pegin/register_pegin_test.go index 19ca4c2a..5fac123d 100644 --- a/internal/usecases/pegin/register_pegin_test.go +++ b/internal/usecases/pegin/register_pegin_test.go @@ -2,13 +2,10 @@ package pegin_test import ( "context" - "encoding/hex" - "errors" "fmt" "github.com/rsksmart/liquidity-provider-server/internal/entities" "github.com/rsksmart/liquidity-provider-server/internal/entities/blockchain" "github.com/rsksmart/liquidity-provider-server/internal/entities/quote" - "github.com/rsksmart/liquidity-provider-server/internal/entities/utils" "github.com/rsksmart/liquidity-provider-server/internal/usecases" "github.com/rsksmart/liquidity-provider-server/internal/usecases/pegin" "github.com/rsksmart/liquidity-provider-server/test" @@ -92,6 +89,7 @@ func TestRegisterPeginUseCase_Run(t *testing.T) { bridge.AssertExpectations(t) btc.AssertExpectations(t) mutex.AssertExpectations(t) + bridge.AssertNotCalled(t, "RegisterBtcCoinbaseTransaction") } func TestRegisterPeginUseCase_Run_DontPublishRecoverableErrors(t *testing.T) { @@ -493,66 +491,3 @@ func registerPeginUpdateErrorSetups(t *testing.T, registerPeginTx string, retain }, } } - -func TestRegisterPeginUseCase_Run_RegisterCoinbase(t *testing.T) { - retainedPeginQuote := quote.RetainedPeginQuote{ - QuoteHash: hex.EncodeToString(utils.MustGetRandomBytes(32)), - Signature: hex.EncodeToString(utils.MustGetRandomBytes(32)), - DepositAddress: test.AnyAddress, RequiredLiquidity: entities.NewWei(1500), - State: quote.PeginStateCallForUserSucceeded, - UserBtcTxHash: userBtcTx, CallForUserTxHash: cfuTx, - } - lbc := new(mocks.LbcMock) - quoteRepository := new(mocks.PeginQuoteRepositoryMock) - eventBus := new(mocks.EventBusMock) - bridge := new(mocks.BridgeMock) - btc := new(mocks.BtcRpcMock) - mutex := new(mocks.MutexMock) - coinbaseInfo := blockchain.BtcCoinbaseTransactionInformation{BlockHash: utils.To32Bytes(utils.MustGetRandomBytes(32))} - // Mocks that don't change per test - mutex.On("Lock").Return().Times(3) - mutex.On("Unlock").Return().Times(3) - quoteRepository.EXPECT().GetQuote(test.AnyCtx, mock.Anything).Return(&testPeginQuote, nil).Times(3) - quoteRepository.EXPECT().UpdateRetainedQuote(test.AnyCtx, mock.Anything).Return(nil).Twice() - btc.On("GetRawTransaction", retainedPeginQuote.UserBtcTxHash).Return(btcRawTxMock, nil).Times(3) - btc.On("GetPartialMerkleTree", retainedPeginQuote.UserBtcTxHash).Return(pmtMock, nil).Times(3) - btc.On("GetTransactionBlockInfo", retainedPeginQuote.UserBtcTxHash).Return(btcBlockInfoMock, nil).Times(3) - bridge.On("GetRequiredTxConfirmations").Return(uint64(10)).Times(3) - btc.On("GetTransactionInfo", retainedPeginQuote.UserBtcTxHash).Return(blockchain.BitcoinTransactionInformation{ - Hash: retainedPeginQuote.UserBtcTxHash, Confirmations: 10, HasWitness: true, - Outputs: map[string][]*entities.Wei{retainedPeginQuote.DepositAddress: {entities.NewWei(1)}}, - }, nil).Times(3) - btc.On("GetCoinbaseInformation", retainedPeginQuote.UserBtcTxHash).Return(coinbaseInfo, nil).Times(3) - // once as it'll be called only on 1st test - lbc.On("RegisterPegin", mock.Anything).Return(registerPeginTx, nil).Once() - - useCase := pegin.NewRegisterPeginUseCase(blockchain.RskContracts{Lbc: lbc, Bridge: bridge}, quoteRepository, eventBus, blockchain.Rpc{Btc: btc}, mutex) - t.Run("Should call RegisterCoinbaseTransaction", func(t *testing.T) { - bridge.On("RegisterBtcCoinbaseTransaction", coinbaseInfo).Return(test.AnyHash, nil).Once() - eventBus.On("Publish", mock.MatchedBy(func(e quote.RegisterPeginCompletedEvent) bool { - return e.Error == nil - })).Return().Once() - err := useCase.Run(context.Background(), retainedPeginQuote) - require.NoError(t, err) - }) - t.Run("Should return recoverable error if tx wasn't registered due to waiting for the bridge", func(t *testing.T) { - bridge.On("RegisterBtcCoinbaseTransaction", coinbaseInfo).Return("", blockchain.WaitingForBridgeError).Once() - err := useCase.Run(context.Background(), retainedPeginQuote) - require.Error(t, err) - require.NotErrorIs(t, err, usecases.NonRecoverableError) - }) - t.Run("Should return non recoverable error if tx wasn't registered due to any other error", func(t *testing.T) { - bridge.On("RegisterBtcCoinbaseTransaction", coinbaseInfo).Return("", assert.AnError).Once() - eventBus.On("Publish", mock.MatchedBy(func(e quote.RegisterPeginCompletedEvent) bool { - return errors.Is(e.Error, usecases.NonRecoverableError) - })).Return().Once() - err := useCase.Run(context.Background(), retainedPeginQuote) - require.ErrorIs(t, err, usecases.NonRecoverableError) - }) - mutex.AssertExpectations(t) - lbc.AssertExpectations(t) - bridge.AssertExpectations(t) - btc.AssertExpectations(t) - quoteRepository.AssertExpectations(t) - eventBus.AssertExpectations(t) -} diff --git a/internal/usecases/pegout/refund_pegout.go b/internal/usecases/pegout/refund_pegout.go index 3dc2a217..ccbf3773 100644 --- a/internal/usecases/pegout/refund_pegout.go +++ b/internal/usecases/pegout/refund_pegout.go @@ -43,7 +43,6 @@ func NewRefundPegoutUseCase( func (useCase *RefundPegoutUseCase) Run(ctx context.Context, retainedQuote quote.RetainedPegoutQuote) error { var params blockchain.RefundPegoutParams var pegoutQuote *quote.PegoutQuote - var lpBtcTransaction blockchain.BitcoinTransactionInformation var err error if retainedQuote.State != quote.PegoutStateSendPegoutSucceeded { @@ -56,7 +55,7 @@ func (useCase *RefundPegoutUseCase) Run(ctx context.Context, retainedQuote quote return useCase.publishErrorEvent(ctx, retainedQuote, usecases.QuoteNotFoundError, false) } - if lpBtcTransaction, err = useCase.getLpBtcTransactionIfValid(ctx, *pegoutQuote, retainedQuote); err != nil { + if err = useCase.validateBtcTransaction(ctx, *pegoutQuote, retainedQuote); err != nil { return err } @@ -68,10 +67,6 @@ func (useCase *RefundPegoutUseCase) Run(ctx context.Context, retainedQuote quote useCase.rskWalletMutex.Lock() defer useCase.rskWalletMutex.Unlock() - if err = usecases.RegisterCoinbaseTransaction(useCase.rpc.Btc, useCase.contracts.Bridge, lpBtcTransaction); err != nil { - return useCase.publishErrorEvent(ctx, retainedQuote, err, errors.Is(err, blockchain.WaitingForBridgeError)) - } - if _, err = useCase.performRefundPegout(ctx, retainedQuote, txConfig, params); err != nil { return err } @@ -164,17 +159,17 @@ func (useCase *RefundPegoutUseCase) performRefundPegout( return retainedQuote, nil } -func (useCase *RefundPegoutUseCase) getLpBtcTransactionIfValid( +func (useCase *RefundPegoutUseCase) validateBtcTransaction( ctx context.Context, pegoutQuote quote.PegoutQuote, retainedQuote quote.RetainedPegoutQuote, -) (blockchain.BitcoinTransactionInformation, error) { +) error { var txInfo blockchain.BitcoinTransactionInformation var err error if txInfo, err = useCase.rpc.Btc.GetTransactionInfo(retainedQuote.LpBtcTxHash); err != nil { - return blockchain.BitcoinTransactionInformation{}, useCase.publishErrorEvent(ctx, retainedQuote, err, true) + return useCase.publishErrorEvent(ctx, retainedQuote, err, true) } else if txInfo.Confirmations < uint64(pegoutQuote.TransferConfirmations) { - return blockchain.BitcoinTransactionInformation{}, useCase.publishErrorEvent(ctx, retainedQuote, usecases.NoEnoughConfirmationsError, true) + return useCase.publishErrorEvent(ctx, retainedQuote, usecases.NoEnoughConfirmationsError, true) } - return txInfo, nil + return nil } diff --git a/internal/usecases/pegout/refund_pegout_test.go b/internal/usecases/pegout/refund_pegout_test.go index afbd6ccd..b19100fb 100644 --- a/internal/usecases/pegout/refund_pegout_test.go +++ b/internal/usecases/pegout/refund_pegout_test.go @@ -6,7 +6,6 @@ import ( "github.com/rsksmart/liquidity-provider-server/internal/entities" "github.com/rsksmart/liquidity-provider-server/internal/entities/blockchain" "github.com/rsksmart/liquidity-provider-server/internal/entities/quote" - "github.com/rsksmart/liquidity-provider-server/internal/entities/utils" "github.com/rsksmart/liquidity-provider-server/internal/usecases" "github.com/rsksmart/liquidity-provider-server/internal/usecases/pegout" "github.com/rsksmart/liquidity-provider-server/test" @@ -111,8 +110,9 @@ func TestRefundPegoutUseCase_Run(t *testing.T) { mutex := new(mocks.MutexMock) mutex.On("Lock").Return().Once() mutex.On("Unlock").Return().Once() + bridge := new(mocks.BridgeMock) - contracts := blockchain.RskContracts{Lbc: lbc} + contracts := blockchain.RskContracts{Lbc: lbc, Bridge: bridge} rpc := blockchain.Rpc{Btc: btc} useCase := pegout.NewRefundPegoutUseCase(quoteRepository, contracts, eventBus, rpc, mutex) err := useCase.Run(context.Background(), retainedQuote) @@ -121,6 +121,7 @@ func TestRefundPegoutUseCase_Run(t *testing.T) { eventBus.AssertExpectations(t) btc.AssertExpectations(t) require.NoError(t, err) + bridge.AssertNotCalled(t, "RegisterBtcCoinbaseTransaction") } func TestRefundPegoutUseCase_Run_UpdateError(t *testing.T) { @@ -327,59 +328,3 @@ func TestRefundPegoutUseCase_Run_WrongState(t *testing.T) { mutex.AssertNotCalled(t, "Unlock") require.ErrorIs(t, err, usecases.WrongStateError) } - -func TestRefundPegoutUseCase_Run_RegisterCoinbase(t *testing.T) { - quoteRepository := new(mocks.PegoutQuoteRepositoryMock) - lbc := new(mocks.LbcMock) - bridge := new(mocks.BridgeMock) - eventBus := new(mocks.EventBusMock) - btc := new(mocks.BtcRpcMock) - mutex := new(mocks.MutexMock) - coinbaseInfo := blockchain.BtcCoinbaseTransactionInformation{BlockHash: utils.To32Bytes(utils.MustGetRandomBytes(32))} - // Mocks that don't change per test - mutex.On("Lock").Return().Times(3) - mutex.On("Unlock").Return().Times(3) - quoteRepository.EXPECT().UpdateRetainedQuote(test.AnyCtx, mock.Anything).Return(nil).Twice() - quoteRepository.EXPECT().GetQuote(test.AnyCtx, retainedQuote.QuoteHash).Return(&pegoutQuote, nil).Times(3) - tx := btcTxInfoMock - tx.HasWitness = true - btc.On("GetTransactionInfo", retainedQuote.LpBtcTxHash).Return(tx, nil).Times(3) - btc.On("GetCoinbaseInformation", retainedQuote.LpBtcTxHash).Return(coinbaseInfo, nil).Times(3) - btc.On("BuildMerkleBranch", mock.Anything).Return(merkleBranchMock, nil).Times(3) - btc.On("GetRawTransaction", mock.Anything).Return(btcRawTxMock, nil).Times(3) - btc.On("GetTransactionBlockInfo", mock.Anything).Return(btcBlockInfoMock, nil).Times(3) - // once as it'll be called only on 1st test - lbc.On("RefundPegout", mock.Anything, mock.Anything).Return(refundPegoutTxHash, nil).Once() - - contracts := blockchain.RskContracts{Lbc: lbc, Bridge: bridge} - rpc := blockchain.Rpc{Btc: btc} - useCase := pegout.NewRefundPegoutUseCase(quoteRepository, contracts, eventBus, rpc, mutex) - t.Run("Should call RegisterCoinbaseTransaction", func(t *testing.T) { - bridge.On("RegisterBtcCoinbaseTransaction", coinbaseInfo).Return(test.AnyHash, nil).Once() - eventBus.On("Publish", mock.MatchedBy(func(e quote.PegoutQuoteCompletedEvent) bool { - return e.Error == nil - })).Return().Once() - err := useCase.Run(context.Background(), retainedQuote) - require.NoError(t, err) - }) - t.Run("Should return recoverable error if tx wasn't registered due to waiting for the bridge", func(t *testing.T) { - bridge.On("RegisterBtcCoinbaseTransaction", coinbaseInfo).Return("", blockchain.WaitingForBridgeError).Once() - err := useCase.Run(context.Background(), retainedQuote) - require.Error(t, err) - require.NotErrorIs(t, err, usecases.NonRecoverableError) - }) - t.Run("Should return non recoverable error if tx wasn't registered due to any other error", func(t *testing.T) { - bridge.On("RegisterBtcCoinbaseTransaction", coinbaseInfo).Return("", assert.AnError).Once() - eventBus.On("Publish", mock.MatchedBy(func(e quote.PegoutQuoteCompletedEvent) bool { - return errors.Is(e.Error, usecases.NonRecoverableError) - })).Return().Once() - err := useCase.Run(context.Background(), retainedQuote) - require.ErrorIs(t, err, usecases.NonRecoverableError) - }) - mutex.AssertExpectations(t) - lbc.AssertExpectations(t) - bridge.AssertExpectations(t) - btc.AssertExpectations(t) - quoteRepository.AssertExpectations(t) - eventBus.AssertExpectations(t) -}