Skip to content

Commit 26df6f0

Browse files
Larry RuaneLarryRuane
authored andcommitted
add V5 transaction (orchard) parsing test
1 parent 631bb16 commit 26df6f0

File tree

3 files changed

+126
-3
lines changed

3 files changed

+126
-3
lines changed

parser/transaction.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,6 @@ func (tx *Transaction) parseV5(data []byte) ([]byte, error) {
483483
if tx.nVersionGroupID != 0x26A7270A {
484484
return nil, errors.New(fmt.Sprintf("version group ID %d must be 0x26A7270A", tx.nVersionGroupID))
485485
}
486-
if tx.consensusBranchID != 0x37519621 {
487-
return nil, errors.New("unknown consensusBranchID")
488-
}
489486
if !s.Skip(4) {
490487
return nil, errors.New("could not skip nLockTime")
491488
}

parser/transaction_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,115 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
44
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

Comments
 (0)