From 11c5d38a190669b2cafb9333beefa25d26dce75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 13:55:05 +0100 Subject: [PATCH 01/51] first draft of spv validation, using only merkle proofs --- .gitignore | 3 +- go.mod | 1 + go.sum | 9 + spvclient.go | 4 +- spvenvelope.go | 135 ++++++++++++++ spvenvelope_test.go | 428 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 577 insertions(+), 3 deletions(-) create mode 100644 spvenvelope.go create mode 100644 spvenvelope_test.go diff --git a/.gitignore b/.gitignore index 9dab596..05efcea 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .idea/* .vscode/* .DS_Store +*.swp # Output of the go coverage tool, specifically when used with LiteIDE *.out @@ -14,4 +15,4 @@ todo.md dist # Converage -coverage.txt \ No newline at end of file +coverage.txt diff --git a/go.mod b/go.mod index 413ebd4..a64f62b 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.15 require ( github.com/davecgh/go-spew v1.1.1 // indirect + github.com/libsv/go-bk v0.1.3 github.com/libsv/go-bt v0.0.11 github.com/stretchr/testify v1.7.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/go.sum b/go.sum index c161a34..dfd2a3b 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9/go.mod h1:p44KuN github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/libsv/go-bk v0.1.3 h1:yhcoB9mOHReM1CeeGEPHpeQH5O2YpSHdpeSfKn6qaxs= +github.com/libsv/go-bk v0.1.3/go.mod h1:xbDkeFFpP0uyFaPLnP6TwaLpAsHaslZ0LftTdWlB6HI= github.com/libsv/go-bt v0.0.11 h1:+FXtw4hC83Kg6VEdNAqD0Pk5scwjYAzsiScHWMarcls= github.com/libsv/go-bt v0.0.11/go.mod h1:AfXoLFYEbY/TvCq/84xTce2xGjPUuC5imokHmcykF2k= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -15,11 +17,18 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 h1:sYNJzB4J8toYPQTM6pAkcmBRgw9SnQKP9oXCHfgy604= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/spvclient.go b/spvclient.go index 70a4941..586b451 100644 --- a/spvclient.go +++ b/spvclient.go @@ -32,8 +32,8 @@ func NewSPVClient(opts ...SPVOpts) (*SPVClient, error) { for _, opt := range opts { opt(cli) } - if cli.bhc == nil { + if cli.bhc == nil { return nil, errors.New("at least one blockchain header implementation should be returned") } return cli, nil -} \ No newline at end of file +} diff --git a/spvenvelope.go b/spvenvelope.go new file mode 100644 index 0000000..28a40ef --- /dev/null +++ b/spvenvelope.go @@ -0,0 +1,135 @@ +package bc + +import ( + "context" + "errors" + "time" + + "github.com/libsv/go-bk/envelope" + "github.com/libsv/go-bt" +) + +// SPVEnvelope is a struct which contains all information needed +// for a transaction to be verified. +type SPVEnvelope struct { + TxID string `json:"txid"` + RawTX string `json:"rawTx,omitempty"` + Proof *MerkleProof `json:"proof,omitempty"` + MapiResponses []envelope.JSONEnvelope `json:"mapiResponses,omitempty"` + Inputs map[string]*SPVEnvelope `json:"inputs"` +} + +type MapiResponse struct { + CallbackPayload MerkleProof `json:"callbackPayload"` + ApiVersion string `json:"apiVersion"` + Timestamp time.Time `json:"timestamp"` + MinerId string `json:"minerId"` + BlockHash string `json:"blockHash"` + BlockHeight uint64 `json:"blockHeight"` + CallbackTxID string `json:"callbackTxId"` + CallbackReason string `json:"callbackReason"` +} + +func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { + proofs := make(map[string]bool) + outputValues := make(map[string]uint64) + + tx, err := bt.NewTxFromString(payment.RawTX) + if err != nil { + return false, err + } + + if payment.Proof != nil { + return false, errors.New("root payment must be unconfirmed") + } + + for inputTxID, input := range payment.Inputs { + if input.TxID == "" { + input.TxID = inputTxID + } + valid, err := s.verifyTxs(ctx, input, tx.GetInputs(), proofs) + if err != nil { + return false, err + } + if !valid { + return valid, nil + } + } + + for _, v := range proofs { + if !v { + return false, errors.New("payment was not verified") + } + } + + outputValues[tx.GetTxID()] = tx.GetTotalOutputSatoshis() + + return true, nil +} + +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentInputs []*bt.Input, proofs map[string]bool) (bool, error) { + tx, err := bt.NewTxFromString(payment.RawTX) + if err != nil { + return false, err + } + txID := tx.GetTxID() + proofs[txID] = false + + for inputTxID, input := range payment.Inputs { + if input.TxID == "" { + input.TxID = inputTxID + } + valid, err := s.verifyTxs(ctx, input, tx.GetInputs(), proofs) + if err != nil { + return false, nil + } + if !valid { + return valid, nil + } + } + + if payment.Proof != nil { + proofTxID := payment.Proof.TxOrID + if len(proofTxID) != 64 { + proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) + if err != nil { + return false, err + } + + proofTxID = proofTx.GetTxID() + } + + if proofTxID != payment.TxID { + return false, errors.New("invalid proof supplied with payment") + } + + valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) + if err != nil { + return false, err + } + + if !valid { + return valid, nil + } + } + + var pass bool + for _, input := range parentInputs { + if input.PreviousTxID != txID { + continue + } + pass = true + + // verify input and output + output := tx.Outputs[int(input.PreviousTxOutIndex)] + _ = output + } + + if !pass { + return false, errors.New("invalid payment") + } + + proofs[txID] = true + + return true, nil +} diff --git a/spvenvelope_test.go b/spvenvelope_test.go new file mode 100644 index 0000000..45ced45 --- /dev/null +++ b/spvenvelope_test.go @@ -0,0 +1,428 @@ +package bc + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +type mockBlockHeaderClient struct { + blockHeaderFunc func(context.Context, string) (*BlockHeader, error) +} + +func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash string) (*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 *SPVEnvelope + blockHeaderFunc func(context.Context, string) (*BlockHeader, error) + exp bool + expErr error + }{ + "valid envelope passes": { + exp: true, + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", + RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd", + Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + Nodes: []string{ + "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", + "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", + "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + }, + }, + }, + }, + }, + }, + "valid envelope with merkle proof supplied as hex passes": { + exp: true, + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", + RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + Nodes: []string{ + "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", + "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", + "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + }, + }, + }, + }, + }, + }, + "invalid merkle proof fails": { + exp: false, + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", + RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Proof: &MerkleProof{ + Index: 3, // failing part, would pass if index were 1 + TxOrID: "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd", + Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + Nodes: []string{ + "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", + "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", + "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + }, + }, + }, + }, + }, + }, + "tx relying on multiple proofs passes": { + exp: true, + blockHeaderFunc: func(ctx context.Context, blockhash string) (*BlockHeader, error) { + if blockhash == "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde" { + return EncodeBlockHeaderStr("000000200adb899e30726063e84b74d439b67309497c4717825a6ba6aa575fe349750561d5b08c94d2beae4847cec09da1aea32cfd5e0f11add310eb7c6d1b427fbc09c647320161ffff7f2000000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", + RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + Inputs: map[string]*SPVEnvelope{ + "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433": { + RawTX: "02000000020e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7000000006b48304502210096373becf407ec50251aac835a9902173707688fa6dab001de9abe6acea3f98a022040f5b15ecf2e11d106878777e470e144bdb96fc567233eeb966989c958d16719412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff0e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7010000006b483045022100e0d75f4cc3d8b60ef36caa9d099975c3f3201a2e48ad1f8ac0d74d8e07a0aee40220459619b284589b53f14514b3c203b31a40d1442159c64d8e8631a68f9f74f5f841210302b1d9199e7a9357a24c98d5c22822fbaf4a1f39838bc564bd9b4384a75615a6feffffff021ecdf008000000001976a914ac0c1480344ba91deb47415153dbf7d2e4b1ccf788ac80b2e60e000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac69000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433", + Target: "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde", + Nodes: []string{ + "82e2faf3f1966eefbea0a88e77c629dfc35320e77ee053ee2071adf341cecda8", + }, + }, + }, + "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f": { + RawTX: "0200000001be304e579f89ea351c9eb351d8e29b72fb6ad71704553134e67a526b423490da010000006a47304402204b035ef4e8190ddbf6a11343ef46cdf6a35b60d18b3aec169c90463b52ab60c602205dc830ab4806c37f9875c234a8389a99f7a8b7a3b5e6cbd1e557dcf5e12df0f3412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff0200c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac1ea2e111000000001976a914ba4276fe9cca9c4d0e5bbefa6b5b7ee74a36fa6c88ac6a000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "025a356701f41c40769558a8962c765cb6b1da2bb3f7007916ad3c187215736c", + "fe4c0107b918c1366dc0485c404e7b6f92eb9499fd0036a07f9e58d3b4a992e8", + }, + }, + }, + "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa": { + RawTX: "02000000013324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c010000006b483045022100bde190f6a794aaaf14b4f1c553724883c8732c6bdcaae8b1633d52df769ffa1f02207f7cfed7183fd8515a575b070297e86a49c548977e456848f3109f342fc754ae412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff029eeffa02000000001976a914972e260dd73b41f8d91b1709005b60355cdc36ed88ac00c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac6a000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", + "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + }, + }, + }, + }, + }, + }, + "tx relying on multiple proofs with one false fails": { + exp: false, + blockHeaderFunc: func(ctx context.Context, blockhash string) (*BlockHeader, error) { + if blockhash == "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde" { + return EncodeBlockHeaderStr("000000200adb899e30726063e84b74d439b67309497c4717825a6ba6aa575fe349750561d5b08c94d2beae4847cec09da1aea32cfd5e0f11add310eb7c6d1b427fbc09c647320161ffff7f2000000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", + RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + Inputs: map[string]*SPVEnvelope{ + "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433": { + RawTX: "02000000020e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7000000006b48304502210096373becf407ec50251aac835a9902173707688fa6dab001de9abe6acea3f98a022040f5b15ecf2e11d106878777e470e144bdb96fc567233eeb966989c958d16719412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff0e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7010000006b483045022100e0d75f4cc3d8b60ef36caa9d099975c3f3201a2e48ad1f8ac0d74d8e07a0aee40220459619b284589b53f14514b3c203b31a40d1442159c64d8e8631a68f9f74f5f841210302b1d9199e7a9357a24c98d5c22822fbaf4a1f39838bc564bd9b4384a75615a6feffffff021ecdf008000000001976a914ac0c1480344ba91deb47415153dbf7d2e4b1ccf788ac80b2e60e000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac69000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433", + Target: "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde", + Nodes: []string{ + "82e2faf3f1966eefbea0a88e77c629dfc35320e77ee053ee2071adf341cecda8", + }, + }, + }, + "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f": { + RawTX: "0200000001be304e579f89ea351c9eb351d8e29b72fb6ad71704553134e67a526b423490da010000006a47304402204b035ef4e8190ddbf6a11343ef46cdf6a35b60d18b3aec169c90463b52ab60c602205dc830ab4806c37f9875c234a8389a99f7a8b7a3b5e6cbd1e557dcf5e12df0f3412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff0200c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac1ea2e111000000001976a914ba4276fe9cca9c4d0e5bbefa6b5b7ee74a36fa6c88ac6a000000", + Proof: &MerkleProof{ + Index: 1, // failing part, would pass if index were 2 + TxOrID: "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "025a356701f41c40769558a8962c765cb6b1da2bb3f7007916ad3c187215736c", + "fe4c0107b918c1366dc0485c404e7b6f92eb9499fd0036a07f9e58d3b4a992e8", + }, + }, + }, + "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa": { + RawTX: "02000000013324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c010000006b483045022100bde190f6a794aaaf14b4f1c553724883c8732c6bdcaae8b1633d52df769ffa1f02207f7cfed7183fd8515a575b070297e86a49c548977e456848f3109f342fc754ae412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff029eeffa02000000001976a914972e260dd73b41f8d91b1709005b60355cdc36ed88ac00c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac6a000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", + "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + }, + }, + }, + }, + }, + }, + "wrong tx supplied as input in envlope errs": { + exp: false, + expErr: errors.New("invalid payment"), + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "000000200adb899e30726063e84b74d439b67309497c4717825a6ba6aa575fe349750561d5b08c94d2beae4847cec09da1aea32cfd5e0f11add310eb7c6d1b427fbc09c647320161ffff7f2000000000", + RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd", + Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + Nodes: []string{ + "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", + "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", + "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + }, + }, + }, + }, + }, + }, + "wrong merkle proof suppled with otherwise correct input errors": { + exp: false, + expErr: errors.New("invalid proof supplied with payment"), + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", + RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input + Index: 1, + TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", + "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + }, + }, + }, + }, + }, + }, + "wrong merkle proof suppled via hex with otherwise correct input errors": { + exp: false, + expErr: errors.New("invalid proof supplied with payment"), + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", + RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input + Index: 1, + TxOrID: "02000000013324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c010000006b483045022100bde190f6a794aaaf14b4f1c553724883c8732c6bdcaae8b1633d52df769ffa1f02207f7cfed7183fd8515a575b070297e86a49c548977e456848f3109f342fc754ae412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff029eeffa02000000001976a914972e260dd73b41f8d91b1709005b60355cdc36ed88ac00c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac6a000000", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", + "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + }, + }, + }, + }, + }, + }, + "valid multiple layer tx passes": { + exp: true, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + switch blockHash { + case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": + return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") + case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": + return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", + RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + Inputs: map[string]*SPVEnvelope{ + "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { + TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", + RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + Inputs: map[string]*SPVEnvelope{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { + RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + Proof: &MerkleProof{ + Index: 4, + TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { + RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", + Proof: &MerkleProof{ + Index: 5, + TxOrID: "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + }, + }, + "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { + TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", + "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", + "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + }, + }, + }, + }, + }, + }, + "invalid multiple layer tx false": { + exp: false, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + switch blockHash { + case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": + return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") + case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": + return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", + RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + Inputs: map[string]*SPVEnvelope{ + "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { + TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", + RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + Inputs: map[string]*SPVEnvelope{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { + RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + Proof: &MerkleProof{ + Index: 4, + TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { + RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", + Proof: &MerkleProof{ + Index: 1, // invalid index, should be 5 + TxOrID: "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + }, + }, + "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { + TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", + "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", + "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + }, + }, + }, + }, + }, + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + s, err := NewSPVClient(WithBlockHeaderChain(&mockBlockHeaderClient{ + blockHeaderFunc: test.blockHeaderFunc, + })) + assert.NoError(t, err, "expected no error when creating spv client") + + valid, err := s.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) + }) + } +} From 6b67f5dc3cd475c53619138848105c75645075e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 14:02:54 +0100 Subject: [PATCH 02/51] added extra test and fixed linting errs --- spvenvelope.go | 8 +++--- spvenvelope_test.go | 64 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 28a40ef..1acd7f9 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -19,17 +19,19 @@ type SPVEnvelope struct { Inputs map[string]*SPVEnvelope `json:"inputs"` } +// MapiResponse is a callback from mApi type MapiResponse struct { CallbackPayload MerkleProof `json:"callbackPayload"` - ApiVersion string `json:"apiVersion"` + APIVersion string `json:"apiVersion"` Timestamp time.Time `json:"timestamp"` - MinerId string `json:"minerId"` + MinerID string `json:"minerId"` BlockHash string `json:"blockHash"` BlockHeight uint64 `json:"blockHeight"` CallbackTxID string `json:"callbackTxId"` CallbackReason string `json:"callbackReason"` } +// VerifyPayment verifieds whether or not the supplied SPVEnvelope is valid func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) outputValues := make(map[string]uint64) @@ -81,7 +83,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } valid, err := s.verifyTxs(ctx, input, tx.GetInputs(), proofs) if err != nil { - return false, nil + return false, err } if !valid { return valid, nil diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 45ced45..d61932e 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -406,6 +406,70 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "wrong merkle proof suppled with otherwise correct layered input errors": { + exp: false, + expErr: errors.New("invalid proof supplied with payment"), + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + switch blockHash { + case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": + return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") + case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": + return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", + RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + Inputs: map[string]*SPVEnvelope{ + "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { + TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", + RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + Inputs: map[string]*SPVEnvelope{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { + RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + Proof: &MerkleProof{ + Index: 4, + TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { + RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", + Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input + Index: 1, + TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", + Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Nodes: []string{ + "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", + "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + }, + }, + }, + }, + }, + "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { + TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", + "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", + "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + }, + }, + }, + }, + }, + }, } for name, test := range tests { From feb2569173b00fe401c8006c0dd30452dff90015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 14:05:12 +0100 Subject: [PATCH 03/51] fixed test linting --- spvenvelope_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spvenvelope_test.go b/spvenvelope_test.go index d61932e..c3d8e43 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -282,9 +282,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": + case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": //nolint:goconst return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") - case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": + case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": //nolint:goconst return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") } return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") From 49060c1551113ec6fd0683bd7f7fd634b75d76ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 14:12:40 +0100 Subject: [PATCH 04/51] fixed bug where no provided proof can pass. added unit test for this --- spvenvelope.go | 4 +++ spvenvelope_test.go | 71 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/spvenvelope.go b/spvenvelope.go index 1acd7f9..6376d27 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -90,6 +90,10 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } } + if (payment.Inputs == nil || len(payment.Inputs) == 0) && payment.Proof == nil { + return false, errors.New("no confirmed transaction provided") + } + if payment.Proof != nil { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { diff --git a/spvenvelope_test.go b/spvenvelope_test.go index c3d8e43..53a7d67 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -52,6 +52,22 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "envelop without any proof fails": { + exp: false, + expErr: errors.New("no confirmed transaction provided"), + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", + RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + Inputs: map[string]*SPVEnvelope{ + "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { + RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + }, + }, + }, + }, "valid envelope with merkle proof supplied as hex passes": { exp: true, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { @@ -470,6 +486,61 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "single missing merkle proof in layered and branching tx errors": { + exp: false, + expErr: errors.New("no confirmed transaction provided"), + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + switch blockHash { + case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": + return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") + case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": + return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", + RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + Inputs: map[string]*SPVEnvelope{ + "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { + TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", + RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + Inputs: map[string]*SPVEnvelope{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { + RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + Proof: &MerkleProof{ + Index: 4, + TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { + RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", + }, + }, + }, + "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { + TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", + "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", + "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + }, + }, + }, + }, + }, + }, } for name, test := range tests { From eb9ba20c8e9d4de58672d6a64feab6256424ad91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 14:51:11 +0100 Subject: [PATCH 05/51] add isroot bool to recursive function to remove duplicate code --- spvenvelope.go | 54 +++++++++++++++++++++++++++------------------ spvenvelope_test.go | 12 +++++----- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 6376d27..50acc6e 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -41,21 +41,12 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return false, err } - if payment.Proof != nil { - return false, errors.New("root payment must be unconfirmed") + valid, err := s.verifyTxs(ctx, payment, nil, true, proofs) + if err != nil { + return false, err } - - for inputTxID, input := range payment.Inputs { - if input.TxID == "" { - input.TxID = inputTxID - } - valid, err := s.verifyTxs(ctx, input, tx.GetInputs(), proofs) - if err != nil { - return false, err - } - if !valid { - return valid, nil - } + if !valid { + return valid, nil } for _, v := range proofs { @@ -69,7 +60,8 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return true, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentInputs []*bt.Input, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentInputs []*bt.Input, + isRoot bool, proofs map[string]bool) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { return false, err @@ -77,11 +69,15 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI txID := tx.GetTxID() proofs[txID] = false + if isRoot && payment.Proof != nil { + return false, errors.New("root payment must be unconfirmed") + } + for inputTxID, input := range payment.Inputs { if input.TxID == "" { input.TxID = inputTxID } - valid, err := s.verifyTxs(ctx, input, tx.GetInputs(), proofs) + valid, err := s.verifyTxs(ctx, input, tx.GetInputs(), false, proofs) if err != nil { return false, err } @@ -90,10 +86,22 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } } + // cannot verify the proof or outputs of the root tx + if isRoot { + proofs[txID] = true + return true, nil + } + + // if at the leafs of tree and transaction is unconfirmed, fail if (payment.Inputs == nil || len(payment.Inputs) == 0) && payment.Proof == nil { return false, errors.New("no confirmed transaction provided") } + parentInputsMap := make(map[string]bool) + for _, parentInput := range parentInputs { + parentInputsMap[parentInput.PreviousTxID] = true + } + if payment.Proof != nil { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { @@ -106,7 +114,11 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } if proofTxID != payment.TxID { - return false, errors.New("invalid proof supplied with payment") + return false, errors.New("input and proof id mismatch") + } + + if _, ok := parentInputsMap[proofTxID]; !ok { + return false, errors.New("proof for different tx supplied") } valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) @@ -114,9 +126,9 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI return false, err } - if !valid { - return valid, nil - } + proofs[txID] = valid + + return valid, nil } var pass bool @@ -132,7 +144,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } if !pass { - return false, errors.New("invalid payment") + return false, errors.New("could not find any inputs in tx") } proofs[txID] = true diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 53a7d67..ce3b2a2 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -218,14 +218,14 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, - "wrong tx supplied as input in envlope errs": { + "wrong tx supplied as input in envelope errs": { exp: false, - expErr: errors.New("invalid payment"), + expErr: errors.New("proof for different tx supplied"), blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "000000200adb899e30726063e84b74d439b67309497c4717825a6ba6aa575fe349750561d5b08c94d2beae4847cec09da1aea32cfd5e0f11add310eb7c6d1b427fbc09c647320161ffff7f2000000000", + TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", Inputs: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { @@ -246,7 +246,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled with otherwise correct input errors": { exp: false, - expErr: errors.New("invalid proof supplied with payment"), + expErr: errors.New("input and proof id mismatch"), blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") }, @@ -271,7 +271,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled via hex with otherwise correct input errors": { exp: false, - expErr: errors.New("invalid proof supplied with payment"), + expErr: errors.New("input and proof id mismatch"), blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") }, @@ -424,7 +424,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled with otherwise correct layered input errors": { exp: false, - expErr: errors.New("invalid proof supplied with payment"), + expErr: errors.New("input and proof id mismatch"), blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": From 777e2c79756afab453c4461d2e67c3d2952999a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 14:54:57 +0100 Subject: [PATCH 06/51] fix type in comment --- spvenvelope.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spvenvelope.go b/spvenvelope.go index 50acc6e..4da450a 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -31,7 +31,7 @@ type MapiResponse struct { CallbackReason string `json:"callbackReason"` } -// VerifyPayment verifieds whether or not the supplied SPVEnvelope is valid +// VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) outputValues := make(map[string]uint64) From 1a172c299096631e7234f1e6e03d25e98ef4c531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 28 Jul 2021 15:31:04 +0100 Subject: [PATCH 07/51] added extra test --- spvenvelope_test.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/spvenvelope_test.go b/spvenvelope_test.go index ce3b2a2..b355663 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -52,7 +52,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, - "envelop without any proof fails": { + "envelope without any proof fails": { exp: false, expErr: errors.New("no confirmed transaction provided"), blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { @@ -541,6 +541,25 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "envelope with confirmed root errs": { + exp: false, + expErr: errors.New("root payment must be unconfirmed"), + blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { + return EncodeBlockHeaderStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", + RawTX: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", + Target: "4f40da9ccedebb65ec7c29e4188ca11461668d7f2ae2e4e35b59b0fe4d266406", + Nodes: []string{ + "00a43044caef87323a3ddee74dc7917e1dfd2371e9c43f208040cfe3737ee5ec", + }, + }, + }, + }, } for name, test := range tests { From 0f446290b75646657fe6a84b63c76733e8801e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 29 Jul 2021 10:12:38 +0100 Subject: [PATCH 08/51] tidy go.mod --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index a64f62b..a17c1bf 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/libsv/go-bc go 1.15 require ( - github.com/davecgh/go-spew v1.1.1 // indirect github.com/libsv/go-bk v0.1.3 github.com/libsv/go-bt v0.0.11 github.com/stretchr/testify v1.7.0 From 5d9a73ae993286f325e4e3b7e08f51c86e6aca57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Mon, 2 Aug 2021 13:48:28 +0100 Subject: [PATCH 09/51] added named errors --- spvenvelope.go | 41 +++++++++++++++++++++++++++-------------- spvenvelope_test.go | 14 +++++++------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 4da450a..b06a65e 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -9,6 +9,15 @@ import ( "github.com/libsv/go-bt" ) +var ( + ErrPaymentNotVerified = errors.New("a tx was missed during validation") + ErrRootPaymentConfirmed = errors.New("root payment must be unconfirmed") + ErrNoConfirmedTransaction = errors.New("not confirmed tx(s) provided") + ErrTxIDMismatch = errors.New("input and proof ID mismatch") + ErrProofTxMismatch = errors.New("proof tx id does not match input tx id") + ErrTxNotInInputs = errors.New("could not find tx in child inputs") +) + // SPVEnvelope is a struct which contains all information needed // for a transaction to be verified. type SPVEnvelope struct { @@ -51,7 +60,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo for _, v := range proofs { if !v { - return false, errors.New("payment was not verified") + return false, ErrPaymentNotVerified } } @@ -60,7 +69,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return true, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentInputs []*bt.Input, +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childInputs []*bt.Input, isRoot bool, proofs map[string]bool) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { @@ -70,7 +79,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI proofs[txID] = false if isRoot && payment.Proof != nil { - return false, errors.New("root payment must be unconfirmed") + return false, ErrRootPaymentConfirmed } for inputTxID, input := range payment.Inputs { @@ -94,14 +103,10 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI // if at the leafs of tree and transaction is unconfirmed, fail if (payment.Inputs == nil || len(payment.Inputs) == 0) && payment.Proof == nil { - return false, errors.New("no confirmed transaction provided") - } - - parentInputsMap := make(map[string]bool) - for _, parentInput := range parentInputs { - parentInputsMap[parentInput.PreviousTxID] = true + return false, ErrNoConfirmedTransaction } + //childTxInputMap := make(map[string]bool) if payment.Proof != nil { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { @@ -114,11 +119,19 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } if proofTxID != payment.TxID { - return false, errors.New("input and proof id mismatch") + return false, ErrTxIDMismatch + } + + var proofPresent bool + for _, childInput := range childInputs { + if childInput.PreviousTxID == proofTxID { + proofPresent = true + break + } } - if _, ok := parentInputsMap[proofTxID]; !ok { - return false, errors.New("proof for different tx supplied") + if !proofPresent { + return false, ErrProofTxMismatch } valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) @@ -132,7 +145,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } var pass bool - for _, input := range parentInputs { + for _, input := range childInputs { if input.PreviousTxID != txID { continue } @@ -144,7 +157,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, parentI } if !pass { - return false, errors.New("could not find any inputs in tx") + return false, ErrTxNotInInputs } proofs[txID] = true diff --git a/spvenvelope_test.go b/spvenvelope_test.go index b355663..72cca46 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -54,7 +54,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "envelope without any proof fails": { exp: false, - expErr: errors.New("no confirmed transaction provided"), + expErr: ErrNoConfirmedTransaction, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") }, @@ -220,7 +220,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong tx supplied as input in envelope errs": { exp: false, - expErr: errors.New("proof for different tx supplied"), + expErr: ErrProofTxMismatch, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") }, @@ -246,7 +246,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled with otherwise correct input errors": { exp: false, - expErr: errors.New("input and proof id mismatch"), + expErr: ErrTxIDMismatch, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") }, @@ -271,7 +271,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled via hex with otherwise correct input errors": { exp: false, - expErr: errors.New("input and proof id mismatch"), + expErr: ErrTxIDMismatch, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") }, @@ -424,7 +424,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled with otherwise correct layered input errors": { exp: false, - expErr: errors.New("input and proof id mismatch"), + expErr: ErrTxIDMismatch, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": @@ -488,7 +488,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "single missing merkle proof in layered and branching tx errors": { exp: false, - expErr: errors.New("no confirmed transaction provided"), + expErr: ErrNoConfirmedTransaction, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": @@ -543,7 +543,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "envelope with confirmed root errs": { exp: false, - expErr: errors.New("root payment must be unconfirmed"), + expErr: ErrRootPaymentConfirmed, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") }, From 1a51a039d0074e23e3c1c3a5cfe3e267418d1706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 3 Aug 2021 10:02:03 +0100 Subject: [PATCH 10/51] fixed linting --- spvenvelope.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index b06a65e..b65c22f 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -10,12 +10,25 @@ import ( ) var ( - ErrPaymentNotVerified = errors.New("a tx was missed during validation") - ErrRootPaymentConfirmed = errors.New("root payment must be unconfirmed") + // ErrPaymentNotVerified returns if a transaction in the tree provided was missed during verification + ErrPaymentNotVerified = errors.New("a tx was missed during validation") + + // ErrRootPaymentConfirmed returns if the root payment is already confirmed + ErrRootPaymentConfirmed = errors.New("root payment must be unconfirmed") + + // ErrNoConfirmedTransaction returns if a path from root to leaf contains no confirmed transcation ErrNoConfirmedTransaction = errors.New("not confirmed tx(s) provided") - ErrTxIDMismatch = errors.New("input and proof ID mismatch") - ErrProofTxMismatch = errors.New("proof tx id does not match input tx id") - ErrTxNotInInputs = errors.New("could not find tx in child inputs") + + // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID + ErrTxIDMismatch = errors.New("input and proof ID mismatch") + + // ErrProofTxMismatch returns if a proof (valid or not) is supplied for a transaction, but this proof + //is for a transaction other than the one it was bundled with + ErrProofTxMismatch = errors.New("proof tx id does not match input tx id") + + // ErrTxNotInInputs returns if the tx.Outputs of a transaction supplied in the SPV envelope cannot be + // matched to any of its child transactions tx.Inputs + ErrTxNotInInputs = errors.New("could not find tx in child inputs") ) // SPVEnvelope is a struct which contains all information needed From 0c5440af0c238a128ff86504fc069e4c3135df47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 3 Aug 2021 10:10:20 +0100 Subject: [PATCH 11/51] add tsc spec to comment --- spvenvelope.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index b65c22f..60ebd3f 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -31,8 +31,9 @@ var ( ErrTxNotInInputs = errors.New("could not find tx in child inputs") ) -// SPVEnvelope is a struct which contains all information needed -// for a transaction to be verified. +// SPVEnvelope is a struct which contains all information needed for a transaction to be verified. +// +// spec at https://tsc.bitcoinassociation.net/standards/spv-envelope/ type SPVEnvelope struct { TxID string `json:"txid"` RawTX string `json:"rawTx,omitempty"` From 9affc7b10e202397ed2d78c145dde97210eae72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 3 Aug 2021 10:28:46 +0100 Subject: [PATCH 12/51] added pr feedback --- spvenvelope.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 60ebd3f..3e61c3e 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -57,12 +57,6 @@ type MapiResponse struct { // VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) - outputValues := make(map[string]uint64) - - tx, err := bt.NewTxFromString(payment.RawTX) - if err != nil { - return false, err - } valid, err := s.verifyTxs(ctx, payment, nil, true, proofs) if err != nil { @@ -78,8 +72,6 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo } } - outputValues[tx.GetTxID()] = tx.GetTotalOutputSatoshis() - return true, nil } @@ -120,7 +112,6 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childIn return false, ErrNoConfirmedTransaction } - //childTxInputMap := make(map[string]bool) if payment.Proof != nil { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { From c43f21dfdc355fdfa690958f0cd936b5a2fbd2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 6 Aug 2021 13:55:57 +0100 Subject: [PATCH 13/51] use minercraft call for mapi response struct --- go.mod | 5 ++- go.sum | 86 ++++++++++++++++++++++++++++++++++++++++++++++---- spvenvelope.go | 17 ++-------- 3 files changed, 84 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index a17c1bf..1fa4dc4 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,7 @@ module github.com/libsv/go-bc go 1.15 require ( - github.com/libsv/go-bk v0.1.3 - github.com/libsv/go-bt v0.0.11 + github.com/libsv/go-bt v1.0.0-beta github.com/stretchr/testify v1.7.0 - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + github.com/tonicpow/go-minercraft v0.2.11 ) diff --git a/go.sum b/go.sum index dfd2a3b..30c6c55 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,110 @@ +github.com/DataDog/datadog-go v3.7.1+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/afex/hystrix-go v0.0.0-20180209013831-27fae8d30f1a/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/bitcoinschema/go-bitcoin v0.3.17 h1:zyByOoInoqTxypToiND4xmx8itGcU801m9xrJ5nYd9I= +github.com/bitcoinschema/go-bitcoin v0.3.17/go.mod h1:3XL+F4hXuiJjpdIn/KpruivmfyRDOfexsx3coXexymg= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173 h1:2yTIV9u7H0BhRDGXH5xrAwAz7XibWJtX2dNezMeNsUo= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173/go.mod h1:BZ1UcC9+tmcDEcdVXgpt13hMczwJxWzpAn68wNs7zRA= +github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e h1:6f+gRvaPE/4h0g39dqTNPr9/P4mikw0aB+dhiExaWN8= +github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e/go.mod h1:WPrWor6cSeuGQZ15qPe+jqFmblJEFrJHYfr5cD7cmyk= github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9 h1:hFI8rT84FCA0FFy3cFrkW5Nz4FyNKlIdCvEvvTNySKg= github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9/go.mod h1:p44KuNKUH5BC8uX4ONEODaHUR4+ibC8todEAOGQEJAM= +github.com/cactus/go-statsd-client/statsd v0.0.0-20200423205355-cb0885a1018c/go.mod h1:l/bIBLeOl9eX+wxJAzxS4TveKRtAqlyDpHjhkfO0MEI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/libsv/go-bk v0.1.3 h1:yhcoB9mOHReM1CeeGEPHpeQH5O2YpSHdpeSfKn6qaxs= -github.com/libsv/go-bk v0.1.3/go.mod h1:xbDkeFFpP0uyFaPLnP6TwaLpAsHaslZ0LftTdWlB6HI= -github.com/libsv/go-bt v0.0.11 h1:+FXtw4hC83Kg6VEdNAqD0Pk5scwjYAzsiScHWMarcls= -github.com/libsv/go-bt v0.0.11/go.mod h1:AfXoLFYEbY/TvCq/84xTce2xGjPUuC5imokHmcykF2k= +github.com/gojektech/heimdall/v6 v6.1.0 h1:M9L1xryMKGWUlAA33D0r0BaKiXWzvuReltDPPkC5loM= +github.com/gojektech/heimdall/v6 v6.1.0/go.mod h1:8g/ohsh0GXn8fzOf+qVrjX5pQLf7qQy8vEBjBUJ/9L4= +github.com/gojektech/valkyrie v0.0.0-20180215180059-6aee720afcdf/go.mod h1:tDYRk1s5Pms6XJjj5m2PxAzmQvaDU8GqDf1u6x7yxKw= +github.com/gojektech/valkyrie v0.0.0-20190210220504-8f62c1e7ba45 h1:MO2DsGCZz8phRhLnpFvHEQgTH521sVN/6F2GZTbNO3Q= +github.com/gojektech/valkyrie v0.0.0-20190210220504-8f62c1e7ba45/go.mod h1:tDYRk1s5Pms6XJjj5m2PxAzmQvaDU8GqDf1u6x7yxKw= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libsv/go-bt v1.0.0-beta h1:Sh/ACr0y/uTI41qS+3yo9jMl5VUDIa+euWdk33c4OJg= +github.com/libsv/go-bt v1.0.0-beta/go.mod h1:AfXoLFYEbY/TvCq/84xTce2xGjPUuC5imokHmcykF2k= +github.com/mattn/goveralls v0.0.6/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tonicpow/go-minercraft v0.2.11 h1:UuKdjojwz+7Z0ppFATSA6fMRtDX29rp9qjL6MqdzQzA= +github.com/tonicpow/go-minercraft v0.2.11/go.mod h1:eyGNUs6iyGTKgdXp0yWXQUfBBxIRqnfzM+jMb2eeyog= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 h1:sYNJzB4J8toYPQTM6pAkcmBRgw9SnQKP9oXCHfgy604= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200530233709-52effbd89c51/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/spvenvelope.go b/spvenvelope.go index 3e61c3e..d2013ae 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -3,10 +3,9 @@ package bc import ( "context" "errors" - "time" - "github.com/libsv/go-bk/envelope" "github.com/libsv/go-bt" + "github.com/tonicpow/go-minercraft" ) var ( @@ -38,22 +37,10 @@ type SPVEnvelope struct { TxID string `json:"txid"` RawTX string `json:"rawTx,omitempty"` Proof *MerkleProof `json:"proof,omitempty"` - MapiResponses []envelope.JSONEnvelope `json:"mapiResponses,omitempty"` + MapiResponses []minercraft.Callback `json:"mapiResponses,omitempty"` Inputs map[string]*SPVEnvelope `json:"inputs"` } -// MapiResponse is a callback from mApi -type MapiResponse struct { - CallbackPayload MerkleProof `json:"callbackPayload"` - APIVersion string `json:"apiVersion"` - Timestamp time.Time `json:"timestamp"` - MinerID string `json:"minerId"` - BlockHash string `json:"blockHash"` - BlockHeight uint64 `json:"blockHeight"` - CallbackTxID string `json:"callbackTxId"` - CallbackReason string `json:"callbackReason"` -} - // VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) From 395b536adc470271e5e63b2da88a4faf91f97144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 10 Aug 2021 14:30:32 +0100 Subject: [PATCH 14/51] Implemented PR feedback around function simplicity and comment clarity --- spvenvelope.go | 100 +++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index d2013ae..79dc3b4 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -53,6 +53,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return valid, nil } + // Check the proofs map for safety, in case any tx was skipped during verification for _, v := range proofs { if !v { return false, ErrPaymentNotVerified @@ -62,7 +63,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return true, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childInputs []*bt.Input, +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTxInputs []*bt.Input, isRoot bool, proofs map[string]bool) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { @@ -71,10 +72,14 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childIn txID := tx.GetTxID() proofs[txID] = false + // The root tx is the transaction we're trying to verify, and it should not have a supplied + // merkle proof. if isRoot && payment.Proof != nil { return false, ErrRootPaymentConfirmed } + // Recurse to the leaves of the tree and verify upward towards the root. This way, we + // check any merkle proofs provided first. for inputTxID, input := range payment.Inputs { if input.TxID == "" { input.TxID = inputTxID @@ -88,71 +93,94 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childIn } } - // cannot verify the proof or outputs of the root tx + // Given that the root of the SPVEnvelope is the tx we're trying to prove as legitimate, + // it will not come with a proof (or any outputs) to verify. + // + // As well as this, for this condition to be true, every previous merkle proof or + // tx verification will have passed. So, we can safely assume success and return true. if isRoot { proofs[txID] = true return true, nil } - // if at the leafs of tree and transaction is unconfirmed, fail + // If at the leafs of tree and transaction is unconfirmed, fail if (payment.Inputs == nil || len(payment.Inputs) == 0) && payment.Proof == nil { return false, ErrNoConfirmedTransaction } + // If a merkle proof is provided, assume we are at the a leaf of the tree. + // Verify and return the result. if payment.Proof != nil { - proofTxID := payment.Proof.TxOrID - if len(proofTxID) != 64 { - proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) - if err != nil { - return false, err - } - - proofTxID = proofTx.GetTxID() - } + return s.verifyLeafTx(ctx, payment, childTxInputs, proofs) + } - if proofTxID != payment.TxID { - return false, ErrTxIDMismatch - } + // If no merkle proof is provided, use the locking and unlocking scripts of this + // and the child tx to verify legitimacy. + return s.verifyUnconfirmedTx(ctx, txID, tx, childTxInputs, proofs) +} - var proofPresent bool - for _, childInput := range childInputs { - if childInput.PreviousTxID == proofTxID { - proofPresent = true - break - } +func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, childTxInputs []*bt.Input, + proofs map[string]bool) (bool, error) { + proofTxID := payment.Proof.TxOrID + if len(proofTxID) != 64 { + proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) + if err != nil { + return false, err } - if !proofPresent { - return false, ErrProofTxMismatch - } + proofTxID = proofTx.GetTxID() + } - valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) - if err != nil { - return false, err + // If the tx id of the merkle proof doesn't match the tx id provided in the SPVEnvelope, + // fail and error + if proofTxID != payment.TxID { + return false, ErrTxIDMismatch + } + + // If the tx id of the merkle proof doesn't match any of the tx inputs of the child tx, + // fail and error + var proofPresent bool + for _, cTxInput := range childTxInputs { + if cTxInput.PreviousTxID == proofTxID { + proofPresent = true + break } + } - proofs[txID] = valid + if !proofPresent { + return false, ErrProofTxMismatch + } - return valid, nil + valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) + if err != nil { + return false, err } + proofs[payment.TxID] = valid + + return valid, nil +} + +func (s *SPVClient) verifyUnconfirmedTx(ctx context.Context, txID string, tx *bt.Tx, childTxInputs []*bt.Input, + proofs map[string]bool) (bool, error) { + // If current tx id is not found any tx input of the child tx, fail and error var pass bool - for _, input := range childInputs { - if input.PreviousTxID != txID { + for _, cTxInput := range childTxInputs { + if cTxInput.PreviousTxID != txID { continue } pass = true - // verify input and output - output := tx.Outputs[int(input.PreviousTxOutIndex)] + // TODO: verify child tx input's unlocking script with current tx output's locking script + output := tx.Outputs[int(cTxInput.PreviousTxOutIndex)] _ = output } if !pass { - return false, ErrTxNotInInputs + return pass, ErrTxNotInInputs } - proofs[txID] = true + proofs[txID] = pass - return true, nil + return pass, nil } From 7967033b45d6172d3a85e7fde458f0658bfd63c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 10 Aug 2021 14:32:57 +0100 Subject: [PATCH 15/51] fixed linting error --- spvenvelope.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 79dc3b4..ebc2310 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -116,7 +116,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx // If no merkle proof is provided, use the locking and unlocking scripts of this // and the child tx to verify legitimacy. - return s.verifyUnconfirmedTx(ctx, txID, tx, childTxInputs, proofs) + return s.verifyUnconfirmedTx(txID, tx, childTxInputs, proofs) } func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, childTxInputs []*bt.Input, @@ -161,7 +161,7 @@ func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, chil return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(ctx context.Context, txID string, tx *bt.Tx, childTxInputs []*bt.Input, +func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInputs []*bt.Input, proofs map[string]bool) (bool, error) { // If current tx id is not found any tx input of the child tx, fail and error var pass bool From 7f062205f5c6e5844228ec38a167f0dc97255b4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 10 Aug 2021 14:52:20 +0100 Subject: [PATCH 16/51] fix typo in comment --- spvenvelope.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spvenvelope.go b/spvenvelope.go index ebc2310..f3ebf74 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -103,7 +103,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return true, nil } - // If at the leafs of tree and transaction is unconfirmed, fail + // If at the leaves of the tree and transaction is unconfirmed, fail and error. if (payment.Inputs == nil || len(payment.Inputs) == 0) && payment.Proof == nil { return false, ErrNoConfirmedTransaction } From 71d6951ddb11ad3a4339b4342b1383187cd95449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 11:50:15 +0100 Subject: [PATCH 17/51] simplify code complexity, the child tx input is now fetched only once --- spvenvelope.go | 69 ++++++++++++++++++--------------------------- spvenvelope_test.go | 2 +- 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index f3ebf74..566cb22 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -21,10 +21,6 @@ var ( // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID ErrTxIDMismatch = errors.New("input and proof ID mismatch") - // ErrProofTxMismatch returns if a proof (valid or not) is supplied for a transaction, but this proof - //is for a transaction other than the one it was bundled with - ErrProofTxMismatch = errors.New("proof tx id does not match input tx id") - // ErrTxNotInInputs returns if the tx.Outputs of a transaction supplied in the SPV envelope cannot be // matched to any of its child transactions tx.Inputs ErrTxNotInInputs = errors.New("could not find tx in child inputs") @@ -108,19 +104,37 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return false, ErrNoConfirmedTransaction } + // Retrieve the index of the linked child tx input to prevent having to search the the inputs + // slice multiple times later + inputIdx, err := s.childTxInputIdx(txID, childTxInputs) + if err != nil { + return false, err + } + // If a merkle proof is provided, assume we are at the a leaf of the tree. // Verify and return the result. if payment.Proof != nil { - return s.verifyLeafTx(ctx, payment, childTxInputs, proofs) + return s.verifyLeafTx(ctx, payment, proofs) } // If no merkle proof is provided, use the locking and unlocking scripts of this // and the child tx to verify legitimacy. - return s.verifyUnconfirmedTx(txID, tx, childTxInputs, proofs) + return s.verifyUnconfirmedTx(txID, tx, childTxInputs[inputIdx], proofs) } -func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, childTxInputs []*bt.Input, - proofs map[string]bool) (bool, error) { +func (s *SPVClient) childTxInputIdx(txID string, childTxInputs []*bt.Input) (int, error) { + // Search through the child tx's inputs, and when a tx id match is found, return its index. + for i, cTxInput := range childTxInputs { + if cTxInput.PreviousTxID == txID { + return i, nil + } + } + + // Otherwise, fail and error + return 0, ErrTxNotInInputs +} + +func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) @@ -137,20 +151,6 @@ func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, chil return false, ErrTxIDMismatch } - // If the tx id of the merkle proof doesn't match any of the tx inputs of the child tx, - // fail and error - var proofPresent bool - for _, cTxInput := range childTxInputs { - if cTxInput.PreviousTxID == proofTxID { - proofPresent = true - break - } - } - - if !proofPresent { - return false, ErrProofTxMismatch - } - valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) if err != nil { return false, err @@ -161,26 +161,13 @@ func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, chil return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInputs []*bt.Input, +func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInput *bt.Input, proofs map[string]bool) (bool, error) { - // If current tx id is not found any tx input of the child tx, fail and error - var pass bool - for _, cTxInput := range childTxInputs { - if cTxInput.PreviousTxID != txID { - continue - } - pass = true + // TODO: verify child tx input's unlocking script with current tx output's locking script + output := tx.Outputs[int(childTxInput.PreviousTxOutIndex)] + _ = output - // TODO: verify child tx input's unlocking script with current tx output's locking script - output := tx.Outputs[int(cTxInput.PreviousTxOutIndex)] - _ = output - } - - if !pass { - return pass, ErrTxNotInInputs - } + proofs[txID] = true - proofs[txID] = pass - - return pass, nil + return true, nil } diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 72cca46..4e5dfb6 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -220,7 +220,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong tx supplied as input in envelope errs": { exp: false, - expErr: ErrProofTxMismatch, + expErr: ErrTxNotInInputs, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") }, From 66cd92d795a06a51f76e81d12ef19a5d5fccaea8 Mon Sep 17 00:00:00 2001 From: Jad Wahab Date: Wed, 11 Aug 2021 12:29:28 +0100 Subject: [PATCH 18/51] refactor! for clarity (use parents/anchors/tips) --- spvenvelope.go | 61 ++++++++++++++++++++++++--------------------- spvenvelope_test.go | 36 +++++++++++++------------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 566cb22..55fc564 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -12,17 +12,17 @@ var ( // ErrPaymentNotVerified returns if a transaction in the tree provided was missed during verification ErrPaymentNotVerified = errors.New("a tx was missed during validation") - // ErrRootPaymentConfirmed returns if the root payment is already confirmed - ErrRootPaymentConfirmed = errors.New("root payment must be unconfirmed") + // ErrTipTxConfirmed returns if the tip transaction is already confirmed + ErrTipTxConfirmed = errors.New("tip transaction must be unconfirmed") - // ErrNoConfirmedTransaction returns if a path from root to leaf contains no confirmed transcation - ErrNoConfirmedTransaction = errors.New("not confirmed tx(s) provided") + // ErrNoConfirmedTransaction returns if a path from tip to beginning/anchor contains no confirmed transcation + ErrNoConfirmedTransaction = errors.New("not confirmed/anchored tx(s) provided") // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID ErrTxIDMismatch = errors.New("input and proof ID mismatch") // ErrTxNotInInputs returns if the tx.Outputs of a transaction supplied in the SPV envelope cannot be - // matched to any of its child transactions tx.Inputs + // matched to any of its child transactions tx.Inputs (no link found) ErrTxNotInInputs = errors.New("could not find tx in child inputs") ) @@ -34,7 +34,7 @@ type SPVEnvelope struct { RawTX string `json:"rawTx,omitempty"` Proof *MerkleProof `json:"proof,omitempty"` MapiResponses []minercraft.Callback `json:"mapiResponses,omitempty"` - Inputs map[string]*SPVEnvelope `json:"inputs"` + Parents map[string]*SPVEnvelope `json:"parents"` } // VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid @@ -49,6 +49,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return valid, nil } + // TODO: check if still needed // Check the proofs map for safety, in case any tx was skipped during verification for _, v := range proofs { if !v { @@ -60,7 +61,8 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo } func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTxInputs []*bt.Input, - isRoot bool, proofs map[string]bool) (bool, error) { + isTip bool, proofs map[string]bool) (bool, error) { + tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { return false, err @@ -68,19 +70,20 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx txID := tx.GetTxID() proofs[txID] = false - // The root tx is the transaction we're trying to verify, and it should not have a supplied - // merkle proof. - if isRoot && payment.Proof != nil { - return false, ErrRootPaymentConfirmed + // The tip tx is the transaction we're trying to verify, and it should not have a supplied + // Merkle Proof. + if isTip && payment.Proof != nil { + return false, ErrTipTxConfirmed } - // Recurse to the leaves of the tree and verify upward towards the root. This way, we - // check any merkle proofs provided first. - for inputTxID, input := range payment.Inputs { - if input.TxID == "" { - input.TxID = inputTxID + // 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 := s.verifyTxs(ctx, input, tx.GetInputs(), false, proofs) + valid, err := s.verifyTxs(ctx, parent, tx.GetInputs(), false, proofs) if err != nil { return false, err } @@ -89,18 +92,18 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx } } - // Given that the root of the SPVEnvelope is the tx we're trying to prove as legitimate, - // it will not come with a proof (or any outputs) to verify. + // Given that the tip transaction of the SPVEnvelope is the tx we're trying to prove as + // legitimate, it will not come with a Merkle Proof (or any output links) to verify. // - // As well as this, for this condition to be true, every previous merkle proof or + // As well as this, for this condition to be true, every previous Merkle Proof or // tx verification will have passed. So, we can safely assume success and return true. - if isRoot { + if isTip { proofs[txID] = true return true, nil } - // If at the leaves of the tree and transaction is unconfirmed, fail and error. - if (payment.Inputs == nil || len(payment.Inputs) == 0) && payment.Proof == nil { + // If at the beginning of the tx chain and tx is unconfirmed, fail and error. + if (payment.Parents == nil || len(payment.Parents) == 0) && payment.Proof == nil { return false, ErrNoConfirmedTransaction } @@ -111,14 +114,14 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return false, err } - // If a merkle proof is provided, assume we are at the a leaf of the tree. + // If a Merkle Proof is provided, assume we are at the anchor/beginning of the tx chain. // Verify and return the result. if payment.Proof != nil { - return s.verifyLeafTx(ctx, payment, proofs) + return s.verifyAnchorTx(ctx, payment, proofs) } - // If no merkle proof is provided, use the locking and unlocking scripts of this - // and the child tx to verify legitimacy. + // If no Merkle Proof is provided, we must verify the unconfirmed tx or else we can not + // know if any of it's child txs are valid. return s.verifyUnconfirmedTx(txID, tx, childTxInputs[inputIdx], proofs) } @@ -134,7 +137,7 @@ func (s *SPVClient) childTxInputIdx(txID string, childTxInputs []*bt.Input) (int return 0, ErrTxNotInInputs } -func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) @@ -145,7 +148,7 @@ func (s *SPVClient) verifyLeafTx(ctx context.Context, payment *SPVEnvelope, proo proofTxID = proofTx.GetTxID() } - // If the tx id of the merkle proof doesn't match the tx id provided in the SPVEnvelope, + // If the txid of the Merkle Proof doesn't match the txid provided in the SPVEnvelope, // fail and error if proofTxID != payment.TxID { return false, ErrTxIDMismatch diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 4e5dfb6..19dcacb 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -35,7 +35,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", Proof: &MerkleProof{ @@ -61,7 +61,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", }, @@ -76,7 +76,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", Proof: &MerkleProof{ @@ -101,7 +101,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", Proof: &MerkleProof{ @@ -129,7 +129,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433": { RawTX: "02000000020e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7000000006b48304502210096373becf407ec50251aac835a9902173707688fa6dab001de9abe6acea3f98a022040f5b15ecf2e11d106878777e470e144bdb96fc567233eeb966989c958d16719412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff0e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7010000006b483045022100e0d75f4cc3d8b60ef36caa9d099975c3f3201a2e48ad1f8ac0d74d8e07a0aee40220459619b284589b53f14514b3c203b31a40d1442159c64d8e8631a68f9f74f5f841210302b1d9199e7a9357a24c98d5c22822fbaf4a1f39838bc564bd9b4384a75615a6feffffff021ecdf008000000001976a914ac0c1480344ba91deb47415153dbf7d2e4b1ccf788ac80b2e60e000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac69000000", Proof: &MerkleProof{ @@ -179,7 +179,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433": { RawTX: "02000000020e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7000000006b48304502210096373becf407ec50251aac835a9902173707688fa6dab001de9abe6acea3f98a022040f5b15ecf2e11d106878777e470e144bdb96fc567233eeb966989c958d16719412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff0e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7010000006b483045022100e0d75f4cc3d8b60ef36caa9d099975c3f3201a2e48ad1f8ac0d74d8e07a0aee40220459619b284589b53f14514b3c203b31a40d1442159c64d8e8631a68f9f74f5f841210302b1d9199e7a9357a24c98d5c22822fbaf4a1f39838bc564bd9b4384a75615a6feffffff021ecdf008000000001976a914ac0c1480344ba91deb47415153dbf7d2e4b1ccf788ac80b2e60e000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac69000000", Proof: &MerkleProof{ @@ -227,7 +227,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", Proof: &MerkleProof{ @@ -253,7 +253,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input @@ -278,7 +278,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input @@ -308,11 +308,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", Proof: &MerkleProof{ @@ -372,11 +372,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", Proof: &MerkleProof{ @@ -437,11 +437,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", Proof: &MerkleProof{ @@ -501,11 +501,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { envelope: &SPVEnvelope{ TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", - Inputs: map[string]*SPVEnvelope{ + Parents: map[string]*SPVEnvelope{ "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", Proof: &MerkleProof{ @@ -543,7 +543,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "envelope with confirmed root errs": { exp: false, - expErr: ErrRootPaymentConfirmed, + expErr: ErrTipTxConfirmed, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") }, From d058a55780bdcaab472a8f1a3dfa6fe3e3ee4db0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 12:31:27 +0100 Subject: [PATCH 19/51] verify all inputs are present in parent envelope --- spvenvelope.go | 22 +++++++++++++++++++ spvenvelope_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/spvenvelope.go b/spvenvelope.go index 566cb22..da33246 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -21,6 +21,10 @@ var ( // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID ErrTxIDMismatch = errors.New("input and proof ID mismatch") + // NotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not + // present in the parent envelope + ErrNotAllInputsSupplied = errors.New("a tx input missing in parent envelope") + // ErrTxNotInInputs returns if the tx.Outputs of a transaction supplied in the SPV envelope cannot be // matched to any of its child transactions tx.Inputs ErrTxNotInInputs = errors.New("could not find tx in child inputs") @@ -117,11 +121,29 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return s.verifyLeafTx(ctx, payment, proofs) } + // Ensure that every input current present with the current tx is present in the envelope + // as a parent + if ok := s.verifyAllTxInputsPresent(payment, tx); !ok { + return false, ErrNotAllInputsSupplied + } + // If no merkle proof is provided, use the locking and unlocking scripts of this // and the child tx to verify legitimacy. return s.verifyUnconfirmedTx(txID, tx, childTxInputs[inputIdx], proofs) } +func (S *SPVClient) verifyAllTxInputsPresent(payment *SPVEnvelope, tx *bt.Tx) bool { + // If an unconfirmed tx has an input which is not present in the spv envelope, we + // should fail and error, as we cannot prove the legitimacy of those inputs. + for _, txInput := range tx.Inputs { + if _, ok := payment.Inputs[txInput.PreviousTxID]; !ok { + return false + } + } + + return true +} + func (s *SPVClient) childTxInputIdx(txID string, childTxInputs []*bt.Input) (int, error) { // Search through the child tx's inputs, and when a tx id match is found, return its index. for i, cTxInput := range childTxInputs { diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 4e5dfb6..e44dee6 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -422,6 +422,58 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "tx with input missing from envelope parents errors": { + exp: false, + expErr: ErrNotAllInputsSupplied, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + switch blockHash { + case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": //nolint:goconst + return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") + case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": //nolint:goconst + return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + } + return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", + RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + Inputs: map[string]*SPVEnvelope{ + "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { + TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", + RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + Inputs: map[string]*SPVEnvelope{ + "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { + RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + Proof: &MerkleProof{ + Index: 4, + TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", + "*", + "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + }, + }, + }, + }, + }, + "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { + TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", + Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Nodes: []string{ + "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", + "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", + "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + }, + }, + }, + }, + }, + }, "wrong merkle proof suppled with otherwise correct layered input errors": { exp: false, expErr: ErrTxIDMismatch, From 5b75c0945ba86da0cdab202cde6c143b9f751908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 18:16:14 +0100 Subject: [PATCH 20/51] fixed bug with script vaidation --- spvenvelope.go | 81 +++-- spvenvelope_test.go | 836 +++++++++++++++++++++++++++----------------- 2 files changed, 551 insertions(+), 366 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 6c514c5..e002401 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -24,10 +24,6 @@ var ( // NotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not // present in the parent envelope ErrNotAllInputsSupplied = errors.New("a tx input missing in parent envelope") - - // ErrTxNotInInputs returns if the tx.Outputs of a transaction supplied in the SPV envelope cannot be - // matched to any of its child transactions tx.Inputs (no link found) - ErrTxNotInInputs = errors.New("could not find tx in child inputs") ) // SPVEnvelope is a struct which contains all information needed for a transaction to be verified. @@ -80,6 +76,16 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return false, ErrTipTxConfirmed } + // If at the beginning of the tx chain and tx is unconfirmed, fail and error. + if (payment.Parents == nil || len(payment.Parents) == 0) && payment.Proof == nil { + return false, ErrNoConfirmedTransaction + } + + m, err := s.buildInputPaymentMap(tx, payment) + if err != nil { + return false, err + } + // 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. @@ -87,7 +93,8 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx if parent.TxID == "" { parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent, tx.GetInputs(), false, proofs) + + valid, err := s.verifyTxs(ctx, parent, m[parentTxID], false, proofs) if err != nil { return false, err } @@ -106,57 +113,52 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return true, nil } - // If at the beginning of the tx chain and tx is unconfirmed, fail and error. - if (payment.Parents == nil || len(payment.Parents) == 0) && payment.Proof == nil { - return false, ErrNoConfirmedTransaction - } - - // Retrieve the index of the linked child tx input to prevent having to search the the inputs - // slice multiple times later - inputIdx, err := s.childTxInputIdx(txID, childTxInputs) - if err != nil { - return false, err - } - // If a Merkle Proof is provided, assume we are at the anchor/beginning of the tx chain. // Verify and return the result. if payment.Proof != nil { return s.verifyAnchorTx(ctx, payment, proofs) } - // Ensure that every input current present with the current tx is present in the envelope - // as a parent - if ok := s.verifyAllTxInputsPresent(payment, tx); !ok { - return false, ErrNotAllInputsSupplied - } - // If no Merkle Proof is provided, we must verify the unconfirmed tx or else we can not // know if any of it's child txs are valid. - return s.verifyUnconfirmedTx(txID, tx, childTxInputs[inputIdx], proofs) + return s.verifyUnconfirmedTx(txID, tx, childTxInputs, proofs) } -func (S *SPVClient) verifyAllTxInputsPresent(payment *SPVEnvelope, tx *bt.Tx) bool { +func (s *SPVClient) buildInputPaymentMap(tx *bt.Tx, payment *SPVEnvelope) (map[string][]*bt.Input, error) { + m := make(map[string][]*bt.Input, len(tx.Inputs)) + + // No need to manually verify the tx inputs if a Merkle Proof has been provided + if payment.Proof != nil { + return m, nil + } + // If an unconfirmed tx has an input which is not present in the spv envelope, we // should fail and error, as we cannot prove the legitimacy of those inputs. for _, txInput := range tx.Inputs { if _, ok := payment.Parents[txInput.PreviousTxID]; !ok { - return false + return nil, ErrNotAllInputsSupplied } + + if m[txInput.PreviousTxID] == nil { + m[txInput.PreviousTxID] = make([]*bt.Input, 0) + } + + m[txInput.PreviousTxID] = append(m[txInput.PreviousTxID], txInput) } - return true + return m, nil } -func (s *SPVClient) childTxInputIdx(txID string, childTxInputs []*bt.Input) (int, error) { - // Search through the child tx's inputs, and when a tx id match is found, return its index. - for i, cTxInput := range childTxInputs { - if cTxInput.PreviousTxID == txID { - return i, nil +func (s *SPVClient) verifyAllTxInputsPresent(payment *SPVEnvelope, tx *bt.Tx) bool { + // If an unconfirmed tx has an input which is not present in the spv envelope, we + // should fail and error, as we cannot prove the legitimacy of those inputs. + for _, txInput := range tx.Inputs { + if _, ok := payment.Parents[txInput.PreviousTxID]; !ok { + return false } } - // Otherwise, fail and error - return 0, ErrTxNotInInputs + return true } func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { @@ -186,11 +188,14 @@ func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, pr return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInput *bt.Input, +func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInputs []*bt.Input, proofs map[string]bool) (bool, error) { - // TODO: verify child tx input's unlocking script with current tx output's locking script - output := tx.Outputs[int(childTxInput.PreviousTxOutIndex)] - _ = output + + for _, cTxInput := range childTxInputs { + // TODO: verify child tx input's unlocking script with current tx output's locking script + output := tx.Outputs[int(cTxInput.PreviousTxOutIndex)] + _ = output + } proofs[txID] = true diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 331f9af..4143cc3 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -29,23 +29,49 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }{ "valid envelope passes": { exp: true, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", - RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ Index: 1, - TxOrID: "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd", - Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", - "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", - "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", }, }, }, @@ -55,163 +81,140 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "envelope without any proof fails": { exp: false, expErr: ErrNoConfirmedTransaction, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") - }, - envelope: &SPVEnvelope{ - TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", - RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", - }, - }, - }, - }, - "valid envelope with merkle proof supplied as hex passes": { - exp: true, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", - RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ - Index: 1, - TxOrID: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", - Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", - "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", - "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", }, }, }, - }, - }, - }, - "invalid merkle proof fails": { - exp: false, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") - }, - envelope: &SPVEnvelope{ - TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", - RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", - Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ - Index: 3, // failing part, would pass if index were 1 - TxOrID: "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd", - Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", - "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", - "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", }, }, }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + }, }, }, }, - "tx relying on multiple proofs passes": { + "valid envelope with merkle proof supplied as hex passes": { exp: true, - blockHeaderFunc: func(ctx context.Context, blockhash string) (*BlockHeader, error) { - if blockhash == "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde" { - return EncodeBlockHeaderStr("000000200adb899e30726063e84b74d439b67309497c4717825a6ba6aa575fe349750561d5b08c94d2beae4847cec09da1aea32cfd5e0f11add310eb7c6d1b427fbc09c647320161ffff7f2000000000") + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", - RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*SPVEnvelope{ - "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433": { - RawTX: "02000000020e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7000000006b48304502210096373becf407ec50251aac835a9902173707688fa6dab001de9abe6acea3f98a022040f5b15ecf2e11d106878777e470e144bdb96fc567233eeb966989c958d16719412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff0e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7010000006b483045022100e0d75f4cc3d8b60ef36caa9d099975c3f3201a2e48ad1f8ac0d74d8e07a0aee40220459619b284589b53f14514b3c203b31a40d1442159c64d8e8631a68f9f74f5f841210302b1d9199e7a9357a24c98d5c22822fbaf4a1f39838bc564bd9b4384a75615a6feffffff021ecdf008000000001976a914ac0c1480344ba91deb47415153dbf7d2e4b1ccf788ac80b2e60e000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac69000000", + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ - Index: 1, - TxOrID: "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433", - Target: "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde", + Index: 2, + TxOrID: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "82e2faf3f1966eefbea0a88e77c629dfc35320e77ee053ee2071adf341cecda8", + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", }, }, }, - "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f": { - RawTX: "0200000001be304e579f89ea351c9eb351d8e29b72fb6ad71704553134e67a526b423490da010000006a47304402204b035ef4e8190ddbf6a11343ef46cdf6a35b60d18b3aec169c90463b52ab60c602205dc830ab4806c37f9875c234a8389a99f7a8b7a3b5e6cbd1e557dcf5e12df0f3412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff0200c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac1ea2e111000000001976a914ba4276fe9cca9c4d0e5bbefa6b5b7ee74a36fa6c88ac6a000000", + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ - Index: 2, - TxOrID: "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "025a356701f41c40769558a8962c765cb6b1da2bb3f7007916ad3c187215736c", - "fe4c0107b918c1366dc0485c404e7b6f92eb9499fd0036a07f9e58d3b4a992e8", + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", }, }, }, - "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa": { - RawTX: "02000000013324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c010000006b483045022100bde190f6a794aaaf14b4f1c553724883c8732c6bdcaae8b1633d52df769ffa1f02207f7cfed7183fd8515a575b070297e86a49c548977e456848f3109f342fc754ae412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff029eeffa02000000001976a914972e260dd73b41f8d91b1709005b60355cdc36ed88ac00c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac6a000000", + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &MerkleProof{ Index: 1, - TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + TxOrID: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", Nodes: []string{ - "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", - "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", }, }, }, }, }, }, - "tx relying on multiple proofs with one false fails": { + "invalid merkle proof fails": { exp: false, - blockHeaderFunc: func(ctx context.Context, blockhash string) (*BlockHeader, error) { - if blockhash == "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde" { - return EncodeBlockHeaderStr("000000200adb899e30726063e84b74d439b67309497c4717825a6ba6aa575fe349750561d5b08c94d2beae4847cec09da1aea32cfd5e0f11add310eb7c6d1b427fbc09c647320161ffff7f2000000000") + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", - RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*SPVEnvelope{ - "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433": { - RawTX: "02000000020e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7000000006b48304502210096373becf407ec50251aac835a9902173707688fa6dab001de9abe6acea3f98a022040f5b15ecf2e11d106878777e470e144bdb96fc567233eeb966989c958d16719412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff0e088697d6908275ab3084f77ca45d523433a3352947d1c1599a1a9fc9bb47a7010000006b483045022100e0d75f4cc3d8b60ef36caa9d099975c3f3201a2e48ad1f8ac0d74d8e07a0aee40220459619b284589b53f14514b3c203b31a40d1442159c64d8e8631a68f9f74f5f841210302b1d9199e7a9357a24c98d5c22822fbaf4a1f39838bc564bd9b4384a75615a6feffffff021ecdf008000000001976a914ac0c1480344ba91deb47415153dbf7d2e4b1ccf788ac80b2e60e000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac69000000", + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ - Index: 1, - TxOrID: "1cd17879b7a8a604cd10fe34a1872fec2b2bf0e4d0612445daa5a20737272433", - Target: "4d24ca92094980f0daacd7639f9329cf35848240db84fdd4c72b604082609bde", + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "82e2faf3f1966eefbea0a88e77c629dfc35320e77ee053ee2071adf341cecda8", + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", }, }, }, - "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f": { - RawTX: "0200000001be304e579f89ea351c9eb351d8e29b72fb6ad71704553134e67a526b423490da010000006a47304402204b035ef4e8190ddbf6a11343ef46cdf6a35b60d18b3aec169c90463b52ab60c602205dc830ab4806c37f9875c234a8389a99f7a8b7a3b5e6cbd1e557dcf5e12df0f3412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff0200c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac1ea2e111000000001976a914ba4276fe9cca9c4d0e5bbefa6b5b7ee74a36fa6c88ac6a000000", + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &MerkleProof{ - Index: 1, // failing part, would pass if index were 2 - TxOrID: "d4c91e0ebd38aa84a236e7567bb4c4ef1277f4a385420ac8c47011b56763310f", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "025a356701f41c40769558a8962c765cb6b1da2bb3f7007916ad3c187215736c", - "fe4c0107b918c1366dc0485c404e7b6f92eb9499fd0036a07f9e58d3b4a992e8", + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", }, }, }, - "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa": { - RawTX: "02000000013324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c010000006b483045022100bde190f6a794aaaf14b4f1c553724883c8732c6bdcaae8b1633d52df769ffa1f02207f7cfed7183fd8515a575b070297e86a49c548977e456848f3109f342fc754ae412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff029eeffa02000000001976a914972e260dd73b41f8d91b1709005b60355cdc36ed88ac00c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac6a000000", + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &MerkleProof{ - Index: 1, - TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + Index: 2, // fails, should be 1 to pass + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", Nodes: []string{ - "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", - "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", }, }, }, @@ -220,74 +223,122 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong tx supplied as input in envelope errs": { exp: false, - expErr: ErrTxNotInInputs, + expErr: ErrNotAllInputsSupplied, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", + TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &MerkleProof{ Index: 1, - TxOrID: "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd", - Target: "7264e88cccd8f3cbfc37f3a237b74ed02612c2f381291e3ffc1c70978642afd0", + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", Nodes: []string{ - "b1f3ed9a26f39f910a5186f4d33cc5fcef7fdc71328e96f3324e9eb84b54476e", - "e2a39c08e6cb998a5c7b5e9f4ac9303af43d8e6a859ad8127d9e2c569324f7d2", - "b17da0617adee7a7dad8147ca03cf5541c33ba10918dd88ddb2bc3889d78db05", + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", }, }, }, }, }, }, - "wrong merkle proof suppled with otherwise correct input errors": { + "wrong merkle proof supplied with otherwise correct input errors": { exp: false, expErr: ErrTxIDMismatch, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", - RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", - Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ // Valid merkle proof but for different tx Index: 1, - TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + TxOrID: "2e2b706ddede3b8c5e9bd13c684a0678072b11898770167c7ce569095d386df5", + Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", Nodes: []string{ - "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", - "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + "a859bb441c1a0082f1e3ffb24361242375ab63e648e1367d19d75cbe36a9ecaf", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", }, }, }, }, }, }, - "wrong merkle proof suppled via hex with otherwise correct input errors": { + "wrong merkle proof supplied via hex with otherwise correct input errors": { exp: false, expErr: ErrTxIDMismatch, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "af554cd922b2acd2f98b74b40c4b9b3c34c67e675226af162538fd6fbc27e3f2", - RawTX: "0200000002dd5975d42001f949bddbd305a0151f5a02af8c12762c816b4f124590aaecd661010000006b483045022100f0395c6faef111a79863d1beb06576ede11510cc7c4faf2f7d15d676bb9fde6102204f8fbfb3b00c6f1f2feb6ef967f811f820d689d65cb438c848c3202cab929053412103fea85bbd0423b68c678a4d2022d877d9062a1b406945b5c56e4e5c73f88c670ffeffffff4f0ffecd7a155bf39ccf0888ec834ef17f16cb0c42242dca6fde05d694745505000000006b483045022100ffe6c6990edc236c7679b2ac90d075d132230ad7ac54223089e9eeda3c50ff4302205a5a904e9e6c3f5843d4fa6071056ac2d23a525777b827dc825d20b9a8da362b412103659025689fd2d731ef500a4b12482076c8022bc726e98ca87eacc690036f5a60feffffff0200c2eb0b000000001976a91433236d7d53bce84f11875c142753ae9da01a965b88ac9ebdeb0b000000001976a914333d0cc4c776bafc389c867c1956b0ff42b7a4ad88acd3000000", + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*SPVEnvelope{ - "61d6ecaa9045124f6b812c76128caf025a1f15a005d3dbbd49f90120d47559dd": { - RawTX: "0200000002f5de420f7cfc76a3c3b3739ae1885e0e800bd43ab581e7db20c134d45b9092e4010000006b483045022100fdbdafafec00fee03e567663fc5b63c3d7798df6eafdac1b7d45105c256bbf3e0220110d96657b78ddce4485df4cc59fc782abc5237eaca6fd06f8df25d176e9271d412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff50bfdd732d9b58da2618d3455a3449e1e9f4adbcf738d10a47a7e77340c7f71e000000006b483045022100bfe70637627ec9132050f6c2f76eb0e1dbd2b31833d90e64704856b1993a3dd4022014fc68acf954604ade64ada962084f7dac3c9b573273bc3dec038fdd3bf48910412102eee549cbaf8dd3bd77991845115c20ab8709d215f939d13e2e6ae159c4b4dabffeffffff0200c2eb0b000000001976a9146b627e56d5b1d56dbffccb2f5dddc731bb7e8d6388ac8ac0eb0b000000001976a91419de2a52795e4aacf83f940386dca64ce3c988c288acd2000000", - Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ // Valid merkle proof but for different tx Index: 1, - TxOrID: "02000000013324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c010000006b483045022100bde190f6a794aaaf14b4f1c553724883c8732c6bdcaae8b1633d52df769ffa1f02207f7cfed7183fd8515a575b070297e86a49c548977e456848f3109f342fc754ae412102129cf1690078801a48c1fe3c0bdb6d8aac90756633c9fb7bec40f28403f7a3d9feffffff029eeffa02000000001976a914972e260dd73b41f8d91b1709005b60355cdc36ed88ac00c2eb0b000000001976a914cf3904101bdf618e8f0446bfab91c345111908a088ac6a000000", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + TxOrID: "0200000001e6512113175679cc5c78d637b0934e2e09bcd0d6a6693c11a372c0effd055ebf010000006a47304402200bf8ddd45e87d187740d1500451f54e24933be6d4cb188b2d8c300895ffe1c5e02207f82e9c9e97387cd5341a51d10e06455a21fcb53ffb5ba006ef91a2ab3dc4383412102ac939508911a1266ea64a30f6d3f2b311527c379087deca7171700e0369ecfa9feffffff0294cef008000000001976a9144cd75969d2baa7b0e5eab0d52f6555496799033088ac00e1f505000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac6a000000", + Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", Nodes: []string{ - "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", - "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + "a859bb441c1a0082f1e3ffb24361242375ab63e648e1367d19d75cbe36a9ecaf", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", }, }, }, @@ -298,60 +349,85 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": //nolint:goconst - return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") - case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": //nolint:goconst - return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", - RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*SPVEnvelope{ - "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { - TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", - RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*SPVEnvelope{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { - RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", - Proof: &MerkleProof{ - Index: 4, - TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", - "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, }, }, }, - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { - RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &MerkleProof{ - Index: 5, - TxOrID: "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", Nodes: []string{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", }, }, }, - }, - }, - "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { - TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", - Proof: &MerkleProof{ - Index: 2, - TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", - "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", - "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*SPVEnvelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, }, }, }, @@ -362,60 +438,85 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: false, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": - return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") - case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": - return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", - RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*SPVEnvelope{ - "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { - TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", - RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*SPVEnvelope{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { - RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", - Proof: &MerkleProof{ - Index: 4, - TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", - "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, }, }, }, - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { - RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &MerkleProof{ - Index: 1, // invalid index, should be 5 - TxOrID: "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", Nodes: []string{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", }, }, }, - }, - }, - "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { - TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", - Proof: &MerkleProof{ - Index: 2, - TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", - "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", - "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*SPVEnvelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &MerkleProof{ + Index: 2, // failure here, should be 1 to pass + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, }, }, }, @@ -427,47 +528,73 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrNotAllInputsSupplied, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": //nolint:goconst - return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") - case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": //nolint:goconst - return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", - RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*SPVEnvelope{ - "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { - TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", - RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*SPVEnvelope{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { - RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &MerkleProof{ - Index: 4, - TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", Nodes: []string{ - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", }, }, }, - }, - }, - "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { - TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", - Proof: &MerkleProof{ - Index: 2, - TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", - "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", - "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*SPVEnvelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + // TX missing here, b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f + }, }, }, }, @@ -479,59 +606,85 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrTxIDMismatch, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": - return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") - case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": - return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", - RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*SPVEnvelope{ - "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { - TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", - RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*SPVEnvelope{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { - RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", - Proof: &MerkleProof{ - Index: 4, - TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", - "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, }, }, }, - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { - RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", - Proof: &MerkleProof{ // Merkle proof is for a different TX that the current one suppled in input - Index: 1, - TxOrID: "05f587d97b067c2bd944533c4f7343a563ed46f01c09552138f805225b67dffa", - Target: "73894de091bb6910882295dc9d03539aae560de3612552285d612faa0fc3c216", + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &MerkleProof{ // This Merkle Proof is valid, it is just for a different tx. + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", Nodes: []string{ - "1c84115865bf49ab2eadf27548cdcb3c36cb8ca5402d77ffa90f1de001a3fee3", - "98979feadc42e66a67d762f930c22bf12d04ff8224b9d9b859ab29980a27f90a", + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", }, }, }, - }, - }, - "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { - TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", - Proof: &MerkleProof{ - Index: 2, - TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", - "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", - "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*SPVEnvelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, }, }, }, @@ -543,50 +696,77 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrNoConfirmedTransaction, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4980969d0fa17a8bfb541c54cf715cfb07b5c1bd6c272a5ba739810aa786dbc2": - return EncodeBlockHeaderStr("000000206e687283a5fb7b5e3a1e8e3452e431f8f987c9624b709d0bb65222adde722a6b219d5619fe8b4fc9dc056c81b28eedbd38be9f5e9b2e51def60106e836da8cf9164e0161ffff7f2000000000") - case "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e": - return EncodeBlockHeaderStr("00000020b575b47d65d7ef45b33facecef8b24b46ed1f2900413f0396fbc4dc8fc3e517f35ab994946ff6b342e24ff55b08a2f36b167dca104c49d9103b8d2bb83e991d3c44d0161ffff7f2001000000") + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("00000020de9b608240602bc7d4fd84db40828435cf29939f63d7acdaf080490992ca244dc13856f79f45f57721d007a2bb93d165625dc944b629bd231c1de5437ff7e5786e320161ffff7f2000000000") + return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &SPVEnvelope{ - TxID: "16519695ea4c79b80953192f1ff4d0b828cd19d529f27c1fe45a4b1585e437b0", - RawTX: "020000000204b160d59dac43bec838f8d9a93b8adf28f14d9798b1baaf90f11c7f1a7cc0c9010000006a47304402201e7e779f65f887c48650680c6d60b3a4565d51b011b9f3cccdbbe36bf8c31752022055957ede7c8b4cf0505ab4f250eca85ea9214ac2ec3c7dd5df3808f3225c8ce54121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff108e6958fed7d9ab449cd2285b7362ef025901a7fd370bbb1d1a56fc6d11d0e8000000006a47304402202fc570aafaf6c8b606a92eaf51d018da9ac6c739bd5db6be43e47a5b82b4a9b202205804176d19f68005c990ec188bae6f7864041ba5c6d1b505e4caaf46dc97c039412103f9faef2f65cba8df4003d91d8bf16a1d7fc82e77813360e6681f6d663f2c92b1feffffff0200ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac8ac0eb0b000000001976a914714ea9cfc710275d3eba4b5a116a724299057f8888acd0000000", + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*SPVEnvelope{ - "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10": { - TxID: "e8d0116dfc561a1dbb0b37fda7015902ef62735b28d29c44abd9d7fe58698e10", - RawTX: "02000000022cbec1e99aacccedccfd6274d8d741a22d7fd1e5d65b58af890e4dc7d0b5aef9000000006b483045022100c14c4c7909c9fbcc8597767637daf4acfa7a7e43f0bcb57a82a9cfe07f0d169e02206243c62953c835b1a00c843cf94fb9a869b67b811b4c99a1900ac2c55b21eac14121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffffc710a11837d8208a51e4b8a1ddc3aa5077fb8172e63ea44a0040284ee201c6f3000000006a47304402203bd3b3dc3a7b17dcd32d7cbc86a83700fa3d9bd9194f39b7255bba6a1f01bce702204fd594eeab7012cb285a116b3f2cd22a0ff3c907f19465273867662c7a3902b74121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff020027b929000000001976a91433cf3e04fc0b3264ce19d9b09b046a0b11617b8188ac8aa1e111000000001976a91466d296cbdba31a0cd733c3778dd059428fe7f01788accc000000", + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*SPVEnvelope{ - "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c": { - RawTX: "0200000001a45612a9c98030fdc5e350029ff13fb9a4bf4207819bf0ffc9c8e8595751576d0000000049483045022100f600fcaa08f7c7c0494385a821fb42196b1487a5ff882242224d3bc4dd02f72c0220418e145c571d881bf977a5af14db259414df259dced1eb8663362c504851558b41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914b26aac659ec4703fb1d7fce3e56eb98743c1483288accb000000", + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &MerkleProof{ - Index: 4, - TxOrID: "f9aeb5d0c74d0e89af585bd6e5d17f2da241d7d87462fdccedccac9ae9c1be2c", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", Nodes: []string{ - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7", "*", - "09ca16b38bfdcacec20ad2662a5fa8ad81a7599b35c54f898056841cd3428891", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", }, }, }, - "f3c601e24e2840004aa43ee67281fb7750aac3dda1b8e4518a20d83718a110c7": { - RawTX: "020000000121d1cbda5439d99b053abe2a4f81d34ddd5349cb2fb46b537f99348a018c040a00000000494830450221008c28f5443fe1daced51465ad3665af74c8bbec7334a1500da02859e4f61a4d0702203a73bc0ebb45c4799008ef9b666e01907fca1e2eb12eda528c7cf2dddc148c0f41feffffff020065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988ac408c380c010000001976a914bbbc06d2cb49f48f0338239d354e023ad9eedb7588accb000000", - }, - }, - }, - "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104": { - TxID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - RawTX: "0200000001d5653309f34addbe017b7f36f95bab4375c8f759c7323eafadd9827c4a60493d0000000048473044022067f66a7cdda8b6e3395095c99d8883c6e79f1ce2c9f19ddde0fb8acc3186531902204f6c9dd6184543a40ba8b9360fa74eac0961cfcc36564c8b2667c7a39e01ffc941feffffff02408c380c010000001976a914c01024d5ccfa50cd24431facc859f1904930a6ab88ac0065cd1d000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988accb000000", - Proof: &MerkleProof{ - Index: 2, - TxOrID: "c9c07c1a7f1cf190afbab198974df128df8a3ba9d9f838c8be43ac9dd560b104", - Target: "6b2a72dead2252b60b9d704b62c987f9f831e452348e1e3a5e7bfba58372686e", - Nodes: []string{ - "1849a6749e9ea4afbaa7bf3dd7323f38830e8351f58864e2991ee3e6af27d8a3", - "cd89244cbe9f6b94d260747b2546f4a80d2b007ca9a17c06d61a84df28127e4e", - "4d43e5fd615782958402e8b231171ee03eebeccb37817f13d380295cc958abee", + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*SPVEnvelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + Parents: map[string]*SPVEnvelope{ // This tx is missing its proof + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, }, }, }, From a8a5790653a868d1159fc9aabbaadefcb9a13289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 18:22:10 +0100 Subject: [PATCH 21/51] fixed linting --- spvenvelope.go | 15 ++------------- spvenvelope_test.go | 6 +++--- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index e002401..ce79aa4 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -21,7 +21,7 @@ var ( // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID ErrTxIDMismatch = errors.New("input and proof ID mismatch") - // NotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not + // ErrNotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not // present in the parent envelope ErrNotAllInputsSupplied = errors.New("a tx input missing in parent envelope") ) @@ -81,6 +81,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return false, ErrNoConfirmedTransaction } + // Group all tx inputs by their tx id, to pass to the parent envelope m, err := s.buildInputPaymentMap(tx, payment) if err != nil { return false, err @@ -149,18 +150,6 @@ func (s *SPVClient) buildInputPaymentMap(tx *bt.Tx, payment *SPVEnvelope) (map[s return m, nil } -func (s *SPVClient) verifyAllTxInputsPresent(payment *SPVEnvelope, tx *bt.Tx) bool { - // If an unconfirmed tx has an input which is not present in the spv envelope, we - // should fail and error, as we cannot prove the legitimacy of those inputs. - for _, txInput := range tx.Inputs { - if _, ok := payment.Parents[txInput.PreviousTxID]; !ok { - return false - } - } - - return true -} - func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 4143cc3..2d57d39 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -31,7 +31,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") @@ -349,9 +349,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { switch blockHash { - case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": //nolint:goconst return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") - case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": //nolint:goconst return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") From d18129f1687ad2d890483f4ddd40b579a43349ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 18:25:43 +0100 Subject: [PATCH 22/51] fixed incorrect rawtx in tests --- spvenvelope_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 2d57d39..3a91820 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -370,7 +370,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", From 5a0c42914890af115f21789373c5394de8e4dfb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 18:28:10 +0100 Subject: [PATCH 23/51] rename map variable to better name --- spvenvelope.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index ce79aa4..6424332 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -82,7 +82,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx } // Group all tx inputs by their tx id, to pass to the parent envelope - m, err := s.buildInputPaymentMap(tx, payment) + txInputs, err := s.buildInputPaymentMap(tx, payment) if err != nil { return false, err } @@ -95,7 +95,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent, m[parentTxID], false, proofs) + valid, err := s.verifyTxs(ctx, parent, txInputs[parentTxID], false, proofs) if err != nil { return false, err } From 89a368b47d88a31856b6300ba15df1c28f2bd8f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Wed, 11 Aug 2021 18:30:54 +0100 Subject: [PATCH 24/51] Updated commit to explain failure condition --- spvenvelope.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spvenvelope.go b/spvenvelope.go index 6424332..277ba09 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -81,7 +81,8 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return false, ErrNoConfirmedTransaction } - // Group all tx inputs by their tx id, to pass to the parent envelope + // Group all tx inputs by their tx id, to pass to the parent envelope. If we find any tx inputs + // that haven't been supplied as parents in the envelope, fail and error. txInputs, err := s.buildInputPaymentMap(tx, payment) if err != nil { return false, err From 6f2166a71a71e2aa978085dabf4a753e3ac5635d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 10:21:12 +0100 Subject: [PATCH 25/51] fix couple of bugs, added IsAnchor function --- spvenvelope.go | 49 ++++++++++----- spvenvelope_test.go | 142 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 174 insertions(+), 17 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 277ba09..839f308 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -24,6 +24,9 @@ var ( // ErrNotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not // present in the parent envelope ErrNotAllInputsSupplied = errors.New("a tx input missing in parent envelope") + + // ErrNoTxInputsToVerify returns if a transaction has no inputs + ErrNoTxInputsToVerify = errors.New("a tx has no inputs to verify") ) // SPVEnvelope is a struct which contains all information needed for a transaction to be verified. @@ -41,7 +44,7 @@ type SPVEnvelope struct { func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) - valid, err := s.verifyTxs(ctx, payment, nil, true, proofs) + valid, err := s.verifyTxs(ctx, payment, "", nil, true, proofs) if err != nil { return false, err } @@ -60,8 +63,8 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return true, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTxInputs []*bt.Input, - isTip bool, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTxID string, + childTxInputs []*bt.Input, isTip bool, proofs map[string]bool) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { @@ -72,16 +75,16 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx // The tip tx is the transaction we're trying to verify, and it should not have a supplied // Merkle Proof. - if isTip && payment.Proof != nil { + if isTip && payment.IsAnchor() { return false, ErrTipTxConfirmed } - // If at the beginning of the tx chain and tx is unconfirmed, fail and error. - if (payment.Parents == nil || len(payment.Parents) == 0) && payment.Proof == nil { + // If at the beginning or middle of the tx chain and tx is unconfirmed, fail and error. + if !payment.IsAnchor() && (payment.Parents == nil || len(payment.Parents) == 0) { return false, ErrNoConfirmedTransaction } - // Group all tx inputs by their tx id, to pass to the parent envelope. If we find any tx inputs + // Group all tx inputs by their outpoint tx id, to pass to the parent envelope. If we find any tx inputs // that haven't been supplied as parents in the envelope, fail and error. txInputs, err := s.buildInputPaymentMap(tx, payment) if err != nil { @@ -96,7 +99,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent, txInputs[parentTxID], false, proofs) + valid, err := s.verifyTxs(ctx, parent, parentTxID, txInputs[parentTxID], false, proofs) if err != nil { return false, err } @@ -117,20 +120,25 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx // If a Merkle Proof is provided, assume we are at the anchor/beginning of the tx chain. // Verify and return the result. - if payment.Proof != nil { - return s.verifyAnchorTx(ctx, payment, proofs) + if payment.IsAnchor() { + anchorValid, err := s.verifyAnchorTx(ctx, payment, proofs) + if err != nil { + return false, err + } + if !anchorValid { + return anchorValid, nil + } } - // If no Merkle Proof is provided, we must verify the unconfirmed tx or else we can not - // know if any of it's child txs are valid. - return s.verifyUnconfirmedTx(txID, tx, childTxInputs, proofs) + // We must verify the child tx or else we can not know if any of it's child txs are valid. + return s.verifyUnconfirmedTx(tx, childTxID, childTxInputs, proofs) } func (s *SPVClient) buildInputPaymentMap(tx *bt.Tx, payment *SPVEnvelope) (map[string][]*bt.Input, error) { m := make(map[string][]*bt.Input, len(tx.Inputs)) // No need to manually verify the tx inputs if a Merkle Proof has been provided - if payment.Proof != nil { + if payment.IsAnchor() { return m, nil } @@ -178,8 +186,12 @@ func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, pr return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInputs []*bt.Input, +func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, childTxID string, childTxInputs []*bt.Input, proofs map[string]bool) (bool, error) { + // If no inputs from the child tx have been provided, fail and error + if len(childTxInputs) == 0 { + return false, ErrNoTxInputsToVerify + } for _, cTxInput := range childTxInputs { // TODO: verify child tx input's unlocking script with current tx output's locking script @@ -187,7 +199,12 @@ func (s *SPVClient) verifyUnconfirmedTx(txID string, tx *bt.Tx, childTxInputs [] _ = output } - proofs[txID] = true + proofs[childTxID] = true return true, nil } + +// IsAnchor returns true if the evelope is the anchor tx. +func (s *SPVEnvelope) IsAnchor() bool { + return s.Proof != nil +} diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 3a91820..1fb7819 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -30,7 +30,6 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "valid envelope passes": { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } @@ -345,6 +344,57 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "envelope with tx no inputs errs": { + exp: false, + expErr: ErrNoTxInputsToVerify, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed + Parents: map[string]*SPVEnvelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, "valid multiple layer tx passes": { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { @@ -773,6 +823,96 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "tx with no inputs in multiple layer tx fails": { + exp: false, + expErr: ErrNoTxInputsToVerify, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + switch blockHash { + case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": + return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": + return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + } + return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", + RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + Parents: map[string]*SPVEnvelope{ + "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { + TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", + RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + Parents: map[string]*SPVEnvelope{ + "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { + TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", + RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { + RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", + Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", + Nodes: []string{ + "*", + "5ae4ef03ffd3ae75fbce6ae421dead87993af5d807564666bf49bf28254179dc", + }, + }, + }, + "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { + RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + Parents: map[string]*SPVEnvelope{ + "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { + TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", + RawTX: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed + Parents: map[string]*SPVEnvelope{ + "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", + Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", + Nodes: []string{ + "39db801002498eec86c8b902c997b5aa4cc6a5d60bbf2557a2a0d4f976b8a1be", + }, + }, + }, + }, + }, + "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { + TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", + Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", + Nodes: []string{ + "*", + "14ab2d3bb4310ed96da52dbd154c8f931656c6e7c193c8ff2e0a98627b00c710", + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, "envelope with confirmed root errs": { exp: false, expErr: ErrTipTxConfirmed, From 8e4a9d424f86b040ffbe94a97526150199e7586e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 11:22:06 +0100 Subject: [PATCH 26/51] made code way way simpler --- spvenvelope.go | 81 +++++++++++---------------------------------- spvenvelope_test.go | 3 +- 2 files changed, 22 insertions(+), 62 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 839f308..beababc 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -44,7 +44,7 @@ type SPVEnvelope struct { func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) - valid, err := s.verifyTxs(ctx, payment, "", nil, true, proofs) + valid, err := s.verifyTxs(ctx, payment, true, proofs) if err != nil { return false, err } @@ -63,8 +63,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return true, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTxID string, - childTxInputs []*bt.Input, isTip bool, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, isTip bool, proofs map[string]bool) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { @@ -84,13 +83,6 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx return false, ErrNoConfirmedTransaction } - // Group all tx inputs by their outpoint tx id, to pass to the parent envelope. If we find any tx inputs - // that haven't been supplied as parents in the envelope, fail and error. - txInputs, err := s.buildInputPaymentMap(tx, payment) - if err != nil { - return false, err - } - // 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. @@ -99,7 +91,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent, parentTxID, txInputs[parentTxID], false, proofs) + valid, err := s.verifyTxs(ctx, parent, false, proofs) if err != nil { return false, err } @@ -108,55 +100,14 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, childTx } } - // Given that the tip transaction of the SPVEnvelope is the tx we're trying to prove as - // legitimate, it will not come with a Merkle Proof (or any output links) to verify. - // - // As well as this, for this condition to be true, every previous Merkle Proof or - // tx verification will have passed. So, we can safely assume success and return true. - if isTip { - proofs[txID] = true - return true, 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.IsAnchor() { - anchorValid, err := s.verifyAnchorTx(ctx, payment, proofs) - if err != nil { - return false, err - } - if !anchorValid { - return anchorValid, nil - } + return s.verifyAnchorTx(ctx, payment, proofs) } // We must verify the child tx or else we can not know if any of it's child txs are valid. - return s.verifyUnconfirmedTx(tx, childTxID, childTxInputs, proofs) -} - -func (s *SPVClient) buildInputPaymentMap(tx *bt.Tx, payment *SPVEnvelope) (map[string][]*bt.Input, error) { - m := make(map[string][]*bt.Input, len(tx.Inputs)) - - // No need to manually verify the tx inputs if a Merkle Proof has been provided - if payment.IsAnchor() { - return m, nil - } - - // If an unconfirmed tx has an input which is not present in the spv envelope, we - // should fail and error, as we cannot prove the legitimacy of those inputs. - for _, txInput := range tx.Inputs { - if _, ok := payment.Parents[txInput.PreviousTxID]; !ok { - return nil, ErrNotAllInputsSupplied - } - - if m[txInput.PreviousTxID] == nil { - m[txInput.PreviousTxID] = make([]*bt.Input, 0) - } - - m[txInput.PreviousTxID] = append(m[txInput.PreviousTxID], txInput) - } - - return m, nil + return s.verifyUnconfirmedTx(tx, payment, proofs) } func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { @@ -186,20 +137,28 @@ func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, pr return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, childTxID string, childTxInputs []*bt.Input, - proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { // If no inputs from the child tx have been provided, fail and error - if len(childTxInputs) == 0 { + if len(tx.Inputs) == 0 { return false, ErrNoTxInputsToVerify } - for _, cTxInput := range childTxInputs { - // TODO: verify child tx input's unlocking script with current tx output's locking script - output := tx.Outputs[int(cTxInput.PreviousTxOutIndex)] + for _, input := range tx.Inputs { + parent, ok := payment.Parents[input.PreviousTxID] + if !ok { + return false, ErrNotAllInputsSupplied + } + + parentTx, err := bt.NewTxFromString(parent.RawTX) + if err != nil { + return false, err + } + + output := parentTx.Outputs[int(input.PreviousTxOutIndex)] _ = output } - proofs[childTxID] = true + proofs[tx.GetTxID()] = true return true, nil } diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 1fb7819..d8f6dc1 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -224,13 +224,14 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: false, expErr: ErrNotAllInputsSupplied, blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020d9c6bb358e13ec549c3e78ad67b2975f72e164d44f925ccf36fdaf3a35959b0348f38f71db7afaecc2b8b324c44ec05eed43a98de16fcb2e7e501622abff759cb2210161ffff7f2000000000") + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") }, envelope: &SPVEnvelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", Parents: map[string]*SPVEnvelope{ "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above + TxID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &MerkleProof{ Index: 1, From 779dae268af6ac56ca36bc36f1fa0bd93d37e42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 11:24:00 +0100 Subject: [PATCH 27/51] removed unneeded new line --- spvenvelope.go | 1 - 1 file changed, 1 deletion(-) diff --git a/spvenvelope.go b/spvenvelope.go index beababc..766a21d 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -64,7 +64,6 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo } func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, isTip bool, proofs map[string]bool) (bool, error) { - tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { return false, err From 42aee251b066262da65b974219af44258f9dfa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 11:28:41 +0100 Subject: [PATCH 28/51] removed extra param and fixed comments --- spvenvelope.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 766a21d..5be00c2 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -44,7 +44,13 @@ type SPVEnvelope struct { func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) - valid, err := s.verifyTxs(ctx, payment, true, proofs) + // The tip tx is the transaction we're trying to verify, and it should not have a supplied + // Merkle Proof. + if payment.IsAnchor() { + return false, ErrTipTxConfirmed + } + + valid, err := s.verifyTxs(ctx, payment, proofs) if err != nil { return false, err } @@ -63,7 +69,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo return true, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, isTip bool, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { return false, err @@ -71,12 +77,6 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, isTip b txID := tx.GetTxID() proofs[txID] = false - // The tip tx is the transaction we're trying to verify, and it should not have a supplied - // Merkle Proof. - if isTip && payment.IsAnchor() { - return false, ErrTipTxConfirmed - } - // If at the beginning or middle of the tx chain and tx is unconfirmed, fail and error. if !payment.IsAnchor() && (payment.Parents == nil || len(payment.Parents) == 0) { return false, ErrNoConfirmedTransaction @@ -90,7 +90,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, isTip b parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent, false, proofs) + valid, err := s.verifyTxs(ctx, parent, proofs) if err != nil { return false, err } @@ -105,7 +105,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, isTip b return s.verifyAnchorTx(ctx, payment, proofs) } - // We must verify the child tx or else we can not know if any of it's child txs are valid. + // We must verify the tx or else we can not know if any of it's child txs are valid. return s.verifyUnconfirmedTx(tx, payment, proofs) } @@ -137,7 +137,7 @@ func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, pr } func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { - // If no inputs from the child tx have been provided, fail and error + // If no tx inputs have been provided, fail and error if len(tx.Inputs) == 0 { return false, ErrNoTxInputsToVerify } From 3648e7d712eb07108c750f901b6a77d47371c05c Mon Sep 17 00:00:00 2001 From: Jad Wahab Date: Thu, 12 Aug 2021 11:43:13 +0100 Subject: [PATCH 29/51] refactor! for clarify --- spvenvelope.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 5be00c2..00a7687 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -46,7 +46,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bo // The tip tx is the transaction we're trying to verify, and it should not have a supplied // Merkle Proof. - if payment.IsAnchor() { + if payment.IsAnchored() { return false, ErrTipTxConfirmed } @@ -78,7 +78,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, proofs proofs[txID] = false // If at the beginning or middle of the tx chain and tx is unconfirmed, fail and error. - if !payment.IsAnchor() && (payment.Parents == nil || len(payment.Parents) == 0) { + if !payment.IsAnchored() && (payment.Parents == nil || len(payment.Parents) == 0) { return false, ErrNoConfirmedTransaction } @@ -95,21 +95,21 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, proofs return false, err } if !valid { - return valid, nil + 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.IsAnchor() { - return s.verifyAnchorTx(ctx, payment, proofs) + if payment.IsAnchored() { + return s.verifyTxAnchor(ctx, payment, proofs) } // We must verify the tx or else we can not know if any of it's child txs are valid. return s.verifyUnconfirmedTx(tx, payment, proofs) } -func (s *SPVClient) verifyAnchorTx(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) @@ -154,6 +154,8 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs } output := parentTx.Outputs[int(input.PreviousTxOutIndex)] + + // TODO: verify script using input and previous output _ = output } @@ -162,7 +164,7 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs return true, nil } -// IsAnchor returns true if the evelope is the anchor tx. -func (s *SPVEnvelope) IsAnchor() bool { +// IsAnchored returns true if the evelope is the anchor tx. +func (s *SPVEnvelope) IsAnchored() bool { return s.Proof != nil } From 8dc716764a05a8737c1a3147e279e1eac255befa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 12:19:01 +0100 Subject: [PATCH 30/51] better param naming. Added check for initial payment being nil, and output index out of bounds. Added test cases for these --- spvenvelope.go | 23 +++++++++++++++---- spvenvelope_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 00a7687..76cdf35 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -27,6 +27,12 @@ var ( // ErrNoTxInputsToVerify returns if a transaction has no inputs ErrNoTxInputsToVerify = errors.New("a tx has no inputs to verify") + + // ErrNilInitialPayment returns if a transaction has no inputs + ErrNilInitialPayment = errors.New("initial payment cannot be nil") + + // ErrInputRefsOutOfBoundsOutput returns if a transaction has no inputs + ErrInputRefsOutOfBoundsOutput = errors.New("tx input index into output is out of bounds") ) // SPVEnvelope is a struct which contains all information needed for a transaction to be verified. @@ -41,16 +47,20 @@ type SPVEnvelope struct { } // VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid -func (s *SPVClient) VerifyPayment(ctx context.Context, payment *SPVEnvelope) (bool, error) { +func (s *SPVClient) VerifyPayment(ctx context.Context, initialPayment *SPVEnvelope) (bool, error) { proofs := make(map[string]bool) + 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 payment.IsAnchored() { + if initialPayment.IsAnchored() { return false, ErrTipTxConfirmed } - valid, err := s.verifyTxs(ctx, payment, proofs) + valid, err := s.verifyTxs(ctx, initialPayment, proofs) if err != nil { return false, err } @@ -153,6 +163,11 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs return false, err } + // If the input is indexing an ouput 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 @@ -164,7 +179,7 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs return true, nil } -// IsAnchored returns true if the evelope is the anchor tx. +// IsAnchored returns true if the envelope is the anchor tx. func (s *SPVEnvelope) IsAnchored() bool { return s.Proof != nil } diff --git a/spvenvelope_test.go b/spvenvelope_test.go index d8f6dc1..78dd869 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -396,6 +396,57 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "tx with input indexing out of bounds output errors": { + exp: false, + expErr: ErrInputRefsOutOfBoundsOutput, + blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst + return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + } + return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + }, + envelope: &SPVEnvelope{ + TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", + RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0020000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // tx.Input[0].PreviousTxOutIndex has been changed from 1, to 2, leaving it out of bounds + Parents: map[string]*SPVEnvelope{ + "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { + RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 2, + TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "*", + "88ab1ef96db7609ed506efebd84a07082f1bb2e6cc7f459cc3e0944c2aecc9b5", + }, + }, + }, + "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { + RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", + Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", + Nodes: []string{ + "1ded06ffd7b5a079f778ddd59e8e81e7ca9a200dba16e9e62b84a86f7a88fa48", + "1935e31ab86f41cc82fbcbf225bf7641b2ced25b100ead4bf4dd219513257c83", + }, + }, + }, + "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { + RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + Proof: &MerkleProof{ + Index: 1, + TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", + Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", + Nodes: []string{ + "f9c8760a09caef1359177165659336d4d10bc3f5c712e71adff33f43089587b6", + }, + }, + }, + }, + }, + }, "valid multiple layer tx passes": { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { @@ -933,6 +984,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, + "nil initial payment errors": { + exp: false, + expErr: ErrNilInitialPayment, + }, } for name, test := range tests { From 9374860f2f9dc6ffafa551a2679b59e90c563e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 12:38:40 +0100 Subject: [PATCH 31/51] removed proofs map --- spvenvelope.go | 37 +++++++++---------------------------- spvenvelope_test.go | 2 +- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 76cdf35..c6fa10b 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -48,8 +48,6 @@ type SPVEnvelope struct { // VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid func (s *SPVClient) VerifyPayment(ctx context.Context, initialPayment *SPVEnvelope) (bool, error) { - proofs := make(map[string]bool) - if initialPayment == nil { return false, ErrNilInitialPayment } @@ -60,32 +58,19 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, initialPayment *SPVEnvelo return false, ErrTipTxConfirmed } - valid, err := s.verifyTxs(ctx, initialPayment, proofs) + valid, err := s.verifyTxs(ctx, initialPayment) if err != nil { return false, err } - if !valid { - return valid, nil - } - - // TODO: check if still needed - // Check the proofs map for safety, in case any tx was skipped during verification - for _, v := range proofs { - if !v { - return false, ErrPaymentNotVerified - } - } - return true, nil + return valid, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope) (bool, error) { tx, err := bt.NewTxFromString(payment.RawTX) if err != nil { return false, err } - txID := tx.GetTxID() - proofs[txID] = false // 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) { @@ -100,7 +85,7 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, proofs parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent, proofs) + valid, err := s.verifyTxs(ctx, parent) if err != nil { return false, err } @@ -112,14 +97,14 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope, proofs // 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 s.verifyTxAnchor(ctx, payment, proofs) + return s.verifyTxAnchor(ctx, payment) } // We must verify the tx or else we can not know if any of it's child txs are valid. - return s.verifyUnconfirmedTx(tx, payment, proofs) + return s.verifyUnconfirmedTx(tx, payment) } -func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) @@ -141,12 +126,10 @@ func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope, pr return false, err } - proofs[payment.TxID] = valid - return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs map[string]bool) (bool, error) { +func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope) (bool, error) { // If no tx inputs have been provided, fail and error if len(tx.Inputs) == 0 { return false, ErrNoTxInputsToVerify @@ -163,7 +146,7 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs return false, err } - // If the input is indexing an ouput that is out of bounds, fail and error + // 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 } @@ -174,8 +157,6 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope, proofs _ = output } - proofs[tx.GetTxID()] = true - return true, nil } diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 78dd869..57171e8 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -400,7 +400,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: false, expErr: ErrInputRefsOutOfBoundsOutput, blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { - if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst + if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") From a742b93ab1dc721241afee3d9db3f549834fb92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 12 Aug 2021 17:07:17 +0100 Subject: [PATCH 32/51] removed minercraft dependency. added mapi callback --- go.mod | 6 ++++- go.sum | 67 ------------------------------------------------- mapicallback.go | 13 ++++++++++ spvenvelope.go | 3 +-- 4 files changed, 19 insertions(+), 70 deletions(-) create mode 100644 mapicallback.go diff --git a/go.mod b/go.mod index 1fa4dc4..d1a1364 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,11 @@ module github.com/libsv/go-bc go 1.15 require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/kr/pretty v0.1.0 // indirect github.com/libsv/go-bt v1.0.0-beta github.com/stretchr/testify v1.7.0 - github.com/tonicpow/go-minercraft v0.2.11 + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 30c6c55..d9ff69b 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,10 @@ -github.com/DataDog/datadog-go v3.7.1+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/afex/hystrix-go v0.0.0-20180209013831-27fae8d30f1a/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/bitcoinschema/go-bitcoin v0.3.17 h1:zyByOoInoqTxypToiND4xmx8itGcU801m9xrJ5nYd9I= -github.com/bitcoinschema/go-bitcoin v0.3.17/go.mod h1:3XL+F4hXuiJjpdIn/KpruivmfyRDOfexsx3coXexymg= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173 h1:2yTIV9u7H0BhRDGXH5xrAwAz7XibWJtX2dNezMeNsUo= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173/go.mod h1:BZ1UcC9+tmcDEcdVXgpt13hMczwJxWzpAn68wNs7zRA= -github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e h1:6f+gRvaPE/4h0g39dqTNPr9/P4mikw0aB+dhiExaWN8= -github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e/go.mod h1:WPrWor6cSeuGQZ15qPe+jqFmblJEFrJHYfr5cD7cmyk= github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9 h1:hFI8rT84FCA0FFy3cFrkW5Nz4FyNKlIdCvEvvTNySKg= github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9/go.mod h1:p44KuNKUH5BC8uX4ONEODaHUR4+ibC8todEAOGQEJAM= -github.com/cactus/go-statsd-client/statsd v0.0.0-20200423205355-cb0885a1018c/go.mod h1:l/bIBLeOl9eX+wxJAzxS4TveKRtAqlyDpHjhkfO0MEI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gojektech/heimdall/v6 v6.1.0 h1:M9L1xryMKGWUlAA33D0r0BaKiXWzvuReltDPPkC5loM= -github.com/gojektech/heimdall/v6 v6.1.0/go.mod h1:8g/ohsh0GXn8fzOf+qVrjX5pQLf7qQy8vEBjBUJ/9L4= -github.com/gojektech/valkyrie v0.0.0-20180215180059-6aee720afcdf/go.mod h1:tDYRk1s5Pms6XJjj5m2PxAzmQvaDU8GqDf1u6x7yxKw= -github.com/gojektech/valkyrie v0.0.0-20190210220504-8f62c1e7ba45 h1:MO2DsGCZz8phRhLnpFvHEQgTH521sVN/6F2GZTbNO3Q= -github.com/gojektech/valkyrie v0.0.0-20190210220504-8f62c1e7ba45/go.mod h1:tDYRk1s5Pms6XJjj5m2PxAzmQvaDU8GqDf1u6x7yxKw= -github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -26,60 +12,21 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/libsv/go-bt v1.0.0-beta h1:Sh/ACr0y/uTI41qS+3yo9jMl5VUDIa+euWdk33c4OJg= github.com/libsv/go-bt v1.0.0-beta/go.mod h1:AfXoLFYEbY/TvCq/84xTce2xGjPUuC5imokHmcykF2k= -github.com/mattn/goveralls v0.0.6/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= -github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tonicpow/go-minercraft v0.2.11 h1:UuKdjojwz+7Z0ppFATSA6fMRtDX29rp9qjL6MqdzQzA= -github.com/tonicpow/go-minercraft v0.2.11/go.mod h1:eyGNUs6iyGTKgdXp0yWXQUfBBxIRqnfzM+jMb2eeyog= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9 h1:sYNJzB4J8toYPQTM6pAkcmBRgw9SnQKP9oXCHfgy604= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -87,24 +34,10 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200530233709-52effbd89c51/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/mapicallback.go b/mapicallback.go new file mode 100644 index 0000000..fb259f7 --- /dev/null +++ b/mapicallback.go @@ -0,0 +1,13 @@ +package bc + +// MapiCallback is the body contents posted to the provided callback url from Merchant API +type MapiCallback struct { + CallbackPayload string `json:"callbackPayload"` + APIVersion string `json:"apiVersion"` + Timestamp string `json:"timestamp"` + MinerID string `json:"minerId"` + BlockHash string `json:"blockHash"` + BlockHeight uint64 `json:"blockHeight"` + CallbackTxID string `json:"callbackTxId"` + CallbackReason string `json:"callbackReason"` +} diff --git a/spvenvelope.go b/spvenvelope.go index c6fa10b..5341de5 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -5,7 +5,6 @@ import ( "errors" "github.com/libsv/go-bt" - "github.com/tonicpow/go-minercraft" ) var ( @@ -42,7 +41,7 @@ type SPVEnvelope struct { TxID string `json:"txid"` RawTX string `json:"rawTx,omitempty"` Proof *MerkleProof `json:"proof,omitempty"` - MapiResponses []minercraft.Callback `json:"mapiResponses,omitempty"` + MapiResponses []MapiCallback `json:"mapiResponses,omitempty"` Parents map[string]*SPVEnvelope `json:"parents"` } From fd86095a907d272f0bb498f9df1d64129b54db4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 13 Aug 2021 11:11:24 +0100 Subject: [PATCH 33/51] add omitempty to two fields --- spvenvelope.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spvenvelope.go b/spvenvelope.go index 5341de5..5b6eaba 100644 --- a/spvenvelope.go +++ b/spvenvelope.go @@ -38,11 +38,11 @@ var ( // // spec at https://tsc.bitcoinassociation.net/standards/spv-envelope/ type SPVEnvelope struct { - TxID string `json:"txid"` + TxID string `json:"txid,omitempty"` RawTX string `json:"rawTx,omitempty"` Proof *MerkleProof `json:"proof,omitempty"` MapiResponses []MapiCallback `json:"mapiResponses,omitempty"` - Parents map[string]*SPVEnvelope `json:"parents"` + Parents map[string]*SPVEnvelope `json:"parents,omitempty"` } // VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid From 41ddd1b658c567dc692d3e5ef9d09c884b1c8eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 16:49:43 +0100 Subject: [PATCH 34/51] fixed test data --- spvenvelope_test.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/spvenvelope_test.go b/spvenvelope_test.go index 57171e8..48684ab 100644 --- a/spvenvelope_test.go +++ b/spvenvelope_test.go @@ -504,6 +504,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, @@ -561,7 +562,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -593,6 +594,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 2, // failure here, should be 1 to pass @@ -651,7 +653,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -683,6 +685,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, @@ -729,7 +732,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -761,6 +764,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, @@ -819,7 +823,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { Parents: map[string]*SPVEnvelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -851,6 +855,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*SPVEnvelope{ // This tx is missing its proof "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { + TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", }, }, From 87a779ce4c0c12c4d281bcb8dbd706ee338263f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 16:50:02 +0100 Subject: [PATCH 35/51] spv envelope creater, first tests written --- go.mod | 1 + go.sum | 2 + spv/options.go | 25 + spv/spvclient.go | 60 ++ spvenvelope.go => spv/spvenvelope.go | 89 +- .../spvenvelope_test.go | 981 +++++++++++++++--- spv/txgetter.go | 14 + .../verifymerkleproof.go | 15 +- .../verifymerkleproof_internal_test.go | 5 +- .../verifymerkleproof_test.go | 5 +- spvclient.go | 39 - 11 files changed, 1005 insertions(+), 231 deletions(-) create mode 100644 spv/options.go create mode 100644 spv/spvclient.go rename spvenvelope.go => spv/spvenvelope.go (69%) rename spvenvelope_test.go => spv/spvenvelope_test.go (56%) create mode 100644 spv/txgetter.go rename verifymerkleproof.go => spv/verifymerkleproof.go (94%) rename verifymerkleproof_internal_test.go => spv/verifymerkleproof_internal_test.go (95%) rename verifymerkleproof_test.go => spv/verifymerkleproof_test.go (93%) delete mode 100644 spvclient.go diff --git a/go.mod b/go.mod index 7477678..dd2f910 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/kr/pretty v0.1.0 // indirect github.com/libsv/go-bk v0.0.0-20210430094342-ff08e691962b github.com/libsv/go-bt/v2 v2.0.0-20210730150403-97fd3b293e05 + github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect diff --git a/go.sum b/go.sum index 1e2978a..5af7461 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,8 @@ github.com/libsv/go-bk v0.0.0-20210430094342-ff08e691962b h1:NJkme7OR8Mz8emNPiG0 github.com/libsv/go-bk v0.0.0-20210430094342-ff08e691962b/go.mod h1:xbDkeFFpP0uyFaPLnP6TwaLpAsHaslZ0LftTdWlB6HI= github.com/libsv/go-bt/v2 v2.0.0-20210730150403-97fd3b293e05 h1:rRANK7Nc+bp0odO2zvDdHZBloGuwopGIx54yXypuR9k= github.com/libsv/go-bt/v2 v2.0.0-20210730150403-97fd3b293e05/go.mod h1:62PATaSIMQ3omXVr9D4S7uMKaQByCJjNkrNzFpYThco= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/spv/options.go b/spv/options.go new file mode 100644 index 0000000..13cacb2 --- /dev/null +++ b/spv/options.go @@ -0,0 +1,25 @@ +package spv + +import "github.com/libsv/go-bc" + +// SPVOpts can be implemented to provided functional options for an SPVClient. +type ClientOpts func(*spvclient) + +// WithBlockHeaderChain will inject the provided BlockHeaderChain into the SPVClient. +func WithBlockHeaderChain(bhc bc.BlockHeaderChain) ClientOpts { + return func(s *spvclient) { + s.bhc = bhc + } +} + +func WithTXGetter(txg TXGetter) ClientOpts { + return func(s *spvclient) { + s.txg = txg + } +} + +func WithMerkleProofGetter(mpg MerkleProofGetter) ClientOpts { + return func(s *spvclient) { + s.mpg = mpg + } +} diff --git a/spv/spvclient.go b/spv/spvclient.go new file mode 100644 index 0000000..e93d9c1 --- /dev/null +++ b/spv/spvclient.go @@ -0,0 +1,60 @@ +package spv + +import ( + "context" + "errors" + + "github.com/libsv/go-bc" + "github.com/libsv/go-bt/v2" +) + +// An Client is a struct used to specify interfaces +// used to complete Simple Payment Verification (SPV) +// in conjunction with a Merkle Proof. +// +// The implementation of BlockHeaderChain which is supplied will depend on the client +// you are using, some may return a HeaderJSON response others may return the blockhash. +type Client interface { + EnvelopeService + MerkleProofVerifier +} + +type EnvelopeService interface { + EnvelopeBuilder + EnvelopeVerifier +} + +type EnvelopeBuilder interface { + CreateEnvelope(*bt.Tx) (*Envelope, error) +} + +// EnvelopeVerifier interfaces the verification of SPV Envelopes +type EnvelopeVerifier interface { + VerifyPayment(context.Context, *Envelope) (bool, error) +} + +// MerkleProofVerifier interfaces the verification of Merkle Proofs +type MerkleProofVerifier interface { + VerifyMerkleProof(context.Context, []byte) (bool, bool, error) + VerifyMerkleProofJSON(context.Context, *bc.MerkleProof) (bool, bool, error) +} + +type spvclient struct { + // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. + bhc bc.BlockHeaderChain + txg TXGetter + mpg MerkleProofGetter +} + +// NewClient creates a new spv.Client based on the options provided. +// If no BlockHeaderChain implementation is provided, the setup will return an error. +func NewClient(opts ...ClientOpts) (Client, error) { + cli := &spvclient{} + for _, opt := range opts { + opt(cli) + } + if cli.bhc == nil { + return nil, errors.New("at least one blockchain header implementation should be returned") + } + return cli, nil +} diff --git a/spvenvelope.go b/spv/spvenvelope.go similarity index 69% rename from spvenvelope.go rename to spv/spvenvelope.go index c628fbd..0ed1b03 100644 --- a/spvenvelope.go +++ b/spv/spvenvelope.go @@ -1,10 +1,12 @@ -package bc +package spv import ( "context" - "errors" + "fmt" + "github.com/libsv/go-bc" "github.com/libsv/go-bt/v2" + "github.com/pkg/errors" ) var ( @@ -34,19 +36,64 @@ var ( ErrInputRefsOutOfBoundsOutput = errors.New("tx input index into output is out of bounds") ) -// SPVEnvelope is a struct which contains all information needed for a transaction to be verified. +// Envelope is a struct which contains all information needed for a transaction to be verified. // // spec at https://tsc.bitcoinassociation.net/standards/spv-envelope/ -type SPVEnvelope struct { - TxID string `json:"txid,omitempty"` - RawTX string `json:"rawTx,omitempty"` - Proof *MerkleProof `json:"proof,omitempty"` - MapiResponses []MapiCallback `json:"mapiResponses,omitempty"` - Parents map[string]*SPVEnvelope `json:"parents,omitempty"` +type Envelope struct { + TxID string `json:"txid,omitempty"` + RawTX string `json:"rawTx,omitempty"` + Proof *bc.MerkleProof `json:"proof,omitempty"` + MapiResponses []bc.MapiCallback `json:"mapiResponses,omitempty"` + Parents map[string]*Envelope `json:"parents,omitempty"` } -// VerifyPayment verifies whether or not the txs supplied via the supplied SPVEnvelope are valid -func (s *SPVClient) VerifyPayment(ctx context.Context, initialPayment *SPVEnvelope) (bool, error) { +func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { + txID := tx.TxID() + envelope := &Envelope{ + TxID: txID, + RawTX: tx.String(), + Parents: make(map[string]*Envelope), + } + + for _, input := range tx.Inputs { + pTxID := input.PreviousTxIDStr() + if _, ok := envelope.Parents[pTxID]; ok { + continue + } + + mp, err := s.mpg.MerkleProof(pTxID) + if err != nil { + return nil, errors.Wrapf(err, "failed to get merkle proof for tx %s", pTxID) + } + if mp != nil { + envelope.Parents[pTxID] = &Envelope{ + TxID: pTxID, + Proof: mp, + } + continue + } + + pTx, err := s.txg.Tx(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 := s.CreateEnvelope(pTx) + if err != nil { + return nil, err + } + + envelope.Parents[pTxID] = pEnvelope + } + + return envelope, nil +} + +// VerifyPayment verifies whether or not the txs supplied via the supplied spv.Envelope are valid +func (s *spvclient) VerifyPayment(ctx context.Context, initialPayment *Envelope) (bool, error) { if initialPayment == nil { return false, ErrNilInitialPayment } @@ -65,12 +112,7 @@ func (s *SPVClient) VerifyPayment(ctx context.Context, initialPayment *SPVEnvelo return valid, nil } -func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope) (bool, error) { - tx, err := bt.NewTxFromString(payment.RawTX) - if err != nil { - return false, err - } - +func (s *spvclient) 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 @@ -99,11 +141,16 @@ func (s *SPVClient) verifyTxs(ctx context.Context, payment *SPVEnvelope) (bool, return s.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 s.verifyUnconfirmedTx(tx, payment) } -func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope) (bool, error) { +func (s *spvclient) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) @@ -114,7 +161,7 @@ func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope) (b proofTxID = proofTx.TxID() } - // If the txid of the Merkle Proof doesn't match the txid provided in the SPVEnvelope, + // 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 @@ -128,7 +175,7 @@ func (s *SPVClient) verifyTxAnchor(ctx context.Context, payment *SPVEnvelope) (b return valid, nil } -func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope) (bool, error) { +func (s *spvclient) 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 @@ -160,6 +207,6 @@ func (s *SPVClient) verifyUnconfirmedTx(tx *bt.Tx, payment *SPVEnvelope) (bool, } // IsAnchored returns true if the envelope is the anchor tx. -func (s *SPVEnvelope) IsAnchored() bool { +func (s *Envelope) IsAnchored() bool { return s.Proof != nil } diff --git a/spvenvelope_test.go b/spv/spvenvelope_test.go similarity index 56% rename from spvenvelope_test.go rename to spv/spvenvelope_test.go index 48684ab..2e445a8 100644 --- a/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -1,18 +1,21 @@ -package bc +package spv import ( "context" "errors" + "fmt" "testing" + "github.com/libsv/go-bc" + "github.com/libsv/go-bt/v2" "github.com/stretchr/testify/assert" ) type mockBlockHeaderClient struct { - blockHeaderFunc func(context.Context, string) (*BlockHeader, error) + blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) } -func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash string) (*BlockHeader, error) { +func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if m.blockHeaderFunc != nil { return m.blockHeaderFunc(ctx, blockHash) } @@ -20,28 +23,49 @@ func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash strin return nil, errors.New("blockHeaderFunc in test is undefined") } +type mockTXMerkleGetter struct { + txGetterFunc func(string) (*bt.Tx, error) + mpGetterFunc func(string) (*bc.MerkleProof, error) +} + +func (m *mockTXMerkleGetter) Tx(txID string) (*bt.Tx, error) { + if m.txGetterFunc == nil { + return nil, errors.New("txGetterFunc in test is undefined") + } + + return m.txGetterFunc(txID) +} + +func (m *mockTXMerkleGetter) MerkleProof(txID string) (*bc.MerkleProof, error) { + if m.txGetterFunc == nil { + return nil, errors.New("mpGetterFunc in test is undefined") + } + + return m.mpGetterFunc(txID) +} + func TestSPVEnvelope_VerifyPayment(t *testing.T) { tests := map[string]struct { - envelope *SPVEnvelope - blockHeaderFunc func(context.Context, string) (*BlockHeader, error) + envelope *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) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -53,7 +77,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -65,7 +89,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -80,19 +104,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "envelope without any proof fails": { exp: false, expErr: ErrNoConfirmedTransaction, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -104,7 +128,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -122,19 +146,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "valid envelope with merkle proof supplied as hex passes": { exp: true, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -146,7 +170,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -158,7 +182,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -172,19 +196,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "invalid merkle proof fails": { exp: false, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -196,7 +220,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -208,7 +232,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, // fails, should be 1 to pass TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -223,17 +247,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "wrong tx supplied as input in envelope errs": { exp: false, expErr: ErrNotAllInputsSupplied, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above TxID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -248,19 +272,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "wrong merkle proof supplied with otherwise correct input errors": { exp: false, expErr: ErrTxIDMismatch, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -272,7 +296,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ // Valid merkle proof but for different tx + Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx Index: 1, TxOrID: "2e2b706ddede3b8c5e9bd13c684a0678072b11898770167c7ce569095d386df5", Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", @@ -283,7 +307,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -298,19 +322,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "wrong merkle proof supplied via hex with otherwise correct input errors": { exp: false, expErr: ErrTxIDMismatch, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -322,7 +346,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ // Valid merkle proof but for different tx + Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx Index: 1, TxOrID: "0200000001e6512113175679cc5c78d637b0934e2e09bcd0d6a6693c11a372c0effd055ebf010000006a47304402200bf8ddd45e87d187740d1500451f54e24933be6d4cb188b2d8c300895ffe1c5e02207f82e9c9e97387cd5341a51d10e06455a21fcb53ffb5ba006ef91a2ab3dc4383412102ac939508911a1266ea64a30f6d3f2b311527c379087deca7171700e0369ecfa9feffffff0294cef008000000001976a9144cd75969d2baa7b0e5eab0d52f6555496799033088ac00e1f505000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac6a000000", Target: "14ed7fa0bb38d7ecae9d352075d32c9dd75dd0bcdc7feefb2793d99042462875", @@ -333,7 +357,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -348,19 +372,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "envelope with tx no inputs errs": { exp: false, expErr: ErrNoTxInputsToVerify, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -372,7 +396,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -384,7 +408,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -399,19 +423,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "tx with input indexing out of bounds output errors": { exp: false, expErr: ErrInputRefsOutOfBoundsOutput, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0020000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // tx.Input[0].PreviousTxOutIndex has been changed from 1, to 2, leaving it out of bounds - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -423,7 +447,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -435,7 +459,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", Target: "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f", @@ -449,31 +473,31 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "valid multiple layer tx passes": { exp: true, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": //nolint:goconst - return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": //nolint:goconst - return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -486,7 +510,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", @@ -498,15 +522,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -520,7 +544,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", @@ -539,31 +563,31 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "invalid multiple layer tx false": { exp: false, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -576,7 +600,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", @@ -588,15 +612,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, // failure here, should be 1 to pass TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -610,7 +634,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", @@ -630,31 +654,31 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "tx with input missing from envelope parents errors": { exp: false, expErr: ErrNotAllInputsSupplied, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -667,7 +691,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", @@ -679,15 +703,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -709,31 +733,31 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "wrong merkle proof suppled with otherwise correct layered input errors": { exp: false, expErr: ErrTxIDMismatch, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -746,7 +770,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &MerkleProof{ // This Merkle Proof is valid, it is just for a different tx. + Proof: &bc.MerkleProof{ // This Merkle Proof is valid, it is just for a different tx. Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", Target: "6f2c5a14033b6082fb160cc2603d2047f30df4bcc07b506c5de97dd9b10d4477", @@ -758,15 +782,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -780,7 +804,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", @@ -800,31 +824,31 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "single missing merkle proof in layered and branching tx errors": { exp: false, expErr: ErrNoConfirmedTransaction, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -837,7 +861,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", @@ -849,11 +873,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*SPVEnvelope{ // This tx is missing its proof + Parents: map[string]*Envelope{ // This tx is missing its proof "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -863,7 +887,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", @@ -883,31 +907,31 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "tx with no inputs in multiple layer tx fails": { exp: false, expErr: ErrNoTxInputsToVerify, - blockHeaderFunc: func(ctx context.Context, blockHash string) (*BlockHeader, error) { + blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -920,7 +944,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", Target: "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d", @@ -932,14 +956,14 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTX: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed - Parents: map[string]*SPVEnvelope{ + Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", Target: "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb", @@ -953,7 +977,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", Target: "0994eeb6386321c276177d52be4879ed4f8fedaa942cca6ecf18d66cf08962ef", @@ -973,13 +997,13 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { "envelope with confirmed root errs": { exp: false, expErr: ErrTipTxConfirmed, - blockHeaderFunc: func(context.Context, string) (*BlockHeader, error) { - return EncodeBlockHeaderStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") + blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { + return bc.EncodeBlockHeaderStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") }, - envelope: &SPVEnvelope{ + envelope: &Envelope{ TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", RawTX: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", - Proof: &MerkleProof{ + Proof: &bc.MerkleProof{ Index: 1, TxOrID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", Target: "4f40da9ccedebb65ec7c29e4188ca11461668d7f2ae2e4e35b59b0fe4d266406", @@ -997,7 +1021,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - s, err := NewSPVClient(WithBlockHeaderChain(&mockBlockHeaderClient{ + s, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{ blockHeaderFunc: test.blockHeaderFunc, })) assert.NoError(t, err, "expected no error when creating spv client") @@ -1013,3 +1037,640 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }) } } + +func TestSPVEnvelope_CreateEnvelope(t *testing.T) { + tests := map[string]struct { + tx string + txFunc func(string) (*bt.Tx, error) + mpFunc func(string) (*bc.MerkleProof, error) + exp Envelope + expErr error + }{ + "valid envelope created": { + tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + txFunc: func(txID string) (*bt.Tx, error) { + return nil, fmt.Errorf("this test should be be using txFunc, tx %s", txID) + }, + mpFunc: func(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: Envelope{ + TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", + RawTX: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + Parents: map[string]*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(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(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(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(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(txID string) (*bt.Tx, error) { + return nil, fmt.Errorf("this test should be be using txFunc, tx %s", txID) + }, + mpFunc: func(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(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(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: Envelope{ + TxID: "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759", + RawTX: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + Parents: map[string]*Envelope{ + "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { + TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Proof: &bc.MerkleProof{ + Index: 3, + TxOrID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", + Target: "67641544b6fe809a0037c9683df0983e973c77a7ed1e8eff3b0f8c9b74cd3472", + Nodes: []string{ + "a6d45ccb68a19c05346d3412f78d154d5834380413cbe740ec3550469b487f6e", + }, + }, + }, + "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": { + TxID: "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161", + RawTX: "02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000", + Parents: map[string]*Envelope{ + "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": { + TxID: "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a", + RawTX: "0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000", + Parents: map[string]*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]*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(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(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(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(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"), + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + testTx, err := bt.NewTxFromString(test.tx) + assert.NoError(t, err) + + mock := &mockTXMerkleGetter{ + txGetterFunc: test.txFunc, + mpGetterFunc: test.mpFunc, + } + + spvc, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{}), WithTXGetter(mock), WithMerkleProofGetter(mock)) + assert.NoError(t, err) + + envelope, err := spvc.CreateEnvelope(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/txgetter.go b/spv/txgetter.go new file mode 100644 index 0000000..efe55b1 --- /dev/null +++ b/spv/txgetter.go @@ -0,0 +1,14 @@ +package spv + +import ( + "github.com/libsv/go-bc" + "github.com/libsv/go-bt/v2" +) + +type TXGetter interface { + Tx(txID string) (*bt.Tx, error) +} + +type MerkleProofGetter interface { + MerkleProof(txID string) (*bc.MerkleProof, error) +} diff --git a/verifymerkleproof.go b/spv/verifymerkleproof.go similarity index 94% rename from verifymerkleproof.go rename to spv/verifymerkleproof.go index a485f61..da8f157 100644 --- a/verifymerkleproof.go +++ b/spv/verifymerkleproof.go @@ -1,4 +1,4 @@ -package bc +package spv import ( "context" @@ -6,6 +6,7 @@ import ( "errors" "fmt" + "github.com/libsv/go-bc" "github.com/libsv/go-bt/v2" ) @@ -20,7 +21,7 @@ const ( ) // VerifyMerkleProof verifies a Merkle Proof in standard byte format. -func (spvc *SPVClient) VerifyMerkleProof(ctx context.Context, proof []byte) (valid, isLastInTree bool, err error) { +func (spvc *spvclient) VerifyMerkleProof(ctx context.Context, proof []byte) (valid, isLastInTree bool, err error) { mpb, err := parseBinaryMerkleProof(proof) if err != nil { @@ -58,7 +59,7 @@ func (spvc *SPVClient) VerifyMerkleProof(ctx context.Context, proof []byte) (val case 2: // The `target` field contains a block header var err error - merkleRoot, err = ExtractMerkleRootFromBlockHeader(mpb.target) + merkleRoot, err = bc.ExtractMerkleRootFromBlockHeader(mpb.target) if err != nil { return false, false, err } @@ -87,7 +88,7 @@ func (spvc *SPVClient) VerifyMerkleProof(ctx context.Context, proof []byte) (val } // VerifyMerkleProofJSON verifies a Merkle Proof in standard JSON format. -func (spvc *SPVClient) VerifyMerkleProofJSON(ctx context.Context, proof *MerkleProof) (bool, bool, error) { +func (spvc *spvclient) VerifyMerkleProofJSON(ctx context.Context, proof *bc.MerkleProof) (bool, bool, error) { txid, err := txidFromTxOrID(proof.TxOrID) if err != nil { @@ -111,7 +112,7 @@ func (spvc *SPVClient) VerifyMerkleProofJSON(ctx context.Context, proof *MerkleP } else if proof.TargetType == "header" && len(proof.Target) == 160 { // The `target` field contains a block header var err error - merkleRoot, err = ExtractMerkleRootFromBlockHeader(proof.Target) + merkleRoot, err = bc.ExtractMerkleRootFromBlockHeader(proof.Target) if err != nil { return false, false, err } @@ -168,13 +169,13 @@ func verifyProof(c, merkleRoot string, index uint64, nodes []string) (bool, bool // Calculate the parent node if cIsLeft { // Concatenate left leaf (c) with right leaf (p) - c, err = MerkleTreeParentStr(c, p) + c, err = bc.MerkleTreeParentStr(c, p) if err != nil { return false, false, err } } else { // Concatenate left leaf (p) with right leaf (c) - c, err = MerkleTreeParentStr(p, c) + c, err = bc.MerkleTreeParentStr(p, c) if err != nil { return false, false, err } diff --git a/verifymerkleproof_internal_test.go b/spv/verifymerkleproof_internal_test.go similarity index 95% rename from verifymerkleproof_internal_test.go rename to spv/verifymerkleproof_internal_test.go index d51f90c..a7ff6dd 100644 --- a/verifymerkleproof_internal_test.go +++ b/spv/verifymerkleproof_internal_test.go @@ -1,13 +1,14 @@ -package bc +package spv import ( "testing" + "github.com/libsv/go-bc" "github.com/stretchr/testify/assert" ) func TestParseBinaryMerkleProof(t *testing.T) { - var proofJSON = &MerkleProof{ + var proofJSON = &bc.MerkleProof{ Index: 12, TxOrID: "ffeff11c25cde7c06d407490d81ef4d0db64aad6ab3d14393530701561a465ef", Target: "75edb0a69eb195cdd81e310553aa4d25e18450e08f168532a2c2e9cf447bf169", diff --git a/verifymerkleproof_test.go b/spv/verifymerkleproof_test.go similarity index 93% rename from verifymerkleproof_test.go rename to spv/verifymerkleproof_test.go index 2b5b972..ec6b409 100644 --- a/verifymerkleproof_test.go +++ b/spv/verifymerkleproof_test.go @@ -1,10 +1,11 @@ -package bc_test +package spv_test import ( "context" "testing" "github.com/libsv/go-bc" + "github.com/libsv/go-bc/spv" "github.com/stretchr/testify/assert" ) @@ -31,7 +32,7 @@ func TestVerifyMerkleProof(t *testing.T) { } hcm := &mockBlockHeaderChain{} - spvc, _ := bc.NewSPVClient(bc.WithBlockHeaderChain(hcm)) + spvc, _ := spv.NewClient(spv.WithBlockHeaderChain(hcm)) t.Run("JSON", func(t *testing.T) { valid, isLastInTree, err := spvc.VerifyMerkleProofJSON(context.Background(), proofJSON) diff --git a/spvclient.go b/spvclient.go deleted file mode 100644 index 586b451..0000000 --- a/spvclient.go +++ /dev/null @@ -1,39 +0,0 @@ -package bc - -import ( - "errors" -) - -// An SPVClient is a struct used to specify interfaces -// used to complete Simple Payment Verification (SPV) -// in conjunction with a Merkle Proof. -// -// The implementation of BlockHeaderChain which is supplied will depend on the client -// you are using, some may return a HeaderJSON response others may return the blockhash. -type SPVClient struct { - // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. - bhc BlockHeaderChain -} - -// SPVOpts can be implemented to provided functional options for an SPVClient. -type SPVOpts func(*SPVClient) - -// WithBlockHeaderChain will inject the provided BlockHeaderChain into the SPVClient. -func WithBlockHeaderChain(bhc BlockHeaderChain) SPVOpts { - return func(s *SPVClient) { - s.bhc = bhc - } -} - -// NewSPVClient creates a new SPVClient based on the options provided. -// If no BlockHeaderChain implementation is provided, the setup will return an error. -func NewSPVClient(opts ...SPVOpts) (*SPVClient, error) { - cli := &SPVClient{} - for _, opt := range opts { - opt(cli) - } - if cli.bhc == nil { - return nil, errors.New("at least one blockchain header implementation should be returned") - } - return cli, nil -} From f3117599b73fc517e2750cb837768fd899758f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 16:53:19 +0100 Subject: [PATCH 36/51] added another test --- spv/spvenvelope_test.go | 89 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index 2e445a8..2586441 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -1647,6 +1647,95 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, 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(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(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 { From 21d3148358932bec319d81eb2e7975057ae7de3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 17:00:00 +0100 Subject: [PATCH 37/51] fixed linting --- spv/options.go | 6 ++++-- spv/spvclient.go | 10 ++++++---- spv/spvenvelope_test.go | 6 +++--- spv/txgetter.go | 2 ++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/spv/options.go b/spv/options.go index 13cacb2..7ab887a 100644 --- a/spv/options.go +++ b/spv/options.go @@ -2,22 +2,24 @@ package spv import "github.com/libsv/go-bc" -// SPVOpts can be implemented to provided functional options for an SPVClient. +// ClientOpts can be implemented to provided functional options for an spv.Client. type ClientOpts func(*spvclient) -// WithBlockHeaderChain will inject the provided BlockHeaderChain into the SPVClient. +// WithBlockHeaderChain will inject the provided BlockHeaderChain into the spv.Client func WithBlockHeaderChain(bhc bc.BlockHeaderChain) ClientOpts { return func(s *spvclient) { s.bhc = bhc } } +// WithTXGetter will inject the provided TXGetter into the spv.Client func WithTXGetter(txg TXGetter) ClientOpts { return func(s *spvclient) { s.txg = txg } } +// WithMerkleProofGetter will inject the provided MerkleProofGetter into the spv.Client func WithMerkleProofGetter(mpg MerkleProofGetter) ClientOpts { return func(s *spvclient) { s.mpg = mpg diff --git a/spv/spvclient.go b/spv/spvclient.go index e93d9c1..d5a2d1a 100644 --- a/spv/spvclient.go +++ b/spv/spvclient.go @@ -15,16 +15,18 @@ import ( // The implementation of BlockHeaderChain which is supplied will depend on the client // you are using, some may return a HeaderJSON response others may return the blockhash. type Client interface { - EnvelopeService + EnvelopeHandler MerkleProofVerifier } -type EnvelopeService interface { - EnvelopeBuilder +// EnvelopeHandler interfaces the handling (creation and verification) of SPV Envelopes +type EnvelopeHandler interface { + EnvelopeCreator EnvelopeVerifier } -type EnvelopeBuilder interface { +// EnvelopeCreator interfaces the creation of SPV Envelopes +type EnvelopeCreator interface { CreateEnvelope(*bt.Tx) (*Envelope, error) } diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index 2586441..099d5e4 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -1297,11 +1297,11 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", txFunc: func(txID string) (*bt.Tx, error) { switch txID { - case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": + case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": //nolint:goconst return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") - case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": + case "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": //nolint:goconst return bt.NewTxFromString("0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000") - case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": + case "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": //nolint:goconst return bt.NewTxFromString("0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000") } return nil, fmt.Errorf("tx %s not defined for test", txID) diff --git a/spv/txgetter.go b/spv/txgetter.go index efe55b1..a437418 100644 --- a/spv/txgetter.go +++ b/spv/txgetter.go @@ -5,10 +5,12 @@ import ( "github.com/libsv/go-bt/v2" ) +// TXGetter gets a tx from a provided id type TXGetter interface { Tx(txID string) (*bt.Tx, error) } +// MerkleProofGetter gets a merkle proof for a provided tx id type MerkleProofGetter interface { MerkleProof(txID string) (*bc.MerkleProof, error) } From 4a41429a161e8f1fc7af2fba7d9bfebe80f8c529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 17:05:52 +0100 Subject: [PATCH 38/51] added comment for clarity --- spv/spvenvelope.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index 0ed1b03..2055d37 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -57,6 +57,9 @@ func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { 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 } From 9a107e78dc495a99d8f8115db78b9e7f7b7033fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 17:06:56 +0100 Subject: [PATCH 39/51] removed variable only used once, inlined its creation --- spv/spvenvelope.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index 2055d37..0ecd368 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -48,9 +48,8 @@ type Envelope struct { } func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { - txID := tx.TxID() envelope := &Envelope{ - TxID: txID, + TxID: tx.TxID(), RawTX: tx.String(), Parents: make(map[string]*Envelope), } From cc20c1daa5354ccff2b4c14f5ffeffd8e5447eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 17:11:09 +0100 Subject: [PATCH 40/51] add error for tx with no inputs --- spv/spvenvelope.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index 0ecd368..109214d 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -10,6 +10,9 @@ import ( ) var ( + // ErrNoTxInputs returns if an envelope is attempted to be created from a transaction that has no inputs + ErrNoTxInputs = errors.New("provided tx has no inputs to build envelope from") + // ErrPaymentNotVerified returns if a transaction in the tree provided was missed during verification ErrPaymentNotVerified = errors.New("a tx was missed during validation") @@ -48,6 +51,10 @@ type Envelope struct { } func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { + if len(tx.Inputs) == 0 { + return nil, ErrNoTxInputs + } + envelope := &Envelope{ TxID: tx.TxID(), RawTX: tx.String(), @@ -72,6 +79,8 @@ func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { TxID: pTxID, Proof: mp, } + + // Skip getting the tx data as we have everything we need for verifying the current tx. continue } From aa0654b220d5b92351588604f01221d8b74eb58a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Fri, 20 Aug 2021 17:13:40 +0100 Subject: [PATCH 41/51] change all instances of TX to Tx --- spv/options.go | 4 +- spv/spvclient.go | 2 +- spv/spvenvelope.go | 8 +- spv/spvenvelope_test.go | 198 ++++++++++++++++++++-------------------- spv/txgetter.go | 4 +- 5 files changed, 108 insertions(+), 108 deletions(-) diff --git a/spv/options.go b/spv/options.go index 7ab887a..2ac8aaa 100644 --- a/spv/options.go +++ b/spv/options.go @@ -12,8 +12,8 @@ func WithBlockHeaderChain(bhc bc.BlockHeaderChain) ClientOpts { } } -// WithTXGetter will inject the provided TXGetter into the spv.Client -func WithTXGetter(txg TXGetter) ClientOpts { +// WithTxGetter will inject the provided TxGetter into the spv.Client +func WithTxGetter(txg TxGetter) ClientOpts { return func(s *spvclient) { s.txg = txg } diff --git a/spv/spvclient.go b/spv/spvclient.go index d5a2d1a..4efdbbb 100644 --- a/spv/spvclient.go +++ b/spv/spvclient.go @@ -44,7 +44,7 @@ type MerkleProofVerifier interface { type spvclient struct { // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. bhc bc.BlockHeaderChain - txg TXGetter + txg TxGetter mpg MerkleProofGetter } diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index 109214d..57b9b62 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -44,7 +44,7 @@ var ( // spec at https://tsc.bitcoinassociation.net/standards/spv-envelope/ type Envelope struct { TxID string `json:"txid,omitempty"` - RawTX string `json:"rawTx,omitempty"` + RawTx string `json:"rawTx,omitempty"` Proof *bc.MerkleProof `json:"proof,omitempty"` MapiResponses []bc.MapiCallback `json:"mapiResponses,omitempty"` Parents map[string]*Envelope `json:"parents,omitempty"` @@ -57,7 +57,7 @@ func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { envelope := &Envelope{ TxID: tx.TxID(), - RawTX: tx.String(), + RawTx: tx.String(), Parents: make(map[string]*Envelope), } @@ -152,7 +152,7 @@ func (s *spvclient) verifyTxs(ctx context.Context, payment *Envelope) (bool, err return s.verifyTxAnchor(ctx, payment) } - tx, err := bt.NewTxFromString(payment.RawTX) + tx, err := bt.NewTxFromString(payment.RawTx) if err != nil { return false, err } @@ -198,7 +198,7 @@ func (s *spvclient) verifyUnconfirmedTx(tx *bt.Tx, payment *Envelope) (bool, err return false, ErrNotAllInputsSupplied } - parentTx, err := bt.NewTxFromString(parent.RawTX) + parentTx, err := bt.NewTxFromString(parent.RawTx) if err != nil { return false, err } diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index 099d5e4..bb4d6dc 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -23,12 +23,12 @@ func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash strin return nil, errors.New("blockHeaderFunc in test is undefined") } -type mockTXMerkleGetter struct { +type mockTxMerkleGetter struct { txGetterFunc func(string) (*bt.Tx, error) mpGetterFunc func(string) (*bc.MerkleProof, error) } -func (m *mockTXMerkleGetter) Tx(txID string) (*bt.Tx, error) { +func (m *mockTxMerkleGetter) Tx(txID string) (*bt.Tx, error) { if m.txGetterFunc == nil { return nil, errors.New("txGetterFunc in test is undefined") } @@ -36,7 +36,7 @@ func (m *mockTXMerkleGetter) Tx(txID string) (*bt.Tx, error) { return m.txGetterFunc(txID) } -func (m *mockTXMerkleGetter) MerkleProof(txID string) (*bc.MerkleProof, error) { +func (m *mockTxMerkleGetter) MerkleProof(txID string) (*bc.MerkleProof, error) { if m.txGetterFunc == nil { return nil, errors.New("mpGetterFunc in test is undefined") } @@ -61,10 +61,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -76,7 +76,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", @@ -88,7 +88,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -112,10 +112,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -127,7 +127,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", @@ -139,7 +139,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", }, }, }, @@ -154,10 +154,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", @@ -169,7 +169,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", @@ -181,7 +181,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", @@ -204,10 +204,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -219,7 +219,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", @@ -231,7 +231,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 2, // fails, should be 1 to pass TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -252,11 +252,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs - RawTX: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", + RawTx: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", Parents: map[string]*Envelope{ "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above TxID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -280,10 +280,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -295,7 +295,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx Index: 1, TxOrID: "2e2b706ddede3b8c5e9bd13c684a0678072b11898770167c7ce569095d386df5", @@ -306,7 +306,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -330,10 +330,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -345,7 +345,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ // Valid merkle proof but for different tx Index: 1, TxOrID: "0200000001e6512113175679cc5c78d637b0934e2e09bcd0d6a6693c11a372c0effd055ebf010000006a47304402200bf8ddd45e87d187740d1500451f54e24933be6d4cb188b2d8c300895ffe1c5e02207f82e9c9e97387cd5341a51d10e06455a21fcb53ffb5ba006ef91a2ab3dc4383412102ac939508911a1266ea64a30f6d3f2b311527c379087deca7171700e0369ecfa9feffffff0294cef008000000001976a9144cd75969d2baa7b0e5eab0d52f6555496799033088ac00e1f505000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac6a000000", @@ -356,7 +356,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -380,10 +380,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed + RawTx: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -395,7 +395,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", @@ -407,7 +407,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -431,10 +431,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", - RawTX: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0020000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // tx.Input[0].PreviousTxOutIndex has been changed from 1, to 2, leaving it out of bounds + RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0020000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // tx.Input[0].PreviousTxOutIndex has been changed from 1, to 2, leaving it out of bounds Parents: map[string]*Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { - RawTX: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -446,7 +446,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200": { - RawTX: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", + RawTx: "02000000019d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398010000006a4730440220275765312856c55c2b356378e7fe5cceb7dee7b5ac2a9d742898e6278b58f499022062eb4fd3d4071fea9f1e07bee5e59a096d63243cb7c5d003f722728d2441d45f41210348e077b6424414cfd6fce6401f99d56888798e02bd3d660d350683f679b232a6feffffff025e266bee000000001976a9142ae11994c6afce7093979ff29da86cf60f5b324f88ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "209cc8e71a0b2ae900b6a8f2e225acd9040c537c558fc94ff67be2479abb9200", @@ -458,7 +458,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { - RawTX: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", + RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", @@ -484,19 +484,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -509,7 +509,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", @@ -521,15 +521,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -543,7 +543,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", @@ -574,19 +574,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -599,7 +599,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", @@ -611,15 +611,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 2, // failure here, should be 1 to pass TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -633,7 +633,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", @@ -665,19 +665,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -690,7 +690,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", @@ -702,15 +702,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -722,7 +722,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, }, - // TX missing here, b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f + // Tx missing here, b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f }, }, }, @@ -744,19 +744,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -769,7 +769,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &bc.MerkleProof{ // This Merkle Proof is valid, it is just for a different tx. Index: 2, TxOrID: "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9", @@ -781,15 +781,15 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -803,7 +803,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", @@ -835,19 +835,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -860,7 +860,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", @@ -872,21 +872,21 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", Parents: map[string]*Envelope{ // This tx is missing its proof "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", }, }, }, "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", @@ -918,19 +918,19 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", - RawTX: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", + RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", Parents: map[string]*Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", - RawTX: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", + RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", Parents: map[string]*Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", - RawTX: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", + RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -943,7 +943,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846": { - RawTX: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000018d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b000000006b483045022100b3dbaf3220e93da741281f37b5b0e9de6ccd94ed83d1018a392c4fa52c1ad87102205b0d1457fa6c7735f245268e7edba7aa82bcd7dc5e75c5431f5eecac2e8469c94121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff021ec1eb0b000000001976a91462648339696b5c356d4c7c1af83665f703fa825488ac00c2eb0b000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "e29628f3eeb9881f92336285ea3bd0fc18a98f25cdc950a92af320795d7a9846", @@ -955,14 +955,14 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { - RawTX: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", + RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", Parents: map[string]*Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", - RawTX: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed + RawTx: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed Parents: map[string]*Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { - RawTX: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", + RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", @@ -976,7 +976,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f": { TxID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", - RawTX: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", + RawTx: "02000000017f4c917d890cccbf43eea8aca54e611e2e0fc2b49807182b3133992500b8ea23010000006b483045022100f03327c2c9d1a741154b7b1bd2aa563c5195554560ecd1da7e34a4f76b8594fc022058a7fa5dc02c9efd78afbf3b2207ee4b6b0f551c776308e4981ba13b38140608412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a914f4e16f9a16f7575ae58d164cbef7ebb5393141d688ac67000000", Proof: &bc.MerkleProof{ Index: 2, TxOrID: "b0b9a74ff8a14e0f8aa751047f192b62f38c7f8798449b286153d36238f2f04f", @@ -1002,7 +1002,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, envelope: &Envelope{ TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", - RawTX: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", + RawTx: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", Proof: &bc.MerkleProof{ Index: 1, TxOrID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", @@ -1103,7 +1103,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, exp: Envelope{ TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", - RawTX: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", Parents: map[string]*Envelope{ "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", @@ -1379,7 +1379,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, exp: Envelope{ TxID: "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759", - RawTX: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", + RawTx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", Parents: map[string]*Envelope{ "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", @@ -1394,11 +1394,11 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": { TxID: "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161", - RawTX: "02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000", + RawTx: "02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000", Parents: map[string]*Envelope{ "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": { TxID: "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a", - RawTX: "0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000", + RawTx: "0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000", Parents: map[string]*Envelope{ "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { TxID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", @@ -1426,7 +1426,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": { TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", - RawTX: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", + RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", Parents: map[string]*Envelope{ "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", @@ -1743,12 +1743,12 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { testTx, err := bt.NewTxFromString(test.tx) assert.NoError(t, err) - mock := &mockTXMerkleGetter{ + mock := &mockTxMerkleGetter{ txGetterFunc: test.txFunc, mpGetterFunc: test.mpFunc, } - spvc, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{}), WithTXGetter(mock), WithMerkleProofGetter(mock)) + spvc, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{}), WithTxGetter(mock), WithMerkleProofGetter(mock)) assert.NoError(t, err) envelope, err := spvc.CreateEnvelope(testTx) diff --git a/spv/txgetter.go b/spv/txgetter.go index a437418..9d4808f 100644 --- a/spv/txgetter.go +++ b/spv/txgetter.go @@ -5,8 +5,8 @@ import ( "github.com/libsv/go-bt/v2" ) -// TXGetter gets a tx from a provided id -type TXGetter interface { +// TxGetter gets a tx from a provided id +type TxGetter interface { Tx(txID string) (*bt.Tx, error) } From ef6c08922be08dd90733b3eb0ae7eaf44906022e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Mon, 23 Aug 2021 10:29:56 +0100 Subject: [PATCH 42/51] small refactor of files and interface names --- spv/interfaces.go | 51 +++++++++++++++++++++++++++++++++++++++++ spv/options.go | 8 +++---- spv/spvclient.go | 39 ++----------------------------- spv/spvenvelope_test.go | 18 +++++++-------- spv/txgetter.go | 16 ------------- 5 files changed, 66 insertions(+), 66 deletions(-) create mode 100644 spv/interfaces.go delete mode 100644 spv/txgetter.go diff --git a/spv/interfaces.go b/spv/interfaces.go new file mode 100644 index 0000000..830fdf9 --- /dev/null +++ b/spv/interfaces.go @@ -0,0 +1,51 @@ +package spv + +import ( + "context" + + "github.com/libsv/go-bc" + "github.com/libsv/go-bt/v2" +) + +// An Client is a struct used to specify interfaces +// used to complete Simple Payment Verification (SPV) +// in conjunction with a Merkle Proof. +// +// The implementation of BlockHeaderChain which is supplied will depend on the client +// you are using, some may return a HeaderJSON response others may return the blockhash. +type Client interface { + EnvelopeHandler + MerkleProofVerifier +} + +// EnvelopeHandler interfaces the handling (creation and verification) of SPV Envelopes +type EnvelopeHandler interface { + EnvelopeCreator + EnvelopeVerifier +} + +// EnvelopeCreator interfaces the creation of SPV Envelopes +type EnvelopeCreator interface { + CreateEnvelope(*bt.Tx) (*Envelope, error) +} + +// EnvelopeVerifier interfaces the verification of SPV Envelopes +type EnvelopeVerifier interface { + VerifyPayment(context.Context, *Envelope) (bool, error) +} + +// MerkleProofVerifier interfaces the verification of Merkle Proofs +type MerkleProofVerifier interface { + VerifyMerkleProof(context.Context, []byte) (bool, bool, error) + VerifyMerkleProofJSON(context.Context, *bc.MerkleProof) (bool, bool, error) +} + +// TxStore interfaces the a tx store +type TxStore interface { + Tx(txID string) (*bt.Tx, error) +} + +// MerkleProofStore interfaces a Merkle Proof store +type MerkleProofStore interface { + MerkleProof(txID string) (*bc.MerkleProof, error) +} diff --git a/spv/options.go b/spv/options.go index 2ac8aaa..a11eb38 100644 --- a/spv/options.go +++ b/spv/options.go @@ -12,15 +12,15 @@ func WithBlockHeaderChain(bhc bc.BlockHeaderChain) ClientOpts { } } -// WithTxGetter will inject the provided TxGetter into the spv.Client -func WithTxGetter(txg TxGetter) ClientOpts { +// WithTxStore will inject the provided TxGetter into the spv.Client +func WithTxStore(txg TxStore) ClientOpts { return func(s *spvclient) { s.txg = txg } } -// WithMerkleProofGetter will inject the provided MerkleProofGetter into the spv.Client -func WithMerkleProofGetter(mpg MerkleProofGetter) ClientOpts { +// WithMerkleProofStore will inject the provided MerkleProofGetter into the spv.Client +func WithMerkleProofStore(mpg MerkleProofStore) ClientOpts { return func(s *spvclient) { s.mpg = mpg } diff --git a/spv/spvclient.go b/spv/spvclient.go index 4efdbbb..7e4e3ae 100644 --- a/spv/spvclient.go +++ b/spv/spvclient.go @@ -1,51 +1,16 @@ package spv import ( - "context" "errors" "github.com/libsv/go-bc" - "github.com/libsv/go-bt/v2" ) -// An Client is a struct used to specify interfaces -// used to complete Simple Payment Verification (SPV) -// in conjunction with a Merkle Proof. -// -// The implementation of BlockHeaderChain which is supplied will depend on the client -// you are using, some may return a HeaderJSON response others may return the blockhash. -type Client interface { - EnvelopeHandler - MerkleProofVerifier -} - -// EnvelopeHandler interfaces the handling (creation and verification) of SPV Envelopes -type EnvelopeHandler interface { - EnvelopeCreator - EnvelopeVerifier -} - -// EnvelopeCreator interfaces the creation of SPV Envelopes -type EnvelopeCreator interface { - CreateEnvelope(*bt.Tx) (*Envelope, error) -} - -// EnvelopeVerifier interfaces the verification of SPV Envelopes -type EnvelopeVerifier interface { - VerifyPayment(context.Context, *Envelope) (bool, error) -} - -// MerkleProofVerifier interfaces the verification of Merkle Proofs -type MerkleProofVerifier interface { - VerifyMerkleProof(context.Context, []byte) (bool, bool, error) - VerifyMerkleProofJSON(context.Context, *bc.MerkleProof) (bool, bool, error) -} - type spvclient struct { // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. bhc bc.BlockHeaderChain - txg TxGetter - mpg MerkleProofGetter + txg TxStore + mpg MerkleProofStore } // NewClient creates a new spv.Client based on the options provided. diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index bb4d6dc..4811fb0 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -24,24 +24,24 @@ func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash strin } type mockTxMerkleGetter struct { - txGetterFunc func(string) (*bt.Tx, error) - mpGetterFunc func(string) (*bc.MerkleProof, error) + txStoreFunc func(string) (*bt.Tx, error) + mpStoreFunc func(string) (*bc.MerkleProof, error) } func (m *mockTxMerkleGetter) Tx(txID string) (*bt.Tx, error) { - if m.txGetterFunc == nil { + if m.txStoreFunc == nil { return nil, errors.New("txGetterFunc in test is undefined") } - return m.txGetterFunc(txID) + return m.txStoreFunc(txID) } func (m *mockTxMerkleGetter) MerkleProof(txID string) (*bc.MerkleProof, error) { - if m.txGetterFunc == nil { + if m.txStoreFunc == nil { return nil, errors.New("mpGetterFunc in test is undefined") } - return m.mpGetterFunc(txID) + return m.mpStoreFunc(txID) } func TestSPVEnvelope_VerifyPayment(t *testing.T) { @@ -1744,11 +1744,11 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { assert.NoError(t, err) mock := &mockTxMerkleGetter{ - txGetterFunc: test.txFunc, - mpGetterFunc: test.mpFunc, + txStoreFunc: test.txFunc, + mpStoreFunc: test.mpFunc, } - spvc, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{}), WithTxGetter(mock), WithMerkleProofGetter(mock)) + spvc, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{}), WithTxStore(mock), WithMerkleProofStore(mock)) assert.NoError(t, err) envelope, err := spvc.CreateEnvelope(testTx) diff --git a/spv/txgetter.go b/spv/txgetter.go deleted file mode 100644 index 9d4808f..0000000 --- a/spv/txgetter.go +++ /dev/null @@ -1,16 +0,0 @@ -package spv - -import ( - "github.com/libsv/go-bc" - "github.com/libsv/go-bt/v2" -) - -// TxGetter gets a tx from a provided id -type TxGetter interface { - Tx(txID string) (*bt.Tx, error) -} - -// MerkleProofGetter gets a merkle proof for a provided tx id -type MerkleProofGetter interface { - MerkleProof(txID string) (*bc.MerkleProof, error) -} From 8c7aa33b4ccd28dd89c638678c46998aaa7aaeef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 10:21:22 +0100 Subject: [PATCH 43/51] updated EncodeBlokcHeaderStr to NewBlockHeaderFromStr --- spv/spvenvelope_test.go | 72 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index 4811fb0..5f2d5e9 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -55,9 +55,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { //nolint:goconst - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -106,9 +106,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrNoConfirmedTransaction, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -148,9 +148,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: true, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -198,9 +198,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: false, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -248,7 +248,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: false, expErr: ErrNotAllInputsSupplied, blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") }, envelope: &Envelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs @@ -274,9 +274,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrTxIDMismatch, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -324,9 +324,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrTxIDMismatch, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -374,9 +374,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrNoTxInputsToVerify, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -425,9 +425,9 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { expErr: ErrInputRefsOutOfBoundsOutput, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { if blockHash == "4100429a6a29fd8ddf480f124f02557df39d9d58a671c9ea0a8f1fcc8ace923f" { - return bc.EncodeBlockHeaderStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") + return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") } - return bc.EncodeBlockHeaderStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, envelope: &Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", @@ -476,11 +476,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": //nolint:goconst - return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": //nolint:goconst - return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", @@ -566,11 +566,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", @@ -657,11 +657,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", @@ -736,11 +736,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", @@ -827,11 +827,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", @@ -910,11 +910,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": - return bc.EncodeBlockHeaderStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000209f42742eb51d06c40a42b443888eca5030ca0dbae77e34e47b145c2255608a2d43d011ecd04a8989b4cae204bf1bc5ff15d87a62b356d899ca9d0361c946d671aaf61361ffff7f2000000000") case "730548cc946deba119fcee6ab2415bbb5fd8e0b41c9c0d5cae1ab069f905f56d": - return bc.EncodeBlockHeaderStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") + return bc.NewBlockHeaderFromStr("00000020ef6289f06cd618cf6eca2c94aaed8f4fed7948be527d1776c2216338b6ee940949d8b42d929d966f8e10ec2e47af5f87a39c5b09b9bac8ff6375ac9a8612614408f71361ffff7f2002000000") } - return bc.EncodeBlockHeaderStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") + return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, envelope: &Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", @@ -998,7 +998,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { exp: false, expErr: ErrTipTxConfirmed, blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { - return bc.EncodeBlockHeaderStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") + return bc.NewBlockHeaderFromStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") }, envelope: &Envelope{ TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", From 2101b30eca66480cb1d078ea93f89a9f12b9d450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 10:27:28 +0100 Subject: [PATCH 44/51] moved tests to spv_test package --- spv/spvenvelope_test.go | 159 ++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index 5f2d5e9..29855f4 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -1,4 +1,4 @@ -package spv +package spv_test import ( "context" @@ -7,6 +7,7 @@ import ( "testing" "github.com/libsv/go-bc" + "github.com/libsv/go-bc/spv" "github.com/libsv/go-bt/v2" "github.com/stretchr/testify/assert" ) @@ -46,7 +47,7 @@ func (m *mockTxMerkleGetter) MerkleProof(txID string) (*bc.MerkleProof, error) { func TestSPVEnvelope_VerifyPayment(t *testing.T) { tests := map[string]struct { - envelope *Envelope + envelope *spv.Envelope blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) exp bool expErr error @@ -59,10 +60,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -103,17 +104,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "envelope without any proof fails": { exp: false, - expErr: ErrNoConfirmedTransaction, + 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: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -152,10 +153,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -202,10 +203,10 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000203f92ce8acc1f8f0aeac971a6589d9df37d55024f120f48df8dfd296a9a4200413ca2ca1e79b3a8ff441a9d89feaa39b9771a30032a30fb023894ea4618395611f2ef1361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -246,14 +247,14 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong tx supplied as input in envelope errs": { exp: false, - expErr: ErrNotAllInputsSupplied, + expErr: spv.ErrNotAllInputsSupplied, blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { return bc.NewBlockHeaderFromStr("0000002092df08285c865746bd933a0a97bda382cbc3ad1cbf7d3c8957c24e55eaba652dfc6f46aebb62fe9004ffa1e91b0ab37d1a865454a151e6011ce50751d33b40d7e1ef1361ffff7f2001000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "e3c66e4eddaa7e7e7560cdd8a80c82126dcbb728b4a3bf48a2be95a7847feacc", // different tx with different inputs RawTx: "02000000043324273707a2a5da452461d0e4f02b2bec2f87a134fe10cd04a6a8b77978d11c000000006b483045022100a1e96789f10de15167385eb1f7505628755aa43750ed0df998066d1b6526a5fe02205883662a7c231509ab233026a9bd7dac1221fcfd22cf92c543ce761588ead52b4121029312d305d805dcbf68a0ffaee417a4852d86ce38708725feff2b1a85db53cc59feffffff0f316367b51170c4c80a4285a3f47712efc4b47b56e736a284aa38bd0e1ec9d4000000006a47304402205d7100dd0bcc901507e84cd94e88da90973fd8381eeec24bdc84e70519604b0c02207bb9eacd817eb04378655a32807f3e76d5ed65cff147fac659db270699b44ef5412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505000000006a4730440220255e048d53f6e3897ea1adebe3ce09259ec8f4814939091a0ff93d754c2f508d02201cbda92db5f25b62363dbf744e6a4b82ec3eb9a9a075d08d8051c9729021d69f4121033e792b95ce7a8c70f68ae6070d5b545957343919fab8b0cb4d6915b6117477d3fefffffffadf675b2205f8382155091cf046ed63a543734f3c5344d92b7c067bd987f505010000006b483045022100ff091628f91fbb9ceda9cd62747e570508f95d14205211288071bd3ae4a4500c0220080dba7b1b9379b21c1bd5fed22f582094b54fdb29c16cfe4de3f709d12975e4412103792d3c6e2bb718a515bc8fa8250d92a548ebe94be39a5676ad5bdcfc5c3dd17ffeffffff029ee8fa02000000001976a9146922fe7841288aa0d71292cb8325c4205e4674d288ac8055c820000000001976a914e4e6936b51ecbe715846556b083747bae09e769088ac6b000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d": { // incorrect input for tx above TxID: "98f3d952b09fc9a84acaaf21aaeaf81b0fc6b614a60c83a0202469fa54450d9d", RawTx: "02000000019ec3e27254fd093e5dc3fd18bb5a9bfba9f8b47d9c8810fdea65eff0d92311c3000000004847304402201fa52e3d8df160d932a9835707a2873c370f8a68a0216f7dd4c8e1dabb3d2eae022032dfe07c2e106708f1868f048d25707446073b362b3b582df536b2f052b41bff41feffffff020065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac408c380c010000001976a91400604c1038e008c2c08448c8c86cd64db1dc53d688ac65000000", @@ -271,17 +272,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof supplied with otherwise correct input errors": { exp: false, - expErr: ErrTxIDMismatch, + 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: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -321,17 +322,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof supplied via hex with otherwise correct input errors": { exp: false, - expErr: ErrTxIDMismatch, + 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: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "0200000003a9bc457fdc6a54d99300fb137b23714d860c350a9d19ff0f571e694a419ff3a0010000006b48304502210086c83beb2b2663e4709a583d261d75be538aedcafa7766bd983e5c8db2f8b2fc02201a88b178624ab0ad1748b37c875f885930166237c88f5af78ee4e61d337f935f412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff0092bb9a47e27bf64fc98f557c530c04d9ac25e2f2a8b600e92a0b1ae7c89c20010000006b483045022100f06b3db1c0a11af348401f9cebe10ae2659d6e766a9dcd9e3a04690ba10a160f02203f7fbd7dfcfc70863aface1a306fcc91bbadf6bc884c21a55ef0d32bd6b088c8412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff9d0d4554fa692420a0830ca614b6c60f1bf8eaaa21afca4aa8c99fb052d9f398000000006b483045022100d920f2290548e92a6235f8b2513b7f693a64a0d3fa699f81a034f4b4608ff82f0220767d7d98025aff3c7bd5f2a66aab6a824f5990392e6489aae1e1ae3472d8dffb412103e8be830d98bb3b007a0343ee5c36daa48796ae8bb57946b1e87378ad6e8a090dfeffffff02807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -371,17 +372,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "envelope with tx no inputs errs": { exp: false, - expErr: ErrNoTxInputsToVerify, + 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: &Envelope{ + envelope: &spv.Envelope{ TxID: "bf5e05fdefc072a3113c69a6d6d0bc092e4e93b037d6785ccc795617132151e6", RawTx: "020000000002807c814a000000001976a9143a6bf34ebfcf30e8541bbb33a7882845e5a29cb488ac76b0e60e000000001976a914bd492b67f90cb85918494767ebb23102c4f06b7088ac67000000", // This tx has had its inputs removed - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -422,17 +423,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "tx with input indexing out of bounds output errors": { exp: false, - expErr: ErrInputRefsOutOfBoundsOutput, + 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: &Envelope{ + 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]*Envelope{ + Parents: map[string]*spv.Envelope{ "a0f39f414a691e570fff199d0a350c864d71237b13fb0093d9546adc7f45bca9": { RawTx: "0200000001424408c9d997772e56112c731b6dc6f050cb3847c5570cea12f30bfbc7df0a010000000049483045022100fe759b2cd7f25bce4fcda4c8366891b0d9289dc5bac1cf216909c89dc324437a02204aa590b6e82764971df4fe741adf41ece4cde607cb6443edceba831060213d3641feffffff02408c380c010000001976a914f761fc0927a43f4fab5740ef39f05b1fb7786f5288ac0065cd1d000000001976a914805096c5167877a5799977d46fb9dee5891dc3cb88ac66000000", Proof: &bc.MerkleProof{ @@ -482,18 +483,18 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -522,11 +523,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -572,18 +573,18 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -612,11 +613,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -653,7 +654,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "tx with input missing from envelope parents errors": { exp: false, - expErr: ErrNotAllInputsSupplied, + expErr: spv.ErrNotAllInputsSupplied, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": @@ -663,18 +664,18 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -703,11 +704,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -732,7 +733,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "wrong merkle proof suppled with otherwise correct layered input errors": { exp: false, - expErr: ErrTxIDMismatch, + expErr: spv.ErrTxIDMismatch, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": @@ -742,18 +743,18 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -782,11 +783,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -823,7 +824,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "single missing merkle proof in layered and branching tx errors": { exp: false, - expErr: ErrNoConfirmedTransaction, + expErr: spv.ErrNoConfirmedTransaction, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": @@ -833,18 +834,18 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -873,11 +874,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba010000006b483045022100c5b05cdd247250e999d4ad8775f7dc25aec52dd84aaeee7a5d8f51bc48c7f70e02206759afc0cc53b13332d0698763ad84ea896355caccfcb9d76d128302a516e3be412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", - Parents: map[string]*Envelope{ // This tx is missing its proof + Parents: map[string]*spv.Envelope{ // This tx is missing its proof "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -906,7 +907,7 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "tx with no inputs in multiple layer tx fails": { exp: false, - expErr: ErrNoTxInputsToVerify, + expErr: spv.ErrNoTxInputsToVerify, blockHeaderFunc: func(ctx context.Context, blockHash string) (*bc.BlockHeader, error) { switch blockHash { case "4f35d06cd4d00dcba92ade34b4c507c2939d3d1393f490a370c5f4239050dbcb": @@ -916,18 +917,18 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { } return bc.NewBlockHeaderFromStr("000000208aef5325a07e4ec9cca864fca51e14d050d9fb9a371be6c651549580a0e33476414a38a7ddb819a4f3011cd06b17877968100a819348edb2009a60d0e0a65294fdf61361ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "8215a2c96d24cda0875c0a33ad1b3679967e08888e6b881b59fdf1451801b638", RawTx: "0200000001562f61cae886f8b21aaab9232f5f6ccf686e5d3bcc3618f2f4774e8e5eef07e5010000006b483045022100d7553b086257063155b42ffe153d3746755c2bcb61e77fbb5f81cea67c3f1e6b0220720edd3314b1c963ffad5da5b0938a30e990fe6aa4847547dbe72bcded6b50be4121024099fd16bc2f0b3b0682f9f1233d19d88a965c57577e15ab519fcde8dead2314feffffff021ea2e111000000001976a91450f59fc52e5147638e289870c99da80215435bef88ac00ca9a3b000000001976a9143ccdeface30a9b991f00ade4da00e1e55b9d177c88ac6a000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56": { TxID: "e507ef5e8e4e77f4f21836cc3b5d6e68cf6c5f2f23b9aa1ab2f886e8ca612f56", RawTx: "020000000532bc3895b35a4d7b2da0103589a320e4eabeed08ef9777481b6f2475c0cf0084010000006a47304402206579610b3a845e7ffa58203c686ca86ed3f2f946454bcb5f78e960c8ec34617702206cf0f168267acbca0acdc7fe38311fd94fd821868891aa1da150fe0de6e0ff6c412103bb0164c11476e32287120301be5aca1310b0f72579f83e88cf6e10e42f6f78f1feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2000000006a47304402201cd57a7064c100bb7e565a9aeff12bfe4397d59bd3d44a89115f97e2bd04669e022020cba46c8ab99a763c983f7fb10d61875495af0d6f42e3dfe010b843cb9c0ceb4121033288af9d515600042c64a8a058e80ad0a70f885ab4fc2424da847b18b74335e8feffffff46987a5d7920f32aa950c9cd258fa918fcd03bea856233921f88b9eef32896e2010000006a473044022022ce6618dca7e4d38455f327987f43f1ea127081e51375efe311e310b309aaed0220397f92dcebca00027adcfc11231b490125299ce71c38ff18c096d2272354b85f4121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a000000006a47304402201a4a9c14879acdbde902d6ec27c680f6bbf7c399296b0da31eaaad896dd0451b02201defdcc8514d8fea8425bc18406adf23f4957c218c0f321b9db3850f0b16884e412102a4b2aabf9cbfb9031de4f00d1997f10fe232e7e344b7ceb39e382be9b2e5002dfeffffff910084749909b991b60ff63962ba5f01f2fd30e155f5f5776e694a14eb58e76a010000006a47304402200fe83fbb8c1055190395bf46f8e1521670b1da12680950ea7b40ef5ad02ab7ac02205794d2fba2353cf6e8c9372b9e8900fa40fb5574880be5b455d6927b28fcbfc24121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff0294daf505000000001976a914a12a69314c08a5155d779a2ec247ea735ade23bd88ac006d7c4d000000001976a9146dbb06e4c0395ffdec982856beab28994a548dce88ac69000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32": { TxID: "8400cfc075246f1b487797ef08edbeeae420a3893510a02d7b4d5ab39538bc32", RawTx: "02000000016fc96646b49acbe283ca81813da5ce0cf6b34a79dda74d515eaf68236ac7e2ba000000006a47304402205c1a6ba8018fa5d8c8952d37e4e21b731ac09edb491a2f475133021e348a1e5c02205acba3d90d31738a192593b66940ca119fd7a2e018c198b28d432db68e182034412103e72d6d9988b7fffcdef654e3c40c1227539b90a89dc5f42cd3d850e74ad94503feffffff025e266bee000000001976a9143355c640863b680e977d3608075ee5749f98106188ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac66000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { TxID: "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f", RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", @@ -956,11 +957,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "6ae758eb144a696e77f5f555e130fdf2015fba6239f60fb691b9099974840091": { RawTx: "02000000028d6e14c6886d0e2c033d59a5a2134e167baae7acbaac407b83d90adcaafb358b010000006a473044022008866e2f23b6b2776a03e334a56e2ca887fffa645e7c89d2ac1e7f3bcdcdce29022006bf62917a43afa8c83e5ec2e60526617d13c98cbe6b72795ce748a8a27992914121035c376280173a08084341033731fb5dd22ffa7a726246044c451d137accbeed7afeffffff4ff0f23862d35361289b4498877f8cf3622b197f0451a78a0f4ea1f84fa7b9b0000000006a47304402205db48d1753b80fcf143f5908e2c969d718b62b7ed5af9737a3a86862e323b4e30220499c23aad7140391deb0a4dbdbb81f7bf3f8f8588dea3fbe9217552519ceaef14121034a4a9529513993c0c4f44a011b0e53180e6ebace7791abfd0e291f6c4aeccef8feffffff02a8def505000000001976a914d780641a06296af4a112e02ae80241688ecd058b88ac0084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac68000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d": { TxID: "8b35fbaadc0ad9837b40acbaace7aa7b164e13a2a5593d032c0e6d88c6146e8d", RawTx: "0200000000020084d717000000001976a91449804e4836f00185ccca0a9a96d0c937fdfbc31e88ac1ee0f505000000001976a9141a4eb2adab4b71d8f55aeff3b663dc9e6c12b93f88ac67000000", // This tx has had its inputs removed - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "bae2c76a2368af5e514da7dd794ab3f60ccea53d8181ca83e2cb9ab44666c96f": { RawTx: "0200000001159b1c81cbbc5de005cb5a8f86cafb6b9c0b8b1473cfac99c2d0488029aa2a25000000004847304402202935d7a85c928eb4a3b4a08a6e4713d3b2142c0e16a171322bd7612c7ff8e8f002201b08f62484217b669cc9c25b8172647e5d56b2a54edd67427608ff2ecd00cf6b41feffffff02408c380c010000001976a91463fe2b8cb4ef7a8b01cc3388ce26ef74b8a5c42588ac0065cd1d000000001976a914a0416fb58b878bfaede66f83bb0e8c9fe0b0619c88ac65000000", Proof: &bc.MerkleProof{ @@ -996,11 +997,11 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "envelope with confirmed root errs": { exp: false, - expErr: ErrTipTxConfirmed, + expErr: spv.ErrTipTxConfirmed, blockHeaderFunc: func(context.Context, string) (*bc.BlockHeader, error) { return bc.NewBlockHeaderFromStr("00000020f274078cebf6b61dd94b2124d9e967f7a7b9ccf0e95f46535768e333295b1e0633c974e51079022676c9319cd1cabcbf033282934f2d4fb4846ee6521d652e51fc680161ffff7f2000000000") }, - envelope: &Envelope{ + envelope: &spv.Envelope{ TxID: "06894e08c0e4137d70274c538351f5cea2e82011fafb3cc0192c74447dda19fd", RawTx: "0200000002f16ba9c4f21683b6840400418d4a0d27422e410e4cd398e4c64941363072ce5b000000006b4830450221009d2e7e89c0e0545ff0906cbc47060d0a74ee08948691180f59d9171ced24601a02202566505eaa97b4fb54830e33bb41a644e5d4c16b9d59ac1a61c45836da2961df412102b6dd19e32923d694ee510aa73e2eedf437783fce648b7b53effe31bfa6fee724feffffffb037e485154b5ae41f7cf229d519cd28b8d0f41f2f195309b8794cea95965116000000006a4730440220117995a5050437e1fd3866af61bb53f637fafcd051fcebcc9f40cc72cd40b395022036694fabae9720b03ecce1bf8d9d28e58123bfeb28a79814d95904e754c424634121028300e674b820a0f0df1c3399e9ef26dbca6ca1fdd9a4c53e5dbc964dcc6f2111feffffff0280ddf505000000001976a9149e5408eb250a1f9980ec735765dec14407c195ec88ac00ca9a3b000000001976a9146e8f17ecfc40ef5b429d22c86ffe8acb2acc886988acda000000", Proof: &bc.MerkleProof{ @@ -1015,13 +1016,13 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { }, "nil initial payment errors": { exp: false, - expErr: ErrNilInitialPayment, + expErr: spv.ErrNilInitialPayment, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - s, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{ + s, err := spv.NewClient(spv.WithBlockHeaderChain(&mockBlockHeaderClient{ blockHeaderFunc: test.blockHeaderFunc, })) assert.NoError(t, err, "expected no error when creating spv client") @@ -1043,7 +1044,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { tx string txFunc func(string) (*bt.Tx, error) mpFunc func(string) (*bc.MerkleProof, error) - exp Envelope + exp spv.Envelope expErr error }{ "valid envelope created": { @@ -1101,10 +1102,10 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { return mp, nil }, - exp: Envelope{ + exp: spv.Envelope{ TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", Proof: &bc.MerkleProof{ @@ -1377,10 +1378,10 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { return mp, nil }, - exp: Envelope{ + exp: spv.Envelope{ TxID: "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759", RawTx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc": { TxID: "d485a772e2cf0ea5616a32ee04e95a8cfa1dfac4750607f1cdafc3f1a88ad6bc", Proof: &bc.MerkleProof{ @@ -1395,11 +1396,11 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": { TxID: "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161", RawTx: "02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a": { TxID: "eb48e1fa1e939a24a8529215052ec02dc0afad7d331789494be61ee2758d4c0a", RawTx: "0200000003923b8561e34c743ec4e736973f99b4d99d6a6a779d85a29a1f900af435467257010000006b483045022100b3bb6382590f35ce3eeccf3e4e6cc575b2d0f47a5cfb333c77df4ef276cbaa8c022059040d6ce37292f10d7b70feb96d28784d701ca12d0d26adf149400c47e77128412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffbcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4000000006a473044022077eca6d671d07a19c622cf88cb421787e5a11ba3a4a537e00c74be8491966b84022035279d55889a163b53d029e8e65f3430756a59293208cdf371692bc1120276c6412103c2db1771958c949a26ba221dd048dd387f95ea5d761805bbb8c6cd2d1ed22a6afeffffff844ce271fb05ce083807cc48dc418d35604f2319946346c92d0705fb6bc21ebd000000006a47304402207a1814eefee55e9ee17653b7122cf6352be8d204ce51ecc9b92efa628295e24202200be4daba99d3a01681d74049eca3f256e523ad9d5bb71718409add4b3961417e4121038eae2a1e8fcf7f43788366ce0c5a39753e14bd561b92121306071abf5f5b34bcfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac0ad5f505000000001976a914e361cafbc05a5596fe4378879230000aa28990b088ac6c000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92": { TxID: "57724635f40a901f9aa2859d776a6a9dd9b4993f9736e7c43e744ce361853b92", Proof: &bc.MerkleProof{ @@ -1427,7 +1428,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": { TxID: "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84", RawTx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - Parents: map[string]*Envelope{ + Parents: map[string]*spv.Envelope{ "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { TxID: "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb", Proof: &bc.MerkleProof{ @@ -1748,7 +1749,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { mpStoreFunc: test.mpFunc, } - spvc, err := NewClient(WithBlockHeaderChain(&mockBlockHeaderClient{}), WithTxStore(mock), WithMerkleProofStore(mock)) + spvc, err := spv.NewClient(spv.WithBlockHeaderChain(&mockBlockHeaderClient{}), spv.WithTxStore(mock), spv.WithMerkleProofStore(mock)) assert.NoError(t, err) envelope, err := spvc.CreateEnvelope(testTx) From f04c3a26ad7474ba7124b0a613df8f0f347274aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 11:07:47 +0100 Subject: [PATCH 45/51] added godoc comment to CreateEnvelope --- spv/spvenvelope.go | 1 + 1 file changed, 1 insertion(+) diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index 57b9b62..f6c66a5 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -50,6 +50,7 @@ type Envelope struct { Parents map[string]*Envelope `json:"parents,omitempty"` } +// CreateEnvelope builds and returns an spv.Envelope for the provided tx. func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { if len(tx.Inputs) == 0 { return nil, ErrNoTxInputs From 2e74cca0b56ea58fff6e7dba6693dbe3c4dcd092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 11:34:56 +0100 Subject: [PATCH 46/51] addressed PR feedback, added context as args to interfaces --- spv/interfaces.go | 6 ++--- spv/spvenvelope.go | 13 +++++++---- spv/spvenvelope_test.go | 50 ++++++++++++++++++++--------------------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/spv/interfaces.go b/spv/interfaces.go index 830fdf9..7671f1d 100644 --- a/spv/interfaces.go +++ b/spv/interfaces.go @@ -26,7 +26,7 @@ type EnvelopeHandler interface { // EnvelopeCreator interfaces the creation of SPV Envelopes type EnvelopeCreator interface { - CreateEnvelope(*bt.Tx) (*Envelope, error) + CreateEnvelope(context.Context, *bt.Tx) (*Envelope, error) } // EnvelopeVerifier interfaces the verification of SPV Envelopes @@ -42,10 +42,10 @@ type MerkleProofVerifier interface { // TxStore interfaces the a tx store type TxStore interface { - Tx(txID string) (*bt.Tx, error) + Tx(ctx context.Context, txID string) (*bt.Tx, error) } // MerkleProofStore interfaces a Merkle Proof store type MerkleProofStore interface { - MerkleProof(txID string) (*bc.MerkleProof, error) + MerkleProof(ctx context.Context, txID string) (*bc.MerkleProof, error) } diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index f6c66a5..a66896e 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -51,7 +51,7 @@ type Envelope struct { } // CreateEnvelope builds and returns an spv.Envelope for the provided tx. -func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { +func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, error) { if len(tx.Inputs) == 0 { return nil, ErrNoTxInputs } @@ -71,11 +71,13 @@ func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { continue } - mp, err := s.mpg.MerkleProof(pTxID) + // Check the store for a Merkle Proof for the current input. + mp, err := s.mpg.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, @@ -85,7 +87,10 @@ func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { continue } - pTx, err := s.txg.Tx(pTxID) + // 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 := s.txg.Tx(ctx, pTxID) if err != nil { return nil, errors.Wrapf(err, "failed to get tx %s", pTxID) } @@ -93,7 +98,7 @@ func (s *spvclient) CreateEnvelope(tx *bt.Tx) (*Envelope, error) { return nil, fmt.Errorf("could not find tx %s", pTxID) } - pEnvelope, err := s.CreateEnvelope(pTx) + pEnvelope, err := s.CreateEnvelope(ctx, pTx) if err != nil { return nil, err } diff --git a/spv/spvenvelope_test.go b/spv/spvenvelope_test.go index 29855f4..ca310dd 100644 --- a/spv/spvenvelope_test.go +++ b/spv/spvenvelope_test.go @@ -25,24 +25,24 @@ func (m *mockBlockHeaderClient) BlockHeader(ctx context.Context, blockHash strin } type mockTxMerkleGetter struct { - txStoreFunc func(string) (*bt.Tx, error) - mpStoreFunc func(string) (*bc.MerkleProof, error) + txStoreFunc func(context.Context, string) (*bt.Tx, error) + mpStoreFunc func(context.Context, string) (*bc.MerkleProof, error) } -func (m *mockTxMerkleGetter) Tx(txID string) (*bt.Tx, 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(txID) + return m.txStoreFunc(ctx, txID) } -func (m *mockTxMerkleGetter) MerkleProof(txID string) (*bc.MerkleProof, error) { +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(txID) + return m.mpStoreFunc(ctx, txID) } func TestSPVEnvelope_VerifyPayment(t *testing.T) { @@ -1042,17 +1042,17 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { func TestSPVEnvelope_CreateEnvelope(t *testing.T) { tests := map[string]struct { tx string - txFunc func(string) (*bt.Tx, error) - mpFunc func(string) (*bc.MerkleProof, error) + 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(txID string) (*bt.Tx, error) { + 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(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { mp, ok := map[string]*bc.MerkleProof{ "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, "4fe3882754b17dfe8caee3294770d1212f8957600a8b2bc42ee7a0c9925198eb": { @@ -1163,13 +1163,13 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "creating an envelope with tx that doesn't exist errors": { tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(txID string) (*bt.Tx, error) { + 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(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { mp, ok := map[string]*bc.MerkleProof{ "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, "9eb002032c179f0bbc4d1d30757fbc3aaf73352255b5e73a1653a1c9189c1df3": nil, @@ -1214,13 +1214,13 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "error when getting tx is handled": { tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(txID string) (*bt.Tx, error) { + 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(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { mp, ok := map[string]*bc.MerkleProof{ "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, "5eaf02ca1a20e2815da386442bc47097026e30df62bed2c829ce97cf6bc86e34": nil, @@ -1265,10 +1265,10 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "error when getting merkle proof is handled": { tx: "0200000005eb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f000000006b483045022100d49aded8eb72cf3013ff5ab40e72599120eca0efea888746280d139e780e7a8a02202311185979582154595bf54e2df451921350a99fb8dc6b4534070bcceb782e9e412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffffeb985192c9a0e72ec42b8b0a6057892f21d1704729e3ae8cfe7db1542788e34f010000006a4730440220183793b2ce4f0038eb9ae1117376a58048405bc842ad3aee0dc5c2edb9210e8e0220706abd0c23ec08d4e88773134e38c138918708e9c3473b864bd5cf7ab057f8e1412102d17ed18d28f653fbaa5c01856086f891447207fc3ea794fcbd8d9ba2ffbd0c68feffffff6c1d183beaa8a17316d9e5d6b16ddc79c726e28e3e2a1819bc974e7cdc5e89c3010000006b483045022100902a1a7ff861fddb44dd61c2ac79f8643a10c727abdc103e7c66696e2e55567a0220380e0f81737daba8d5cc6de763dee708ec42eae9015f31ff42cb6bf6f474b879412102ba8d1245a230a671dff96b97b539901f1a2acf1375cc3b3f15a2d65b05751335fefffffff31d9c18c9a153163ae7b555223573af3abc7f75301d4dbc0b9f172c0302b09e000000006a47304402200fe2ec5cb6209a7a70a115d7a989ec718faa7f107e777e7e8acd1bf13f394d95022019bde30bdf0344354f91152533c1262d2b86bb43d22966735c189f4d1f44bcd6412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff346ec86bcf97ce29c8d2be62df306e029770c42b4486a35d81e2201aca02af5e000000006a47304402203e04ed6793f42278eb63f63db5bedf518eb58f04b3abb3b1def3206aaf5c056d0220240ea45a398f3ea4eddff6589ba91a90600ac8496f462f27bbf7c455be9df67a41210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff02f6d7f505000000001976a9142da49f1c71288a4bbf57d0f9aaf352926ef8d66588ac004e7253000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac67000000", - txFunc: func(txID string) (*bt.Tx, error) { + 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(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { if txID == "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c" { return nil, errors.New("bigger badder error") } @@ -1296,7 +1296,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "envelope needing multiple layers can be built": { tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(txID string) (*bt.Tx, error) { + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { switch txID { case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": //nolint:goconst return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") @@ -1307,7 +1307,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { } return nil, fmt.Errorf("tx %s not defined for test", txID) }, - mpFunc: func(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { mp, ok := map[string]*bc.MerkleProof{ "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, @@ -1492,7 +1492,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "missing tx multiple layers down causes error": { tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(txID string) (*bt.Tx, error) { + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { switch txID { case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") @@ -1505,7 +1505,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { } return nil, fmt.Errorf("tx %s not defined for test", txID) }, - mpFunc: func(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { mp, ok := map[string]*bc.MerkleProof{ "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, @@ -1571,7 +1571,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "error getting tx multiple layers down is handled": { tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(txID string) (*bt.Tx, error) { + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { switch txID { case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") @@ -1584,7 +1584,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { } return nil, fmt.Errorf("tx %s not defined for test", txID) }, - mpFunc: func(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { mp, ok := map[string]*bc.MerkleProof{ "3f92e4567741afebdb26296c35c370e274d1b1455faaed2e27af499e6c65e759": nil, "bd1ec26bfb05072dc946639419234f60358d41dc48cc073808ce05fb71e24c84": nil, @@ -1650,7 +1650,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { }, "error getting merkle proof multiple layers down is handled": { tx: "0200000002bcd68aa8f1c3afcdf1070675c4fa1dfa8c5ae904ee326a61a50ecfe272a785d4010000006b483045022100d18b422f8cc7c14444aa091fddcb2cf2276c3f7cf496fc186327366f72e8b03802204b6f1b2d2ca44c8a56766f287c951a14302992f55a3063b7fd5c85ec6f2c4f2641210245189775c1532bedb6b9d929fc539584b07b824a47a5e53af987c92286ba67bafeffffff6111fe484db08f2a3b6035e21423dc0a8251904951182a9f5b1c3165be79dade010000006b4830450221008a277ad76dfeb69dfdcb15b22ed4539e06d263710e527b676915e90341c19bee02205ae03bbcf4281c2d1470b9e60847f13631c9285557c94df07bc8b447370644784121021f163f44d261868142986872ea90f3155a83775fb9c00b4f3c517e95b30d3b3cfeffffff0200ca9a3b000000001976a914c29f2b11dbc426d265eb1246463094a06bb0de4988ac1ed2f505000000001976a914e13aac4a3f01fd3154cc66fc9e285a33bd84d7df88ac6e000000", - txFunc: func(txID string) (*bt.Tx, error) { + txFunc: func(ctx context.Context, txID string) (*bt.Tx, error) { switch txID { case "deda79be65311c5b9f2a1851499051820adc2314e235603b2a8fb04d48fe1161": return bt.NewTxFromString("02000000020a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb000000006b483045022100ed01b49050b67634557cf01ad1abcb7271886e65c2edb09c325df3804270ed6402203b86581c0305778e9fb9f4a6b9b1e46a3084e6b85f5676bbdabe31c8128308d5412103a3d76b2838aed38d800b7bc5612add3e90894893ce7489f055f88ec9a6cd22effeffffff0a4c8d75e21ee64b498917337dadafc02dc02e05159252a8249a931efae148eb010000006a4730440220085479effe11ea67ed66622b1b231ec250131cad773bd0b36e79ea81701e7e55022013f9c6ed94ce7099fe807cbf04095cd545b651b6bbe31645ff5ab143b26faf26412102b552f6dff6e03a36ec58d44b71e20d779e92dbe53b52ac08d8236bf87f6ed14dfeffffff020027b929000000001976a9147d3722c7bab725e732d57c5db1d2765078aab6c388ac94d3f505000000001976a9141dcd2b24fe8457c775e1a6280bf91d68f48186e988ac6d000000") @@ -1661,7 +1661,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { } return nil, fmt.Errorf("tx %s not defined for test", txID) }, - mpFunc: func(txID string) (*bc.MerkleProof, error) { + mpFunc: func(ctx context.Context, txID string) (*bc.MerkleProof, error) { if txID == "c3895edc7c4e97bc19182a3e8ee226c779dc6db1d6e5d91673a1a8ea3b181d6c" { return nil, errors.New("no proof for you") } @@ -1752,7 +1752,7 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { spvc, err := spv.NewClient(spv.WithBlockHeaderChain(&mockBlockHeaderClient{}), spv.WithTxStore(mock), spv.WithMerkleProofStore(mock)) assert.NoError(t, err) - envelope, err := spvc.CreateEnvelope(testTx) + envelope, err := spvc.CreateEnvelope(context.TODO(), testTx) if test.expErr == nil { assert.NoError(t, err) assert.NotNil(t, envelope) From 34bb4c03e055a131a10fc33175a5d2ff75539abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 11:46:39 +0100 Subject: [PATCH 47/51] renamed spv fields --- spv/options.go | 8 ++++---- spv/spvclient.go | 4 ++-- spv/spvenvelope.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spv/options.go b/spv/options.go index a11eb38..9474bd5 100644 --- a/spv/options.go +++ b/spv/options.go @@ -13,15 +13,15 @@ func WithBlockHeaderChain(bhc bc.BlockHeaderChain) ClientOpts { } // WithTxStore will inject the provided TxGetter into the spv.Client -func WithTxStore(txg TxStore) ClientOpts { +func WithTxStore(txc TxStore) ClientOpts { return func(s *spvclient) { - s.txg = txg + s.txc = txc } } // WithMerkleProofStore will inject the provided MerkleProofGetter into the spv.Client -func WithMerkleProofStore(mpg MerkleProofStore) ClientOpts { +func WithMerkleProofStore(mpc MerkleProofStore) ClientOpts { return func(s *spvclient) { - s.mpg = mpg + s.mpc = mpc } } diff --git a/spv/spvclient.go b/spv/spvclient.go index 7e4e3ae..9c2c49e 100644 --- a/spv/spvclient.go +++ b/spv/spvclient.go @@ -9,8 +9,8 @@ import ( type spvclient struct { // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. bhc bc.BlockHeaderChain - txg TxStore - mpg MerkleProofStore + txc TxStore + mpc MerkleProofStore } // NewClient creates a new spv.Client based on the options provided. diff --git a/spv/spvenvelope.go b/spv/spvenvelope.go index a66896e..046e4a9 100644 --- a/spv/spvenvelope.go +++ b/spv/spvenvelope.go @@ -72,7 +72,7 @@ func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, e } // Check the store for a Merkle Proof for the current input. - mp, err := s.mpg.MerkleProof(ctx, pTxID) + mp, err := s.mpc.MerkleProof(ctx, pTxID) if err != nil { return nil, errors.Wrapf(err, "failed to get merkle proof for tx %s", pTxID) } @@ -90,7 +90,7 @@ func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, e // 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 := s.txg.Tx(ctx, pTxID) + pTx, err := s.txc.Tx(ctx, pTxID) if err != nil { return nil, errors.Wrapf(err, "failed to get tx %s", pTxID) } From 0831be597c5d2bc8c99fd4bb61f0ade4f55586f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 13:41:42 +0100 Subject: [PATCH 48/51] split the spv envelope creation and verification --- spv/{spvenvelope.go => envelope.go} | 18 ++++----- spv/{spvenvelope_test.go => envelope_test.go} | 10 ++--- spv/interfaces.go | 29 ++++++-------- spv/options.go | 27 ------------- spv/spv.go | 40 +++++++++++++++++++ spv/spvclient.go | 27 ------------- spv/verifymerkleproof.go | 8 ++-- spv/verifymerkleproof_test.go | 6 +-- 8 files changed, 74 insertions(+), 91 deletions(-) rename spv/{spvenvelope.go => envelope.go} (91%) rename spv/{spvenvelope_test.go => envelope_test.go} (99%) delete mode 100644 spv/options.go create mode 100644 spv/spv.go delete mode 100644 spv/spvclient.go diff --git a/spv/spvenvelope.go b/spv/envelope.go similarity index 91% rename from spv/spvenvelope.go rename to spv/envelope.go index 046e4a9..8e7308b 100644 --- a/spv/spvenvelope.go +++ b/spv/envelope.go @@ -51,7 +51,7 @@ type Envelope struct { } // CreateEnvelope builds and returns an spv.Envelope for the provided tx. -func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, error) { +func (c *creator) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, error) { if len(tx.Inputs) == 0 { return nil, ErrNoTxInputs } @@ -72,7 +72,7 @@ func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, e } // Check the store for a Merkle Proof for the current input. - mp, err := s.mpc.MerkleProof(ctx, pTxID) + mp, err := c.mpc.MerkleProof(ctx, pTxID) if err != nil { return nil, errors.Wrapf(err, "failed to get merkle proof for tx %s", pTxID) } @@ -90,7 +90,7 @@ func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, e // 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 := s.txc.Tx(ctx, pTxID) + pTx, err := c.txc.Tx(ctx, pTxID) if err != nil { return nil, errors.Wrapf(err, "failed to get tx %s", pTxID) } @@ -98,7 +98,7 @@ func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, e return nil, fmt.Errorf("could not find tx %s", pTxID) } - pEnvelope, err := s.CreateEnvelope(ctx, pTx) + pEnvelope, err := c.CreateEnvelope(ctx, pTx) if err != nil { return nil, err } @@ -110,7 +110,7 @@ func (s *spvclient) CreateEnvelope(ctx context.Context, tx *bt.Tx) (*Envelope, e } // VerifyPayment verifies whether or not the txs supplied via the supplied spv.Envelope are valid -func (s *spvclient) VerifyPayment(ctx context.Context, initialPayment *Envelope) (bool, error) { +func (v *verifier) VerifyPayment(ctx context.Context, initialPayment *Envelope) (bool, error) { if initialPayment == nil { return false, ErrNilInitialPayment } @@ -121,7 +121,7 @@ func (s *spvclient) VerifyPayment(ctx context.Context, initialPayment *Envelope) return false, ErrTipTxConfirmed } - valid, err := s.verifyTxs(ctx, initialPayment) + valid, err := v.verifyTxs(ctx, initialPayment) if err != nil { return false, err } @@ -129,7 +129,7 @@ func (s *spvclient) VerifyPayment(ctx context.Context, initialPayment *Envelope) return valid, nil } -func (s *spvclient) verifyTxs(ctx context.Context, payment *Envelope) (bool, error) { +func (s *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 @@ -167,7 +167,7 @@ func (s *spvclient) verifyTxs(ctx context.Context, payment *Envelope) (bool, err return s.verifyUnconfirmedTx(tx, payment) } -func (s *spvclient) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, error) { +func (s *verifier) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, error) { proofTxID := payment.Proof.TxOrID if len(proofTxID) != 64 { proofTx, err := bt.NewTxFromString(payment.Proof.TxOrID) @@ -192,7 +192,7 @@ func (s *spvclient) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool return valid, nil } -func (s *spvclient) verifyUnconfirmedTx(tx *bt.Tx, payment *Envelope) (bool, error) { +func (s *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 diff --git a/spv/spvenvelope_test.go b/spv/envelope_test.go similarity index 99% rename from spv/spvenvelope_test.go rename to spv/envelope_test.go index ca310dd..8db0698 100644 --- a/spv/spvenvelope_test.go +++ b/spv/envelope_test.go @@ -1022,12 +1022,12 @@ func TestSPVEnvelope_VerifyPayment(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - s, err := spv.NewClient(spv.WithBlockHeaderChain(&mockBlockHeaderClient{ + v, err := spv.NewVerifier(&mockBlockHeaderClient{ blockHeaderFunc: test.blockHeaderFunc, - })) + }) assert.NoError(t, err, "expected no error when creating spv client") - valid, err := s.VerifyPayment(context.Background(), test.envelope) + valid, err := v.VerifyPayment(context.Background(), test.envelope) if test.expErr != nil { assert.Error(t, err) assert.EqualError(t, err, test.expErr.Error()) @@ -1749,10 +1749,10 @@ func TestSPVEnvelope_CreateEnvelope(t *testing.T) { mpStoreFunc: test.mpFunc, } - spvc, err := spv.NewClient(spv.WithBlockHeaderChain(&mockBlockHeaderClient{}), spv.WithTxStore(mock), spv.WithMerkleProofStore(mock)) + c, err := spv.NewCreator(mock, mock) assert.NoError(t, err) - envelope, err := spvc.CreateEnvelope(context.TODO(), testTx) + envelope, err := c.CreateEnvelope(context.TODO(), testTx) if test.expErr == nil { assert.NoError(t, err) assert.NotNil(t, envelope) diff --git a/spv/interfaces.go b/spv/interfaces.go index 7671f1d..259c166 100644 --- a/spv/interfaces.go +++ b/spv/interfaces.go @@ -7,26 +7,23 @@ import ( "github.com/libsv/go-bt/v2" ) -// An Client is a struct used to specify interfaces -// used to complete Simple Payment Verification (SPV) -// in conjunction with a Merkle Proof. +// A Creator is an interface used to build the spv.Envelope data type for +// Simple Payment Verification (SPV). // -// The implementation of BlockHeaderChain which is supplied will depend on the client -// you are using, some may return a HeaderJSON response others may return the blockhash. -type Client interface { - EnvelopeHandler - MerkleProofVerifier +// The implementation of an spv.TxStore and spv.MerkleProofStore which is supplied will depend +// on the client you are using. +type Creator interface { + CreateEnvelope(context.Context, *bt.Tx) (*Envelope, error) } -// EnvelopeHandler interfaces the handling (creation and verification) of SPV Envelopes -type EnvelopeHandler interface { - EnvelopeCreator +// A Verifier 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 -} - -// EnvelopeCreator interfaces the creation of SPV Envelopes -type EnvelopeCreator interface { - CreateEnvelope(context.Context, *bt.Tx) (*Envelope, error) + MerkleProofVerifier } // EnvelopeVerifier interfaces the verification of SPV Envelopes diff --git a/spv/options.go b/spv/options.go deleted file mode 100644 index 9474bd5..0000000 --- a/spv/options.go +++ /dev/null @@ -1,27 +0,0 @@ -package spv - -import "github.com/libsv/go-bc" - -// ClientOpts can be implemented to provided functional options for an spv.Client. -type ClientOpts func(*spvclient) - -// WithBlockHeaderChain will inject the provided BlockHeaderChain into the spv.Client -func WithBlockHeaderChain(bhc bc.BlockHeaderChain) ClientOpts { - return func(s *spvclient) { - s.bhc = bhc - } -} - -// WithTxStore will inject the provided TxGetter into the spv.Client -func WithTxStore(txc TxStore) ClientOpts { - return func(s *spvclient) { - s.txc = txc - } -} - -// WithMerkleProofStore will inject the provided MerkleProofGetter into the spv.Client -func WithMerkleProofStore(mpc MerkleProofStore) ClientOpts { - return func(s *spvclient) { - s.mpc = mpc - } -} diff --git a/spv/spv.go b/spv/spv.go new file mode 100644 index 0000000..499c0cd --- /dev/null +++ b/spv/spv.go @@ -0,0 +1,40 @@ +package spv + +import ( + "errors" + + "github.com/libsv/go-bc" +) + +type verifier struct { + // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. + bhc bc.BlockHeaderChain +} + +type creator struct { + txc TxStore + mpc MerkleProofStore +} + +// NewVerifier creates a new spv.Verifer with the bc.BlockHeaderChain provided. +// If no BlockHeaderChain implementation is provided, the setup will return an error. +func NewVerifier(bhc bc.BlockHeaderChain) (Verifier, error) { + if bhc == nil { + return nil, errors.New("at least one blockchain header implementation should be returned") + } + + return &verifier{bhc: bhc}, nil +} + +// NewCreator 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) { + if txc == nil { + return nil, errors.New("an spv.TxStore implementation is required") + } + if mpc == nil { + return nil, errors.New("an spv.MerkleProofStore implementation is required") + } + + return &creator{txc: txc, mpc: mpc}, nil +} diff --git a/spv/spvclient.go b/spv/spvclient.go deleted file mode 100644 index 9c2c49e..0000000 --- a/spv/spvclient.go +++ /dev/null @@ -1,27 +0,0 @@ -package spv - -import ( - "errors" - - "github.com/libsv/go-bc" -) - -type spvclient struct { - // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. - bhc bc.BlockHeaderChain - txc TxStore - mpc MerkleProofStore -} - -// NewClient creates a new spv.Client based on the options provided. -// If no BlockHeaderChain implementation is provided, the setup will return an error. -func NewClient(opts ...ClientOpts) (Client, error) { - cli := &spvclient{} - for _, opt := range opts { - opt(cli) - } - if cli.bhc == nil { - return nil, errors.New("at least one blockchain header implementation should be returned") - } - return cli, nil -} diff --git a/spv/verifymerkleproof.go b/spv/verifymerkleproof.go index ef271c6..5d42e4e 100644 --- a/spv/verifymerkleproof.go +++ b/spv/verifymerkleproof.go @@ -21,7 +21,7 @@ const ( ) // VerifyMerkleProof verifies a Merkle Proof in standard byte format. -func (spvc *spvclient) VerifyMerkleProof(ctx context.Context, proof []byte) (valid, isLastInTree bool, err error) { +func (v *verifier) VerifyMerkleProof(ctx context.Context, proof []byte) (valid, isLastInTree bool, err error) { mpb, err := parseBinaryMerkleProof(proof) if err != nil { @@ -43,7 +43,7 @@ func (spvc *spvclient) VerifyMerkleProof(ctx context.Context, proof []byte) (val // if bits 1 and 2 of flags are NOT set, target should contain a block hash (32 bytes) case 0: // The `target` field contains a block hash - blockHeader, err := spvc.bhc.BlockHeader(ctx, mpb.target) + blockHeader, err := v.bhc.BlockHeader(ctx, mpb.target) if err != nil { return false, false, err } @@ -88,7 +88,7 @@ func (spvc *spvclient) VerifyMerkleProof(ctx context.Context, proof []byte) (val } // VerifyMerkleProofJSON verifies a Merkle Proof in standard JSON format. -func (spvc *spvclient) VerifyMerkleProofJSON(ctx context.Context, proof *bc.MerkleProof) (bool, bool, error) { +func (v *verifier) VerifyMerkleProofJSON(ctx context.Context, proof *bc.MerkleProof) (bool, bool, error) { txid, err := txidFromTxOrID(proof.TxOrID) if err != nil { @@ -103,7 +103,7 @@ func (spvc *spvclient) VerifyMerkleProofJSON(ctx context.Context, proof *bc.Merk return false, false, errors.New("invalid target field") } - blockHeader, err := spvc.bhc.BlockHeader(ctx, proof.Target) + blockHeader, err := v.bhc.BlockHeader(ctx, proof.Target) if err != nil { return false, false, err } diff --git a/spv/verifymerkleproof_test.go b/spv/verifymerkleproof_test.go index e453da5..65ffae4 100644 --- a/spv/verifymerkleproof_test.go +++ b/spv/verifymerkleproof_test.go @@ -32,10 +32,10 @@ func TestVerifyMerkleProof(t *testing.T) { } hcm := &mockBlockHeaderChain{} - spvc, _ := spv.NewClient(spv.WithBlockHeaderChain(hcm)) + v, _ := spv.NewVerifier(hcm) t.Run("JSON", func(t *testing.T) { - valid, isLastInTree, err := spvc.VerifyMerkleProofJSON(context.Background(), proofJSON) + valid, isLastInTree, err := v.VerifyMerkleProofJSON(context.Background(), proofJSON) assert.NoError(t, err) assert.False(t, isLastInTree) @@ -44,7 +44,7 @@ func TestVerifyMerkleProof(t *testing.T) { t.Run("Bytes", func(t *testing.T) { proof, _ := proofJSON.ToBytes() - valid, isLastInTree, err := spvc.VerifyMerkleProof(context.Background(), proof) + valid, isLastInTree, err := v.VerifyMerkleProof(context.Background(), proof) assert.NoError(t, err) assert.False(t, isLastInTree) From 4bd1ff0ad5637a1025fd96bdc11c2968fb44143d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 14:00:28 +0100 Subject: [PATCH 49/51] fixed linter issues --- spv/envelope.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spv/envelope.go b/spv/envelope.go index 8e7308b..6e5cc1c 100644 --- a/spv/envelope.go +++ b/spv/envelope.go @@ -129,7 +129,7 @@ func (v *verifier) VerifyPayment(ctx context.Context, initialPayment *Envelope) return valid, nil } -func (s *verifier) verifyTxs(ctx context.Context, payment *Envelope) (bool, error) { +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 @@ -143,7 +143,7 @@ func (s *verifier) verifyTxs(ctx context.Context, payment *Envelope) (bool, erro parent.TxID = parentTxID } - valid, err := s.verifyTxs(ctx, parent) + valid, err := v.verifyTxs(ctx, parent) if err != nil { return false, err } @@ -155,7 +155,7 @@ func (s *verifier) verifyTxs(ctx context.Context, payment *Envelope) (bool, erro // 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 s.verifyTxAnchor(ctx, payment) + return v.verifyTxAnchor(ctx, payment) } tx, err := bt.NewTxFromString(payment.RawTx) @@ -164,10 +164,10 @@ func (s *verifier) verifyTxs(ctx context.Context, payment *Envelope) (bool, erro } // We must verify the tx or else we can not know if any of it's child txs are valid. - return s.verifyUnconfirmedTx(tx, payment) + return v.verifyUnconfirmedTx(tx, payment) } -func (s *verifier) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, error) { +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) @@ -184,7 +184,7 @@ func (s *verifier) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, return false, ErrTxIDMismatch } - valid, _, err := s.VerifyMerkleProofJSON(ctx, payment.Proof) + valid, _, err := v.VerifyMerkleProofJSON(ctx, payment.Proof) if err != nil { return false, err } @@ -192,7 +192,7 @@ func (s *verifier) verifyTxAnchor(ctx context.Context, payment *Envelope) (bool, return valid, nil } -func (s *verifier) verifyUnconfirmedTx(tx *bt.Tx, payment *Envelope) (bool, error) { +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 @@ -224,6 +224,6 @@ func (s *verifier) verifyUnconfirmedTx(tx *bt.Tx, payment *Envelope) (bool, erro } // IsAnchored returns true if the envelope is the anchor tx. -func (s *Envelope) IsAnchored() bool { - return s.Proof != nil +func (e *Envelope) IsAnchored() bool { + return e.Proof != nil } From d5e2485ed92ded4a368be766f5532c1b501823a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Tue, 24 Aug 2021 14:35:39 +0100 Subject: [PATCH 50/51] split up interface file into creator and verifier files --- spv/creator.go | 106 +++ spv/creator_test.go | 760 ++++++++++++++++++ spv/envelope.go | 208 ----- spv/envelope_test.go | 1756 +----------------------------------------- spv/errors.go | 33 + spv/interfaces.go | 48 -- spv/spv.go | 40 - spv/verifier.go | 159 ++++ spv/verifier_test.go | 1017 ++++++++++++++++++++++++ 9 files changed, 2086 insertions(+), 2041 deletions(-) create mode 100644 spv/creator.go create mode 100644 spv/creator_test.go create mode 100644 spv/errors.go delete mode 100644 spv/interfaces.go delete mode 100644 spv/spv.go create mode 100644 spv/verifier.go create mode 100644 spv/verifier_test.go diff --git a/spv/creator.go b/spv/creator.go new file mode 100644 index 0000000..658b506 --- /dev/null +++ b/spv/creator.go @@ -0,0 +1,106 @@ +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 +// 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 { + CreateEnvelope(context.Context, *bt.Tx) (*Envelope, error) +} + +// TxStore interfaces the a tx store +type TxStore interface { + Tx(ctx context.Context, txID string) (*bt.Tx, error) +} + +// MerkleProofStore interfaces a Merkle Proof store +type MerkleProofStore interface { + MerkleProof(ctx context.Context, txID string) (*bc.MerkleProof, error) +} + +type creator struct { + txc TxStore + mpc MerkleProofStore +} + +// NewCreator 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) { + if txc == nil { + return nil, errors.New("an spv.TxStore implementation is required") + } + if mpc == nil { + return nil, errors.New("an spv.MerkleProofStore implementation is required") + } + + 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 new file mode 100644 index 0000000..90dfc2b --- /dev/null +++ b/spv/creator_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.NewCreator(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/envelope.go b/spv/envelope.go index 6e5cc1c..9643c63 100644 --- a/spv/envelope.go +++ b/spv/envelope.go @@ -1,42 +1,7 @@ package spv import ( - "context" - "fmt" - "github.com/libsv/go-bc" - "github.com/libsv/go-bt/v2" - "github.com/pkg/errors" -) - -var ( - // ErrNoTxInputs returns if an envelope is attempted to be created from a transaction that has no inputs - ErrNoTxInputs = errors.New("provided tx has no inputs to build envelope from") - - // ErrPaymentNotVerified returns if a transaction in the tree provided was missed during verification - ErrPaymentNotVerified = errors.New("a tx was missed during validation") - - // ErrTipTxConfirmed returns if the tip transaction is already confirmed - ErrTipTxConfirmed = errors.New("tip transaction must be unconfirmed") - - // ErrNoConfirmedTransaction returns if a path from tip to beginning/anchor contains no confirmed transcation - ErrNoConfirmedTransaction = errors.New("not confirmed/anchored tx(s) provided") - - // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID - ErrTxIDMismatch = errors.New("input and proof ID mismatch") - - // ErrNotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not - // present in the parent envelope - ErrNotAllInputsSupplied = errors.New("a tx input missing in parent envelope") - - // ErrNoTxInputsToVerify returns if a transaction has no inputs - ErrNoTxInputsToVerify = errors.New("a tx has no inputs to verify") - - // ErrNilInitialPayment returns if a transaction has no inputs - ErrNilInitialPayment = errors.New("initial payment cannot be nil") - - // ErrInputRefsOutOfBoundsOutput returns if a transaction has no inputs - ErrInputRefsOutOfBoundsOutput = errors.New("tx input index into output is out of bounds") ) // Envelope is a struct which contains all information needed for a transaction to be verified. @@ -50,179 +15,6 @@ type Envelope struct { Parents map[string]*Envelope `json:"parents,omitempty"` } -// 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 -} - -// 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 -} - // IsAnchored returns true if the envelope is the anchor tx. func (e *Envelope) IsAnchored() bool { return e.Proof != nil diff --git a/spv/envelope_test.go b/spv/envelope_test.go index 8db0698..8a09ea1 100644 --- a/spv/envelope_test.go +++ b/spv/envelope_test.go @@ -1,1766 +1,32 @@ -package spv_test +package spv 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 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") -} - -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_VerifyPayment(t *testing.T) { +func TestEnvelope_IsAnchored(t *testing.T) { tests := map[string]struct { - envelope *spv.Envelope - blockHeaderFunc func(context.Context, string) (*bc.BlockHeader, error) - exp bool - expErr error + envelope Envelope + exp bool }{ - "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") + "is anchored": { + envelope: Envelope{ + Proof: &bc.MerkleProof{}, }, - 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.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 { - assert.Error(t, err) - assert.EqualError(t, err, test.expErr.Error()) - } else { - assert.NoError(t, err) - } - assert.Equal(t, test.exp, valid) - }) - } -} - -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"), + "is not anchored": { + envelope: Envelope{}, + exp: false, }, } 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) - 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()) - } + assert.Equal(t, test.exp, test.envelope.IsAnchored()) }) } } diff --git a/spv/errors.go b/spv/errors.go new file mode 100644 index 0000000..feb40a1 --- /dev/null +++ b/spv/errors.go @@ -0,0 +1,33 @@ +package spv + +import "github.com/pkg/errors" + +var ( + // ErrNoTxInputs returns if an envelope is attempted to be created from a transaction that has no inputs + ErrNoTxInputs = errors.New("provided tx has no inputs to build envelope from") + + // ErrPaymentNotVerified returns if a transaction in the tree provided was missed during verification + ErrPaymentNotVerified = errors.New("a tx was missed during validation") + + // ErrTipTxConfirmed returns if the tip transaction is already confirmed + ErrTipTxConfirmed = errors.New("tip transaction must be unconfirmed") + + // ErrNoConfirmedTransaction returns if a path from tip to beginning/anchor contains no confirmed transcation + ErrNoConfirmedTransaction = errors.New("not confirmed/anchored tx(s) provided") + + // ErrTxIDMismatch returns if they key value pair of a transactions input has a mismatch in txID + ErrTxIDMismatch = errors.New("input and proof ID mismatch") + + // ErrNotAllInputsSupplied returns if an unconfirmed transaction in envelope contains inputs which are not + // present in the parent envelope + ErrNotAllInputsSupplied = errors.New("a tx input missing in parent envelope") + + // ErrNoTxInputsToVerify returns if a transaction has no inputs + ErrNoTxInputsToVerify = errors.New("a tx has no inputs to verify") + + // ErrNilInitialPayment returns if a transaction has no inputs + ErrNilInitialPayment = errors.New("initial payment cannot be nil") + + // ErrInputRefsOutOfBoundsOutput returns if a transaction has no inputs + ErrInputRefsOutOfBoundsOutput = errors.New("tx input index into output is out of bounds") +) diff --git a/spv/interfaces.go b/spv/interfaces.go deleted file mode 100644 index 259c166..0000000 --- a/spv/interfaces.go +++ /dev/null @@ -1,48 +0,0 @@ -package spv - -import ( - "context" - - "github.com/libsv/go-bc" - "github.com/libsv/go-bt/v2" -) - -// A Creator 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 { - CreateEnvelope(context.Context, *bt.Tx) (*Envelope, error) -} - -// A Verifier 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 { - VerifyPayment(context.Context, *Envelope) (bool, error) -} - -// MerkleProofVerifier interfaces the verification of Merkle Proofs -type MerkleProofVerifier interface { - VerifyMerkleProof(context.Context, []byte) (bool, bool, error) - VerifyMerkleProofJSON(context.Context, *bc.MerkleProof) (bool, bool, error) -} - -// TxStore interfaces the a tx store -type TxStore interface { - Tx(ctx context.Context, txID string) (*bt.Tx, error) -} - -// MerkleProofStore interfaces a Merkle Proof store -type MerkleProofStore interface { - MerkleProof(ctx context.Context, txID string) (*bc.MerkleProof, error) -} diff --git a/spv/spv.go b/spv/spv.go deleted file mode 100644 index 499c0cd..0000000 --- a/spv/spv.go +++ /dev/null @@ -1,40 +0,0 @@ -package spv - -import ( - "errors" - - "github.com/libsv/go-bc" -) - -type verifier struct { - // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. - bhc bc.BlockHeaderChain -} - -type creator struct { - txc TxStore - mpc MerkleProofStore -} - -// NewVerifier creates a new spv.Verifer with the bc.BlockHeaderChain provided. -// If no BlockHeaderChain implementation is provided, the setup will return an error. -func NewVerifier(bhc bc.BlockHeaderChain) (Verifier, error) { - if bhc == nil { - return nil, errors.New("at least one blockchain header implementation should be returned") - } - - return &verifier{bhc: bhc}, nil -} - -// NewCreator 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) { - if txc == nil { - return nil, errors.New("an spv.TxStore implementation is required") - } - if mpc == nil { - return nil, errors.New("an spv.MerkleProofStore implementation is required") - } - - return &creator{txc: txc, mpc: mpc}, nil -} diff --git a/spv/verifier.go b/spv/verifier.go new file mode 100644 index 0000000..948e204 --- /dev/null +++ b/spv/verifier.go @@ -0,0 +1,159 @@ +package spv + +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) +// 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 { + VerifyPayment(context.Context, *Envelope) (bool, error) +} + +// MerkleProofVerifier interfaces the verification of Merkle Proofs +type MerkleProofVerifier interface { + VerifyMerkleProof(context.Context, []byte) (bool, bool, error) + VerifyMerkleProofJSON(context.Context, *bc.MerkleProof) (bool, bool, error) +} + +type verifier struct { + // BlockHeaderChain will be set when an implementation returning a bc.BlockHeader type is provided. + bhc bc.BlockHeaderChain +} + +// NewVerifier creates a new spv.Verifer with the bc.BlockHeaderChain provided. +// If no BlockHeaderChain implementation is provided, the setup will return an error. +func NewVerifier(bhc bc.BlockHeaderChain) (Verifier, error) { + if bhc == nil { + return nil, errors.New("at least one blockchain header implementation should be returned") + } + + 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 +} diff --git a/spv/verifier_test.go b/spv/verifier_test.go new file mode 100644 index 0000000..e2d89a1 --- /dev/null +++ b/spv/verifier_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.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 { + assert.Error(t, err) + assert.EqualError(t, err, test.expErr.Error()) + } else { + assert.NoError(t, err) + } + assert.Equal(t, test.exp, valid) + }) + } +} 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 51/51] 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) + }) + } +}