From 5608544d22bfe60065854ce9fc0daf9681b54157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 14:59:14 +0100 Subject: [PATCH] further split files and their funcitonality --- spv/createenvelope.go | 68 +++ spv/createenvelope_test.go | 760 ++++++++++++++++++++++++ spv/creator.go | 68 +-- spv/creator_test.go | 747 +----------------------- spv/verifier.go | 132 +---- spv/verifier_test.go | 1021 ++------------------------------- spv/verifymerkleproof_test.go | 2 +- spv/verifypayment.go | 121 ++++ spv/verifypayment_test.go | 1017 ++++++++++++++++++++++++++++++++ 9 files changed, 2029 insertions(+), 1907 deletions(-) create mode 100644 spv/createenvelope.go create mode 100644 spv/createenvelope_test.go create mode 100644 spv/verifypayment.go create mode 100644 spv/verifypayment_test.go diff --git a/spv/createenvelope.go b/spv/createenvelope.go new file mode 100644 index 0000000..a230465 --- /dev/null +++ b/spv/createenvelope.go @@ -0,0 +1,68 @@ +package spv + +import ( + "context" + "fmt" + + "github.com/libsv/go-bt/v2" + "github.com/pkg/errors" +) + +// CreateEnvelope builds and returns an spv.Envelope for the provided tx. +func (c *creator) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, error) { + if len(tx.Inputs) == 0 { + return nil, ErrNoTxInputs + } + + envelope := &Envelope{ + TxID: tx.TxID(), + RawTx: tx.String(), + Parents: make(map[string]*Envelope), + } + + for _, input := range tx.Inputs { + pTxID := input.PreviousTxIDStr() + + // If we already have added the tx to the parent envelope, there's no point in + // redoing the same work + if _, ok := envelope.Parents[pTxID]; ok { + continue + } + + // Check the store for a Merkle Proof for the current input. + mp, err := c.mpc.MerkleProof(ctx, pTxID) + if err != nil { + return nil, errors.Wrapf(err, "failed to get merkle proof for tx %s", pTxID) + } + if mp != nil { + // If a Merkle Proof exists, build and return an spv.Envelope + envelope.Parents[pTxID] = &Envelope{ + TxID: pTxID, + Proof: mp, + } + + // Skip getting the tx data as we have everything we need for verifying the current tx. + continue + } + + // If no merkle proof was found for the input, build a *bt.Tx from its TxID and recursively + // call this function building envelopes for inputs without proofs, until a parent with a + // Merkle Proof is found. + pTx, err := c.txc.Tx(ctx, pTxID) + if err != nil { + return nil, errors.Wrapf(err, "failed to get tx %s", pTxID) + } + if pTx == nil { + return nil, fmt.Errorf("could not find tx %s", pTxID) + } + + pEnvelope, err := c.CreateEnvelope(ctx, pTx) + if err != nil { + return nil, err + } + + envelope.Parents[pTxID] = pEnvelope + } + + return envelope, nil +} diff --git a/spv/createenvelope_test.go b/spv/createenvelope_test.go new file mode 100644 index 0000000..8ed56d4 --- /dev/null +++ b/spv/createenvelope_test.go @@ -0,0 +1,760 @@ +package spv_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/libsv/go-bc" + "github.com/libsv/go-bc/spv" + "github.com/libsv/go-bt/v2" + "github.com/stretchr/testify/assert" +) + +type mockTxMerkleGetter struct { + txStoreFunc func(context.Context, string) (*bt.Tx, error) + mpStoreFunc func(context.Context, string) (*bc.MerkleProof, error) +} + +func (m *mockTxMerkleGetter) Tx(ctx context.Context, txID string) (*bt.Tx, error) { + if m.txStoreFunc == nil { + return nil, errors.New("txGetterFunc in test is undefined") + } + + return m.txStoreFunc(ctx, txID) +} + +func (m *mockTxMerkleGetter) MerkleProof(ctx context.Context, txID string) (*bc.MerkleProof, error) { + if m.txStoreFunc == nil { + return nil, errors.New("mpGetterFunc in test is undefined") + } + + return m.mpStoreFunc(ctx, txID) +} + +func TestSPVEnvelope_CreateEnvelope(t *testing.T) { + tests := map[string]struct { + tx string + txFunc func(context.Context, string) (*bt.Tx, error) + mpFunc func(context.Context, string) (*bc.MerkleProof, error) + exp spv.Envelope + expErr error + }{ + "valid envelope created": { + tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + return nil, fmt.Errorf("this test should be be using txFunc, tx %s", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + mp, ok := map[string]*bc.MerkleProof{ + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + exp: spv.Envelope{ + TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", + RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + Parents: map[string]*spv.Envelope{ + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + TxID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + TxID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Proof: &bc.MerkleProof{ + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + TxID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Proof: &bc.MerkleProof{ + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + }, + }, + }, + }, + "creating an envelope with tx that doesn't exist errors": { + tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + if txID == "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3" { + return nil, nil + } + return nil, fmt.Errorf("tx %s not defined for this test", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + mp, ok := map[string]*bc.MerkleProof{ + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": nil, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + expErr: errors.New("could not find tx 9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3"), + }, + "error when getting tx is handled": { + tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + if txID == "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34" { + return nil, errors.New("big bad error") + } + return nil, fmt.Errorf("tx %s not defined in this test", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + mp, ok := map[string]*bc.MerkleProof{ + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": nil, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + expErr: errors.New("failed to get tx 5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34: big bad error"), + }, + "error when getting merkle proof is handled": { + tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + return nil, fmt.Errorf("this test should be be using txFunc, tx %s", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + if txID == "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c" { + return nil, errors.New("bigger badder error") + } + + mp, ok := map[string]*bc.MerkleProof{ + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + expErr: errors.New("failed to get merkle proof for tx c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c: bigger badder error"), + }, + "envelope needing multiple layers can be built": { + tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + switch txID { + case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": //nolint:goconst + return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") + case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": //nolint:goconst + return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") + case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": //nolint:goconst + return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") + } + return nil, fmt.Errorf("tx %s not defined for test", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + mp, ok := map[string]*bc.MerkleProof{ + "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, + "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { + Index: 3, + TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + exp: spv.Envelope{ + TxID: "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759", + RawTx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + Parents: map[string]*spv.Envelope{ + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Proof: &bc.MerkleProof{ + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + }, + "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": { + TxID: "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161", + RawTx: "02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000", + Parents: map[string]*spv.Envelope{ + "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": { + TxID: "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a", + RawTx: "0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000", + Parents: map[string]*spv.Envelope{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { + TxID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + Proof: &bc.MerkleProof{ + Index: 3, + TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }, + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Proof: &bc.MerkleProof{ + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + }, + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": { + TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", + RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + Parents: map[string]*spv.Envelope{ + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + TxID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + TxID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Proof: &bc.MerkleProof{ + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + TxID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Proof: &bc.MerkleProof{ + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "missing tx multiple layers down causes error": { + tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + switch txID { + case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": + return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") + case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": + return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") + case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": + return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") + case "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": + return nil, nil + } + return nil, fmt.Errorf("tx %s not defined for test", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + mp, ok := map[string]*bc.MerkleProof{ + "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, + "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": nil, // The missing tx + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + expErr: errors.New("could not find tx 57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92"), + }, + "error getting tx multiple layers down is handled": { + tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + switch txID { + case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": + return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") + case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": + return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") + case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": + return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") + case "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": + return nil, errors.New("close but no cigar") + } + return nil, fmt.Errorf("tx %s not defined for test", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + mp, ok := map[string]*bc.MerkleProof{ + "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, + "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": nil, // the erroring tx + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { + Index: 3, + TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + expErr: errors.New("failed to get tx 9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3: close but no cigar"), + }, + "error getting merkle proof multiple layers down is handled": { + tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { + switch txID { + case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": + return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") + case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": + return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") + case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": + return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") + } + return nil, fmt.Errorf("tx %s not defined for test", txID) + }, + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { + if txID == "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c" { + return nil, errors.New("no proof for you") + } + mp, ok := map[string]*bc.MerkleProof{ + "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, + "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, + "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, + "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { + Index: 1, + TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", + "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { + Index: 2, + TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { + Index: 4, + TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "*", + "*", + "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", + }, + }, + "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { + Index: 6, + TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", + Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", + Nodes: []string{ + "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", + "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", + "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", + }, + }, + "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { + Index: 3, + TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", + Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", + Nodes: []string{ + "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", + "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", + "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", + }, + }, + }[txID] + if !ok { + return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) + } + + return mp, nil + }, + expErr: errors.New("failed to get merkle proof for tx c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c: no proof for you"), + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + testTx, err := bt.NewTxFromString(test.tx) + assert.NoError(t, err) + + mock := &mockTxMerkleGetter{ + txStoreFunc: test.txFunc, + mpStoreFunc: test.mpFunc, + } + + c, err := spv.NewEnvelopeCreator(mock, mock) + assert.NoError(t, err) + + envelope, err := c.CreateEnvelope(context.TODO(), testTx) + if test.expErr == nil { + assert.NoError(t, err) + assert.NotNil(t, envelope) + assert.Equal(t, test.exp, *envelope) + } else { + assert.Error(t, err) + assert.EqualError(t, err, test.expErr.Error()) + } + }) + } +} diff --git a/spv/creator.go b/spv/creator.go index 658b506..e1108e1 100644 --- a/spv/creator.go +++ b/spv/creator.go @@ -2,19 +2,18 @@ package spv import ( "context" - "fmt" "github.com/libsv/go-bc" "github.com/libsv/go-bt/v2" "github.com/pkg/errors" ) -// A Creator is an interface used to build the spv.Envelope data type for +// An EnvelopeCreator is an interface used to build the spv.Envelope data type for // Simple Payment Verification (SPV). // // The implementation of an spv.TxStore and spv.MerkleProofStore which is supplied will depend // on the client you are using. -type Creator interface { +type EnvelopeCreator interface { CreateEnvelope(context.Context, *bt.Tx) (*Envelope, error) } @@ -33,9 +32,9 @@ type creator struct { mpc MerkleProofStore } -// NewCreator creates a new spv.Creator with the provided spv.TxStore and tx.MerkleProofStore. +// NewEnvelopeCreator creates a new spv.Creator with the provided spv.TxStore and tx.MerkleProofStore. // If either implementation is not provided, the setup will return an error. -func NewCreator(txc TxStore, mpc MerkleProofStore) (Creator, error) { +func NewEnvelopeCreator(txc TxStore, mpc MerkleProofStore) (EnvelopeCreator, error) { if txc == nil { return nil, errors.New("an spv.TxStore implementation is required") } @@ -45,62 +44,3 @@ func NewCreator(txc TxStore, mpc MerkleProofStore) (Creator, error) { return &creator{txc: txc, mpc: mpc}, nil } - -// CreateEnvelope builds and returns an spv.Envelope for the provided tx. -func (c *creator) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, error) { - if len(tx.Inputs) == 0 { - return nil, ErrNoTxInputs - } - - envelope := &Envelope{ - TxID: tx.TxID(), - RawTx: tx.String(), - Parents: make(map[string]*Envelope), - } - - for _, input := range tx.Inputs { - pTxID := input.PreviousTxIDStr() - - // If we already have added the tx to the parent envelope, there's no point in - // redoing the same work - if _, ok := envelope.Parents[pTxID]; ok { - continue - } - - // Check the store for a Merkle Proof for the current input. - mp, err := c.mpc.MerkleProof(ctx, pTxID) - if err != nil { - return nil, errors.Wrapf(err, "failed to get merkle proof for tx %s", pTxID) - } - if mp != nil { - // If a Merkle Proof exists, build and return an spv.Envelope - envelope.Parents[pTxID] = &Envelope{ - TxID: pTxID, - Proof: mp, - } - - // Skip getting the tx data as we have everything we need for verifying the current tx. - continue - } - - // If no merkle proof was found for the input, build a *bt.Tx from its TxID and recursively - // call this function building envelopes for inputs without proofs, until a parent with a - // Merkle Proof is found. - pTx, err := c.txc.Tx(ctx, pTxID) - if err != nil { - return nil, errors.Wrapf(err, "failed to get tx %s", pTxID) - } - if pTx == nil { - return nil, fmt.Errorf("could not find tx %s", pTxID) - } - - pEnvelope, err := c.CreateEnvelope(ctx, pTx) - if err != nil { - return nil, err - } - - envelope.Parents[pTxID] = pEnvelope - } - - return envelope, nil -} diff --git a/spv/creator_test.go b/spv/creator_test.go index 90dfc2b..3de33b5 100644 --- a/spv/creator_test.go +++ b/spv/creator_test.go @@ -1,756 +1,41 @@ package spv_test import ( - "context" - "errors" - "fmt" "testing" - "github.com/libsv/go-bc" "github.com/libsv/go-bc/spv" - "github.com/libsv/go-bt/v2" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) -type mockTxMerkleGetter struct { - txStoreFunc func(context.Context, string) (*bt.Tx, error) - mpStoreFunc func(context.Context, string) (*bc.MerkleProof, error) -} - -func (m *mockTxMerkleGetter) Tx(ctx context.Context, txID string) (*bt.Tx, error) { - if m.txStoreFunc == nil { - return nil, errors.New("txGetterFunc in test is undefined") - } - - return m.txStoreFunc(ctx, txID) -} - -func (m *mockTxMerkleGetter) MerkleProof(ctx context.Context, txID string) (*bc.MerkleProof, error) { - if m.txStoreFunc == nil { - return nil, errors.New("mpGetterFunc in test is undefined") - } - - return m.mpStoreFunc(ctx, txID) -} - -func TestSPVEnvelope_CreateEnvelope(t *testing.T) { +func TestEnvelopeCreator_NewEnvelopeCreator(t *testing.T) { tests := map[string]struct { - tx string - txFunc func(context.Context, string) (*bt.Tx, error) - mpFunc func(context.Context, string) (*bc.MerkleProof, error) - exp spv.Envelope + txc spv.TxStore + mpc spv.MerkleProofStore expErr error }{ - "valid envelope created": { - tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - return nil, fmt.Errorf("this test should be be using txFunc, tx %s", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - mp, ok := map[string]*bc.MerkleProof{ - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - exp: spv.Envelope{ - TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", - RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - Parents: map[string]*spv.Envelope{ - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - TxID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - TxID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Proof: &bc.MerkleProof{ - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - TxID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Proof: &bc.MerkleProof{ - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - }, - }, - }, + "successful create": { + txc: &mockTxMerkleGetter{}, + mpc: &mockTxMerkleGetter{}, }, - "creating an envelope with tx that doesn't exist errors": { - tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - if txID == "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3" { - return nil, nil - } - return nil, fmt.Errorf("tx %s not defined for this test", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - mp, ok := map[string]*bc.MerkleProof{ - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": nil, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - expErr: errors.New("could not find tx 9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3"), + "undefined txc errors": { + mpc: &mockTxMerkleGetter{}, + expErr: errors.New("an spv.TxStore implementation is required"), }, - "error when getting tx is handled": { - tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - if txID == "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34" { - return nil, errors.New("big bad error") - } - return nil, fmt.Errorf("tx %s not defined in this test", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - mp, ok := map[string]*bc.MerkleProof{ - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": nil, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - expErr: errors.New("failed to get tx 5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34: big bad error"), + "undefined mpc errors": { + txc: &mockTxMerkleGetter{}, + expErr: errors.New("an spv.MerkleProofStore implementation is required"), }, - "error when getting merkle proof is handled": { - tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - return nil, fmt.Errorf("this test should be be using txFunc, tx %s", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - if txID == "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c" { - return nil, errors.New("bigger badder error") - } - - mp, ok := map[string]*bc.MerkleProof{ - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - expErr: errors.New("failed to get merkle proof for tx c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c: bigger badder error"), - }, - "envelope needing multiple layers can be built": { - tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - switch txID { - case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": //nolint:goconst - return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") - case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": //nolint:goconst - return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") - case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": //nolint:goconst - return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") - } - return nil, fmt.Errorf("tx %s not defined for test", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - mp, ok := map[string]*bc.MerkleProof{ - "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, - "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, - "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { - Index: 3, - TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", - Nodes: []string{ - "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", - }, - }, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { - Index: 3, - TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - exp: spv.Envelope{ - TxID: "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759", - RawTx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - Parents: map[string]*spv.Envelope{ - "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { - TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Proof: &bc.MerkleProof{ - Index: 3, - TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", - Nodes: []string{ - "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", - }, - }, - }, - "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": { - TxID: "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161", - RawTx: "02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000", - Parents: map[string]*spv.Envelope{ - "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": { - TxID: "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a", - RawTx: "0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000", - Parents: map[string]*spv.Envelope{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { - TxID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - Proof: &bc.MerkleProof{ - Index: 3, - TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }, - "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { - TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Proof: &bc.MerkleProof{ - Index: 3, - TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", - Nodes: []string{ - "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", - }, - }, - }, - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": { - TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", - RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - Parents: map[string]*spv.Envelope{ - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - TxID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - TxID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Proof: &bc.MerkleProof{ - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - TxID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Proof: &bc.MerkleProof{ - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "missing tx multiple layers down causes error": { - tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - switch txID { - case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": - return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") - case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": - return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") - case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": - return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") - case "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": - return nil, nil - } - return nil, fmt.Errorf("tx %s not defined for test", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - mp, ok := map[string]*bc.MerkleProof{ - "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, - "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, - "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { - Index: 3, - TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", - Nodes: []string{ - "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", - }, - }, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": nil, // The missing tx - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - expErr: errors.New("could not find tx 57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92"), - }, - "error getting tx multiple layers down is handled": { - tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - switch txID { - case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": - return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") - case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": - return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") - case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": - return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") - case "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": - return nil, errors.New("close but no cigar") - } - return nil, fmt.Errorf("tx %s not defined for test", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - mp, ok := map[string]*bc.MerkleProof{ - "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, - "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, - "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { - Index: 3, - TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", - Nodes: []string{ - "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", - }, - }, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": nil, // the erroring tx - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { - Index: 3, - TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - expErr: errors.New("failed to get tx 9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3: close but no cigar"), - }, - "error getting merkle proof multiple layers down is handled": { - tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { - switch txID { - case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": - return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") - case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": - return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") - case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": - return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") - } - return nil, fmt.Errorf("tx %s not defined for test", txID) - }, - mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { - if txID == "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c" { - return nil, errors.New("no proof for you") - } - mp, ok := map[string]*bc.MerkleProof{ - "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, - "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, - "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": nil, - "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": nil, - "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { - Index: 3, - TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", - Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", - Nodes: []string{ - "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", - }, - }, - "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { - Index: 1, - TxOrID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "3ba440c59dfa71bad3f8cf8b11c74aa16c3f5cdf95def774c2797cc04075affb", - "db5c17b1e18b2ccd42390dfc879d3989010ad14b568fb85545a4cce557eb2675", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c": { - Index: 2, - TxOrID: "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": { - Index: 4, - TxOrID: "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "*", - "*", - "967b0f389e91648a50f70727bea61bbe7579efee803474780592e3d07a5327f7", - }, - }, - "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": { - Index: 6, - TxOrID: "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34", - Target: "1984451251001b3770f71a6c7beb291a02112d7b93174b58b4be0baae43a0f74", - Nodes: []string{ - "d72e6459a7402c0327c21a7cf8bb2a4e8e006ff0a0699e9f7b65a4db61bcf368", - "ce4fdb7ba7a5a70acbe3a76ce0af60c162109a697fd181ddbd7feab8194b226e", - "4a259318801977c0970becf54f591b91f426b9a15cc6bb09c960c937e2483837", - }, - }, - "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { - Index: 3, - TxOrID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", - Target: "3df51f7b4aea26ad36c5a6742f8574bcc4abd5f240c7729aef54f8a53f2a500a", - Nodes: []string{ - "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c", - "f2fea4f224492c409ad3bd31845187f5017b4cbceab69f45e922ff1c2d7ac8d5", - "4a9ca540c926b5044b1841a622865106618a2613bfe36b36513ce22006983616", - }, - }, - }[txID] - if !ok { - return nil, fmt.Errorf("merkle proof for tx %s not defined in test", txID) - } - - return mp, nil - }, - expErr: errors.New("failed to get merkle proof for tx c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c: no proof for you"), + "both stores undefined errors": { + expErr: errors.New("an spv.TxStore implementation is required"), }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - testTx, err := bt.NewTxFromString(test.tx) - assert.NoError(t, err) - - mock := &mockTxMerkleGetter{ - txStoreFunc: test.txFunc, - mpStoreFunc: test.mpFunc, - } - - c, err := spv.NewCreator(mock, mock) - assert.NoError(t, err) - - envelope, err := c.CreateEnvelope(context.TODO(), testTx) + _, err := spv.NewEnvelopeCreator(test.txc, test.mpc) if test.expErr == nil { assert.NoError(t, err) - assert.NotNil(t, envelope) - assert.Equal(t, test.exp, *envelope) } else { assert.Error(t, err) assert.EqualError(t, err, test.expErr.Error()) diff --git a/spv/verifier.go b/spv/verifier.go index 948e204..00cb863 100644 --- a/spv/verifier.go +++ b/spv/verifier.go @@ -4,23 +4,17 @@ import ( "context" "github.com/libsv/go-bc" - "github.com/libsv/go-bt/v2" "github.com/pkg/errors" ) -// A Verifier is an interface used to complete Simple Payment Verification (SPV) +// A PaymentVerifier is an interface used to complete Simple Payment Verification (SPV) // in conjunction with a Merkle Proof. // // The implementation of bc.BlockHeaderChain which is supplied will depend on the client // you are using, some may return a HeaderJSON response others may return the blockhash. -type Verifier interface { - EnvelopeVerifier - MerkleProofVerifier -} - -// EnvelopeVerifier interfaces the verification of SPV Envelopes -type EnvelopeVerifier interface { +type PaymentVerifier interface { VerifyPayment(context.Context, *Envelope) (bool, error) + MerkleProofVerifier } // MerkleProofVerifier interfaces the verification of Merkle Proofs @@ -34,9 +28,9 @@ type verifier struct { bhc bc.BlockHeaderChain } -// NewVerifier creates a new spv.Verifer with the bc.BlockHeaderChain provided. +// NewPaymentVerifier creates a new spv.PaymentVerifer with the bc.BlockHeaderChain provided. // If no BlockHeaderChain implementation is provided, the setup will return an error. -func NewVerifier(bhc bc.BlockHeaderChain) (Verifier, error) { +func NewPaymentVerifier(bhc bc.BlockHeaderChain) (PaymentVerifier, error) { if bhc == nil { return nil, errors.New("at least one blockchain header implementation should be returned") } @@ -44,116 +38,8 @@ func NewVerifier(bhc bc.BlockHeaderChain) (Verifier, error) { return &verifier{bhc: bhc}, nil } -// VerifyPayment verifies whether or not the txs supplied via the supplied spv.Envelope are valid -func (v *verifier) VerifyPayment(ctx context.Context, initialPayment *Envelope) (bool, error) { - if initialPayment == nil { - return false, ErrNilInitialPayment - } - - // The tip tx is the transaction we're trying to verify, and it should not have a supplied - // Merkle Proof. - if initialPayment.IsAnchored() { - return false, ErrTipTxConfirmed - } - - valid, err := v.verifyTxs(ctx, initialPayment) - if err != nil { - return false, err - } - - return valid, nil -} - -func (v *verifier) verifyTxs(ctx context.Context, payment *Envelope) (bool, error) { - // If at the beginning or middle of the tx chain and tx is unconfirmed, fail and error. - if !payment.IsAnchored() && (payment.Parents == nil || len(payment.Parents) == 0) { - return false, ErrNoConfirmedTransaction - } - - // Recurse back to the anchor transactions of the transaction chain and verify forward towards - // the tip transaction. This way, we check that the first transactions in the chain are anchored - // to the blockchain through a valid Merkle Proof. - for parentTxID, parent := range payment.Parents { - if parent.TxID == "" { - parent.TxID = parentTxID - } - - valid, err := v.verifyTxs(ctx, parent) - if err != nil { - return false, err - } - if !valid { - return false, nil - } - } - - // If a Merkle Proof is provided, assume we are at the anchor/beginning of the tx chain. - // Verify and return the result. - if payment.IsAnchored() { - return v.verifyTxAnchor(ctx, payment) - } - - tx, err := bt.NewTxFromString(payment.RawTx) - if err != nil { - return false, err - } - - // We must verify the tx or else we can not know if any of it's child txs are valid. - return v.verifyUnconfirmedTx(tx, payment) -} - -func (v *verifier) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, error) { - proofTxID := payment.Proof.TxOrID - if len(proofTxID) != 64 { - proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) - if err != nil { - return false, err - } - - proofTxID = proofTx.TxID() - } - - // If the txid of the Merkle Proof doesn't match the txid provided in the spv.Envelope, - // fail and error - if proofTxID != payment.TxID { - return false, ErrTxIDMismatch - } - - valid, _, err := v.VerifyMerkleProofJSON(ctx, payment.Proof) - if err != nil { - return false, err - } - - return valid, nil -} - -func (v *verifier) verifyUnconfirmedTx(tx *bt.Tx, payment *Envelope) (bool, error) { - // If no tx inputs have been provided, fail and error - if len(tx.Inputs) == 0 { - return false, ErrNoTxInputsToVerify - } - - for _, input := range tx.Inputs { - parent, ok := payment.Parents[input.PreviousTxIDStr()] - if !ok { - return false, ErrNotAllInputsSupplied - } - - parentTx, err := bt.NewTxFromString(parent.RawTx) - if err != nil { - return false, err - } - - // If the input is indexing an output that is out of bounds, fail and error - if int(input.PreviousTxOutIndex) > len(parentTx.Outputs)-1 { - return false, ErrInputRefsOutOfBoundsOutput - } - - output := parentTx.Outputs[int(input.PreviousTxOutIndex)] - - // TODO: verify script using input and previous output - _ = output - } - - return true, nil +// NewMerkleProofVerifier creates a new spv.MerkleProofVerifer with the bc.BlockHeaderChain provided. +// If no BlockHeaderChain implementation is provided, the setup will return an error. +func NewMerkleProofVerifier(bhc bc.BlockHeaderChain) (MerkleProofVerifier, error) { + return NewPaymentVerifier(bhc) } diff --git a/spv/verifier_test.go b/spv/verifier_test.go index e2d89a1..bead16c 100644 --- a/spv/verifier_test.go +++ b/spv/verifier_test.go @@ -1,7 +1,6 @@ package spv_test import ( - "context" "testing" "github.com/libsv/go-bc" @@ -10,1008 +9,54 @@ import ( "github.com/stretchr/testify/assert" ) -type mockBlockHeaderClient struct { - blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) -} - -func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if m.blockHeaderFunc != nil { - return m.blockHeaderFunc(ctx, blockHash) +func TestPaymentVerifier_NewPaymentVerifier(t *testing.T) { + tests := map[string]struct { + bhc bc.BlockHeaderChain + expErr error + }{ + "successful create": { + bhc: &mockBlockHeaderClient{}, + }, + "undefined bhc errors": { + expErr: errors.New("at least one blockchain header implementation should be returned"), + }, } - return nil, errors.New("blockHeaderFunc in test is undefined") + for name, test := range tests { + t.Run(name, func(t *testing.T) { + _, err := spv.NewPaymentVerifier(test.bhc) + if test.expErr == nil { + assert.NoError(t, err) + } else { + assert.Error(t, err) + assert.EqualError(t, err, test.expErr.Error()) + } + }) + } } -func TestSPVEnvelope_VerifyPayment(t *testing.T) { +func TestMerkleProofVerifier_NewMerkleProofVerifier(t *testing.T) { tests := map[string]struct { - envelope *spv.Envelope - blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) - exp bool - expErr error + bhc bc.BlockHeaderChain + expErr error }{ - "valid envelope passes": { - exp: true, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", - "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "envelope without any proof fails": { - exp: false, - expErr: spv.ErrNoConfirmedTransaction, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", - "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - }, - }, - }, - }, - "valid envelope with merkle proof supplied as hex passes": { - exp: true, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", - "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "invalid merkle proof fails": { - exp: false, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", - "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 2, // fails, should be 1 to pass - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, + "successful create": { + bhc: &mockBlockHeaderClient{}, }, - "wrong tx supplied as input in envelope errs": { - exp: false, - expErr: spv.ErrNotAllInputsSupplied, - blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - }, - envelope: &spv.Envelope{ - TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs - RawTx: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", - Parents: map[string]*spv.Envelope{ - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above - TxID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "wrong merkle proof supplied with otherwise correct input errors": { - exp: false, - expErr: spv.ErrTxIDMismatch, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx - Index: 1, - TxOrID: "2e2b706ddede3b8c5e9bd13c684a0678072b11898770167c7ce569095d386df5", - Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", - Nodes: []string{ - "a859bb441c1a0082f1e3ffb24361242375ab63e648e1367d19d75cbe36a9ecaf", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "wrong merkle proof supplied via hex with otherwise correct input errors": { - exp: false, - expErr: spv.ErrTxIDMismatch, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx - Index: 1, - TxOrID: "0200000001e6512113175679cc5c78d637b0934e2e09bcd0d6a6693c11a372c0effd055ebf010000006a47304402200bf8ddd45e87d187740d1500451f54e24933be6d4cb188b2d8c300895ffe1c5e02207f82e9c9e97387cd5341a51d10e06455a21fcb53ffb5ba006ef91a2ab3dc4383412102ac939508911a1266ea64a30f6d3f2b311527c379087deca7171700e0369ecfa9feffffff0294cef008000000001976a9144cd75969d2baa7b0e5eab0d52f6555496799033088ac00e1f505000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac6a000000", - Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", - Nodes: []string{ - "a859bb441c1a0082f1e3ffb24361242375ab63e648e1367d19d75cbe36a9ecaf", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "envelope with tx no inputs errs": { - exp: false, - expErr: spv.ErrNoTxInputsToVerify, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", - "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "tx with input indexing out of bounds output errors": { - exp: false, - expErr: spv.ErrInputRefsOutOfBoundsOutput, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") - } - return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0020000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // tx.Input[0].PreviousTxOutIndex has been changed from 1, to 2, leaving it out of bounds - Parents: map[string]*spv.Envelope{ - "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", - "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", - }, - }, - }, - "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", - Nodes: []string{ - "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", - }, - }, - }, - }, - }, - }, - "valid multiple layer tx passes": { - exp: true, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": //nolint:goconst - return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": //nolint:goconst - return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") - } - return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*spv.Envelope{ - "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { - TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*spv.Envelope{ - "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { - TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", - Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", - Nodes: []string{ - "*", - "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", - }, - }, - }, - "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*spv.Envelope{ - "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { - TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { - TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", - Nodes: []string{ - "*", - "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "invalid multiple layer tx false": { - exp: false, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") - } - return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*spv.Envelope{ - "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { - TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*spv.Envelope{ - "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { - TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", - Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", - Nodes: []string{ - "*", - "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", - }, - }, - }, - "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*spv.Envelope{ - "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { - TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 2, // failure here, should be 1 to pass - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { - TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", - Nodes: []string{ - "*", - "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "tx with input missing from envelope parents errors": { - exp: false, - expErr: spv.ErrNotAllInputsSupplied, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") - } - return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*spv.Envelope{ - "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { - TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*spv.Envelope{ - "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { - TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", - Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", - Nodes: []string{ - "*", - "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", - }, - }, - }, - "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*spv.Envelope{ - "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { - TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - // Tx missing here, b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f - }, - }, - }, - }, - }, - }, - }, - "wrong merkle proof suppled with otherwise correct layered input errors": { - exp: false, - expErr: spv.ErrTxIDMismatch, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") - } - return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*spv.Envelope{ - "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { - TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*spv.Envelope{ - "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { - TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &bc.MerkleProof{ // This Merkle Proof is valid, it is just for a different tx. - Index: 2, - TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", - Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", - Nodes: []string{ - "*", - "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", - }, - }, - }, - "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*spv.Envelope{ - "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { - TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { - TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", - Nodes: []string{ - "*", - "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "single missing merkle proof in layered and branching tx errors": { - exp: false, - expErr: spv.ErrNoConfirmedTransaction, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") - } - return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*spv.Envelope{ - "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { - TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*spv.Envelope{ - "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { - TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", - Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", - Nodes: []string{ - "*", - "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", - }, - }, - }, - "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*spv.Envelope{ - "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { - TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*spv.Envelope{ // This tx is missing its proof - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - }, - }, - }, - "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { - TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", - Nodes: []string{ - "*", - "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "tx with no inputs in multiple layer tx fails": { - exp: false, - expErr: spv.ErrNoTxInputsToVerify, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { - switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") - } - return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*spv.Envelope{ - "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { - TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*spv.Envelope{ - "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { - TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", - Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", - Nodes: []string{ - "*", - "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", - }, - }, - }, - "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*spv.Envelope{ - "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { - TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTx: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed - Parents: map[string]*spv.Envelope{ - "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", - Nodes: []string{ - "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", - }, - }, - }, - }, - }, - "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { - TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &bc.MerkleProof{ - Index: 2, - TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", - Nodes: []string{ - "*", - "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - "envelope with confirmed root errs": { - exp: false, - expErr: spv.ErrTipTxConfirmed, - blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { - return bc.NewBlockHeaderFromStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") - }, - envelope: &spv.Envelope{ - TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", - RawTx: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", - Proof: &bc.MerkleProof{ - Index: 1, - TxOrID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", - Target: "4f40da9ccedebb65ec7c29e4188ca11461668d7f2ae2e4e35b59b0fe4d266406", - Nodes: []string{ - "00a43044caef87323a3ddee74dc7917e1dfd2371e9c43f208040cfe3737ee5ec", - }, - }, - }, - }, - "nil initial payment errors": { - exp: false, - expErr: spv.ErrNilInitialPayment, + "undefined bhc errors": { + expErr: errors.New("at least one blockchain header implementation should be returned"), }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - v, err := spv.NewVerifier(&mockBlockHeaderClient{ - blockHeaderFunc: test.blockHeaderFunc, - }) - assert.NoError(t, err, "expected no error when creating spv client") - - valid, err := v.VerifyPayment(context.Background(), test.envelope) - if test.expErr != nil { + _, err := spv.NewMerkleProofVerifier(test.bhc) + if test.expErr == nil { + assert.NoError(t, err) + } else { assert.Error(t, err) assert.EqualError(t, err, test.expErr.Error()) - } else { - assert.NoError(t, err) } - assert.Equal(t, test.exp, valid) }) } } diff --git a/spv/verifymerkleproof_test.go b/spv/verifymerkleproof_test.go index 65ffae4..382f108 100644 --- a/spv/verifymerkleproof_test.go +++ b/spv/verifymerkleproof_test.go @@ -32,7 +32,7 @@ func TestVerifyMerkleProof(t *testing.T) { } hcm := &mockBlockHeaderChain{} - v, _ := spv.NewVerifier(hcm) + v, _ := spv.NewMerkleProofVerifier(hcm) t.Run("JSON", func(t *testing.T) { valid, isLastInTree, err := v.VerifyMerkleProofJSON(context.Background(), proofJSON) diff --git a/spv/verifypayment.go b/spv/verifypayment.go new file mode 100644 index 0000000..d9b03eb --- /dev/null +++ b/spv/verifypayment.go @@ -0,0 +1,121 @@ +package spv + +import ( + "context" + + "github.com/libsv/go-bt/v2" +) + +// VerifyPayment verifies whether or not the txs supplied via the supplied spv.Envelope are valid +func (v *verifier) VerifyPayment(ctx context.Context, initialPayment *Envelope) (bool, error) { + if initialPayment == nil { + return false, ErrNilInitialPayment + } + + // The tip tx is the transaction we're trying to verify, and it should not have a supplied + // Merkle Proof. + if initialPayment.IsAnchored() { + return false, ErrTipTxConfirmed + } + + valid, err := v.verifyTxs(ctx, initialPayment) + if err != nil { + return false, err + } + + return valid, nil +} + +func (v *verifier) verifyTxs(ctx context.Context, payment *Envelope) (bool, error) { + // If at the beginning or middle of the tx chain and tx is unconfirmed, fail and error. + if !payment.IsAnchored() && (payment.Parents == nil || len(payment.Parents) == 0) { + return false, ErrNoConfirmedTransaction + } + + // Recurse back to the anchor transactions of the transaction chain and verify forward towards + // the tip transaction. This way, we check that the first transactions in the chain are anchored + // to the blockchain through a valid Merkle Proof. + for parentTxID, parent := range payment.Parents { + if parent.TxID == "" { + parent.TxID = parentTxID + } + + valid, err := v.verifyTxs(ctx, parent) + if err != nil { + return false, err + } + if !valid { + return false, nil + } + } + + // If a Merkle Proof is provided, assume we are at the anchor/beginning of the tx chain. + // Verify and return the result. + if payment.IsAnchored() { + return v.verifyTxAnchor(ctx, payment) + } + + tx, err := bt.NewTxFromString(payment.RawTx) + if err != nil { + return false, err + } + + // We must verify the tx or else we can not know if any of it's child txs are valid. + return v.verifyUnconfirmedTx(tx, payment) +} + +func (v *verifier) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, error) { + proofTxID := payment.Proof.TxOrID + if len(proofTxID) != 64 { + proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) + if err != nil { + return false, err + } + + proofTxID = proofTx.TxID() + } + + // If the txid of the Merkle Proof doesn't match the txid provided in the spv.Envelope, + // fail and error + if proofTxID != payment.TxID { + return false, ErrTxIDMismatch + } + + valid, _, err := v.VerifyMerkleProofJSON(ctx, payment.Proof) + if err != nil { + return false, err + } + + return valid, nil +} + +func (v *verifier) verifyUnconfirmedTx(tx *bt.Tx, payment *Envelope) (bool, error) { + // If no tx inputs have been provided, fail and error + if len(tx.Inputs) == 0 { + return false, ErrNoTxInputsToVerify + } + + for _, input := range tx.Inputs { + parent, ok := payment.Parents[input.PreviousTxIDStr()] + if !ok { + return false, ErrNotAllInputsSupplied + } + + parentTx, err := bt.NewTxFromString(parent.RawTx) + if err != nil { + return false, err + } + + // If the input is indexing an output that is out of bounds, fail and error + if int(input.PreviousTxOutIndex) > len(parentTx.Outputs)-1 { + return false, ErrInputRefsOutOfBoundsOutput + } + + output := parentTx.Outputs[int(input.PreviousTxOutIndex)] + + // TODO: verify script using input and previous output + _ = output + } + + return true, nil +} diff --git a/spv/verifypayment_test.go b/spv/verifypayment_test.go new file mode 100644 index 0000000..0322012 --- /dev/null +++ b/spv/verifypayment_test.go @@ -0,0 +1,1017 @@ +package spv_test + +import ( + "context" + "testing" + + "github.com/libsv/go-bc" + "github.com/libsv/go-bc/spv" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +type mockBlockHeaderClient struct { + blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) +} + +func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if m.blockHeaderFunc != nil { + return m.blockHeaderFunc(ctx, blockHash) + } + + return nil, errors.New("blockHeaderFunc in test is undefined") +} + +func TestSPVEnvelope_VerifyPayment(t *testing.T) { + tests := map[string]struct { + envelope *spv.Envelope + blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) + exp bool + expErr error + }{ + "valid envelope passes": { + exp: true, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "envelope without any proof fails": { + exp: false, + expErr: spv.ErrNoConfirmedTransaction, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + }, + }, + }, + }, + "valid envelope with merkle proof supplied as hex passes": { + exp: true, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "invalid merkle proof fails": { + exp: false, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 2, // fails, should be 1 to pass + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "wrong tx supplied as input in envelope errs": { + exp: false, + expErr: spv.ErrNotAllInputsSupplied, + blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + }, + envelope: &spv.Envelope{ + TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs + RawTx: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + Parents: map[string]*spv.Envelope{ + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above + TxID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "wrong merkle proof supplied with otherwise correct input errors": { + exp: false, + expErr: spv.ErrTxIDMismatch, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx + Index: 1, + TxOrID: "2e2b706ddede3b8c5e9bd13c684a0678072b11898770167c7ce569095d386df5", + Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", + Nodes: []string{ + "a859bb441c1a0082f1e3ffb24361242375ab63e648e1367d19d75cbe36a9ecaf", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "wrong merkle proof supplied via hex with otherwise correct input errors": { + exp: false, + expErr: spv.ErrTxIDMismatch, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx + Index: 1, + TxOrID: "0200000001e6512113175679cc5c78d637b0934e2e09bcd0d6a6693c11a372c0effd055ebf010000006a47304402200bf8ddd45e87d187740d1500451f54e24933be6d4cb188b2d8c300895ffe1c5e02207f82e9c9e97387cd5341a51d10e06455a21fcb53ffb5ba006ef91a2ab3dc4383412102ac939508911a1266ea64a30f6d3f2b311527c379087deca7171700e0369ecfa9feffffff0294cef008000000001976a9144cd75969d2baa7b0e5eab0d52f6555496799033088ac00e1f505000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac6a000000", + Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", + Nodes: []string{ + "a859bb441c1a0082f1e3ffb24361242375ab63e648e1367d19d75cbe36a9ecaf", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "envelope with tx no inputs errs": { + exp: false, + expErr: spv.ErrNoTxInputsToVerify, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "tx with input indexing out of bounds output errors": { + exp: false, + expErr: spv.ErrInputRefsOutOfBoundsOutput, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0020000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // tx.Input[0].PreviousTxOutIndex has been changed from 1, to 2, leaving it out of bounds + Parents: map[string]*spv.Envelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, + "valid multiple layer tx passes": { + exp: true, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": //nolint:goconst + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": //nolint:goconst + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*spv.Envelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*spv.Envelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", + Nodes: []string{ + "*", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*spv.Envelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "invalid multiple layer tx false": { + exp: false, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*spv.Envelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*spv.Envelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", + Nodes: []string{ + "*", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*spv.Envelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 2, // failure here, should be 1 to pass + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "tx with input missing from envelope parents errors": { + exp: false, + expErr: spv.ErrNotAllInputsSupplied, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*spv.Envelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*spv.Envelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", + Nodes: []string{ + "*", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*spv.Envelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + // Tx missing here, b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f + }, + }, + }, + }, + }, + }, + }, + "wrong merkle proof suppled with otherwise correct layered input errors": { + exp: false, + expErr: spv.ErrTxIDMismatch, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*spv.Envelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*spv.Envelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &bc.MerkleProof{ // This Merkle Proof is valid, it is just for a different tx. + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*spv.Envelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "single missing merkle proof in layered and branching tx errors": { + exp: false, + expErr: spv.ErrNoConfirmedTransaction, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*spv.Envelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*spv.Envelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", + Nodes: []string{ + "*", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*spv.Envelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*spv.Envelope{ // This tx is missing its proof + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "tx with no inputs in multiple layer tx fails": { + exp: false, + expErr: spv.ErrNoTxInputsToVerify, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*spv.Envelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*spv.Envelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", + Nodes: []string{ + "*", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*spv.Envelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTx: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed + Parents: map[string]*spv.Envelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &bc.MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "envelope with confirmed root errs": { + exp: false, + expErr: spv.ErrTipTxConfirmed, + blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { + return bc.NewBlockHeaderFromStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") + }, + envelope: &spv.Envelope{ + TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", + RawTx: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", + Proof: &bc.MerkleProof{ + Index: 1, + TxOrID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", + Target: "4f40da9ccedebb65ec7c29e4188ca11461668d7f2ae2e4e35b59b0fe4d266406", + Nodes: []string{ + "00a43044caef87323a3ddee74dc7917e1dfd2371e9c43f208040cfe3737ee5ec", + }, + }, + }, + }, + "nil initial payment errors": { + exp: false, + expErr: spv.ErrNilInitialPayment, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + v, err := spv.NewPaymentVerifier(&mockBlockHeaderClient{ + blockHeaderFunc: test.blockHeaderFunc, + }) + assert.NoError(t, err, "expected no error when creating spv client") + + valid, err := v.VerifyPayment(context.Background(), test.envelope) + if test.expErr != nil { + assert.Error(t, err) + assert.EqualError(t, err, test.expErr.Error()) + } else { + assert.NoError(t, err) + } + assert.Equal(t, test.exp, valid) + }) + } +}