|
2 | 2 | // Distributed under the MIT software license, see the accompanying
|
3 | 3 | // file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
4 | 4 | package parser
|
| 5 | + |
| 6 | +import ( |
| 7 | + "bytes" |
| 8 | + "encoding/hex" |
| 9 | + "encoding/json" |
| 10 | + "os" |
| 11 | + "testing" |
| 12 | +) |
| 13 | + |
| 14 | +// Some of these values may be "null" (which translates to nil in Go) in |
| 15 | +// the test data, so we have *_set variables to indicate if the corresponding |
| 16 | +// variable is non-null. (There is an "optional" package we could use for |
| 17 | +// these but it doesn't seem worth pulling it in.) |
| 18 | +type TxTestData struct { |
| 19 | + Tx string |
| 20 | + Txid string |
| 21 | + Version int |
| 22 | + NVersionGroupId int |
| 23 | + NConsensusBranchId int |
| 24 | + Tx_in_count int |
| 25 | + Tx_out_count int |
| 26 | + NSpendsSapling int |
| 27 | + NoutputsSapling int |
| 28 | + NActionsOrchard int |
| 29 | +} |
| 30 | + |
| 31 | +// https://jhall.io/posts/go-json-tricks-array-as-structs/ |
| 32 | +func (r *TxTestData) UnmarshalJSON(p []byte) error { |
| 33 | + var t []interface{} |
| 34 | + if err := json.Unmarshal(p, &t); err != nil { |
| 35 | + return err |
| 36 | + } |
| 37 | + r.Tx = t[0].(string) |
| 38 | + r.Txid = t[1].(string) |
| 39 | + r.Version = int(t[2].(float64)) |
| 40 | + r.NVersionGroupId = int(t[3].(float64)) |
| 41 | + r.NConsensusBranchId = int(t[4].(float64)) |
| 42 | + r.Tx_in_count = int(t[7].(float64)) |
| 43 | + r.Tx_out_count = int(t[8].(float64)) |
| 44 | + r.NSpendsSapling = int(t[9].(float64)) |
| 45 | + r.NoutputsSapling = int(t[10].(float64)) |
| 46 | + r.NActionsOrchard = int(t[14].(float64)) |
| 47 | + return nil |
| 48 | +} |
| 49 | + |
| 50 | +func TestV5TransactionParser(t *testing.T) { |
| 51 | + // The raw data are stored in a separate file because they're large enough |
| 52 | + // to make the test table difficult to scroll through. They are in the same |
| 53 | + // order as the test table above. If you update the test table without |
| 54 | + // adding a line to the raw file, this test will panic due to index |
| 55 | + // misalignment. |
| 56 | + s, err := os.ReadFile("../testdata/tx_v5.json") |
| 57 | + if err != nil { |
| 58 | + t.Fatal(err) |
| 59 | + } |
| 60 | + |
| 61 | + var testdata []json.RawMessage |
| 62 | + err = json.Unmarshal(s, &testdata) |
| 63 | + if err != nil { |
| 64 | + t.Fatal(err) |
| 65 | + } |
| 66 | + if len(testdata) < 3 { |
| 67 | + t.Fatal("tx_vt.json has too few lines") |
| 68 | + } |
| 69 | + testdata = testdata[2:] |
| 70 | + for _, onetx := range testdata { |
| 71 | + var txtestdata TxTestData |
| 72 | + |
| 73 | + err = json.Unmarshal(onetx, &txtestdata) |
| 74 | + if err != nil { |
| 75 | + t.Fatal(err) |
| 76 | + } |
| 77 | + t.Logf("txid %s", txtestdata.Txid) |
| 78 | + rawTxData, _ := hex.DecodeString(txtestdata.Tx) |
| 79 | + |
| 80 | + tx := NewTransaction() |
| 81 | + rest, err := tx.ParseFromSlice(rawTxData) |
| 82 | + if err != nil { |
| 83 | + t.Fatalf("%v", err) |
| 84 | + } |
| 85 | + if len(rest) != 0 { |
| 86 | + t.Fatalf("Test did not consume entire buffer, %d remaining", len(rest)) |
| 87 | + } |
| 88 | + if bytes.Equal(tx.cachedTxID, []byte(txtestdata.Txid)) { |
| 89 | + t.Fatal("txid") |
| 90 | + } |
| 91 | + if tx.version != uint32(txtestdata.Version) { |
| 92 | + t.Fatal("version miscompare") |
| 93 | + } |
| 94 | + if tx.nVersionGroupID != uint32(txtestdata.NVersionGroupId) { |
| 95 | + t.Fatal("nVersionGroupId miscompare") |
| 96 | + } |
| 97 | + if tx.consensusBranchID != uint32(txtestdata.NConsensusBranchId) { |
| 98 | + t.Fatal("consensusBranchID miscompare") |
| 99 | + } |
| 100 | + if len(tx.transparentInputs) != int(txtestdata.Tx_in_count) { |
| 101 | + t.Fatal("tx_in_count miscompare") |
| 102 | + } |
| 103 | + if len(tx.transparentOutputs) != int(txtestdata.Tx_out_count) { |
| 104 | + t.Fatal("tx_out_count miscompare") |
| 105 | + } |
| 106 | + if len(tx.shieldedSpends) != int(txtestdata.NSpendsSapling) { |
| 107 | + t.Fatal("NSpendsSapling miscompare") |
| 108 | + } |
| 109 | + if len(tx.shieldedOutputs) != int(txtestdata.NoutputsSapling) { |
| 110 | + t.Fatal("NOutputsSapling miscompare") |
| 111 | + } |
| 112 | + if len(tx.orchardActions) != int(txtestdata.NActionsOrchard) { |
| 113 | + t.Fatal("NActionsOrchard miscompare") |
| 114 | + } |
| 115 | + } |
| 116 | +} |
0 commit comments