Skip to content

Commit ddf3781

Browse files
Larry RuaneLarryRuane
authored andcommitted
parse V5 (nu5) transactions
TODO: - store, instead of just skip over, nu5 transaction fields - add relevant nu5 fields to CompactBlock - restore disabled V4 unit tests - add V5 test vectors to unit tests The reason most of the V4 transaction and block unit tests are removed is that they used V3 transactions, which lightwalletd never sees in production, since lightwalletd starts at Sapling activation (which has V4 transactions). So these tests were always wrong, in a way. This commit simplifies the parsing code by removing support for V3 (since it was never needed). The tests need to be updated to V4, but we'll do that in a later PR.
1 parent 9263e7f commit ddf3781

File tree

5 files changed

+254
-1223
lines changed

5 files changed

+254
-1223
lines changed

parser/block_header_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func TestBlockHeader(t *testing.T) {
134134
}
135135

136136
// This is not necessarily true for anything but our current test cases.
137-
for _, b := range hash[:4] {
137+
for _, b := range hash[:1] {
138138
if b != 0 {
139139
t.Errorf("Hash lacked leading zeros: %x", hash)
140140
}

parser/block_test.go

Lines changed: 0 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -4,214 +4,18 @@
44
package parser
55

66
import (
7-
"bufio"
87
"bytes"
98
"encoding/hex"
109
"encoding/json"
1110
"fmt"
1211
"io/ioutil"
13-
"os"
1412
"testing"
1513

1614
"github.com/pkg/errors"
1715

1816
protobuf "github.com/golang/protobuf/proto"
1917
)
2018

21-
func TestBlockParser(t *testing.T) {
22-
// These (valid on testnet) correspond to the transactions in testdata/blocks;
23-
// for each block, the hashes for the tx within that block.
24-
var txhashes = [][]string{
25-
{
26-
"81096ff101a4f01d25ffd34a446bee4368bd46c233a59ac0faf101e1861c6b22",
27-
}, {
28-
"921dc41bef3a0d887c615abac60a29979efc8b4bbd3d887caeb6bb93501bde8e",
29-
}, {
30-
"d8e4c336ffa69dacaa4e0b4eaf8e3ae46897f1930a573c10b53837a03318c980",
31-
"4d5ccbfc6984680c481ff5ce145b8a93d59dfea90c150dfa45c938ab076ee5b2",
32-
}, {
33-
"df2b03619d441ce3d347e9278d87618e975079d0e235dfb3b3d8271510f707aa",
34-
"8d2593edfc328fa637b4ac91c7d569ee922bb9a6fda7cea230e92deb3ae4b634",
35-
},
36-
}
37-
testBlocks, err := os.Open("../testdata/blocks")
38-
if err != nil {
39-
t.Fatal(err)
40-
}
41-
defer testBlocks.Close()
42-
43-
scan := bufio.NewScanner(testBlocks)
44-
for blockindex := 0; scan.Scan(); blockindex++ {
45-
blockDataHex := scan.Text()
46-
blockData, err := hex.DecodeString(blockDataHex)
47-
if err != nil {
48-
t.Error(err)
49-
continue
50-
}
51-
52-
// This is just a sanity check of the test:
53-
if int(blockData[1487]) != len(txhashes[blockindex]) {
54-
t.Error("wrong number of transactions, test broken?")
55-
}
56-
57-
// Make a copy of just the transactions alone, which,
58-
// for these blocks, start just beyond the header and
59-
// the one-byte nTx value, which is offset 1488.
60-
transactions := make([]byte, len(blockData[1488:]))
61-
copy(transactions, blockData[1488:])
62-
63-
// Each iteration of this loop appends the block's original
64-
// transactions, so we build an ever-larger block. The loop
65-
// limit is arbitrary, but make sure we get into double-digit
66-
// transaction counts (compact integer).
67-
for i := 0; i < 264; i++ {
68-
b := blockData
69-
block := NewBlock()
70-
b, err = block.ParseFromSlice(b)
71-
if err != nil {
72-
t.Error(errors.Wrap(err, fmt.Sprintf("parsing block %d", i)))
73-
continue
74-
}
75-
if len(b) > 0 {
76-
t.Error("Extra data remaining")
77-
}
78-
79-
// Some basic sanity checks
80-
if block.hdr.Version != 4 {
81-
t.Error("Read wrong version in a test block.")
82-
break
83-
}
84-
if block.GetVersion() != 4 {
85-
t.Error("Read wrong version in a test block.")
86-
break
87-
}
88-
if block.GetTxCount() < 1 {
89-
t.Error("No transactions in block")
90-
break
91-
}
92-
if len(block.Transactions()) != block.GetTxCount() {
93-
t.Error("Number of transactions mismatch")
94-
break
95-
}
96-
if block.GetTxCount() != len(txhashes[blockindex])*(i+1) {
97-
t.Error("Unexpected number of transactions")
98-
}
99-
if block.HasSaplingTransactions() {
100-
t.Error("Unexpected Sapling tx")
101-
break
102-
}
103-
for txindex, tx := range block.Transactions() {
104-
if tx.HasSaplingElements() {
105-
t.Error("Unexpected Sapling tx")
106-
break
107-
}
108-
expectedHash := txhashes[blockindex][txindex%len(txhashes[blockindex])]
109-
if hex.EncodeToString(tx.GetDisplayHash()) != expectedHash {
110-
t.Error("incorrect tx hash")
111-
}
112-
}
113-
// Keep appending the original transactions, which is unrealistic
114-
// because the coinbase is being replicated, but it works; first do
115-
// some surgery to the transaction count (see DarksideApplyStaged()).
116-
for j := 0; j < len(txhashes[blockindex]); j++ {
117-
nTxFirstByte := blockData[1487]
118-
switch {
119-
case nTxFirstByte < 252:
120-
blockData[1487]++
121-
case nTxFirstByte == 252:
122-
// incrementing to 253, requires "253" followed by 2-byte length,
123-
// extend the block by two bytes, shift existing transaction bytes
124-
blockData = append(blockData, 0, 0)
125-
copy(blockData[1490:], blockData[1488:len(blockData)-2])
126-
blockData[1487] = 253
127-
blockData[1488] = 253
128-
blockData[1489] = 0
129-
case nTxFirstByte == 253:
130-
blockData[1488]++
131-
if blockData[1488] == 0 {
132-
// wrapped around
133-
blockData[1489]++
134-
}
135-
}
136-
}
137-
blockData = append(blockData, transactions...)
138-
}
139-
}
140-
}
141-
142-
func TestBlockParserFail(t *testing.T) {
143-
testBlocks, err := os.Open("../testdata/badblocks")
144-
if err != nil {
145-
t.Fatal(err)
146-
}
147-
defer testBlocks.Close()
148-
149-
scan := bufio.NewScanner(testBlocks)
150-
151-
// the first "block" contains an illegal hex character
152-
{
153-
scan.Scan()
154-
blockDataHex := scan.Text()
155-
_, err := hex.DecodeString(blockDataHex)
156-
if err == nil {
157-
t.Error("unexpected success parsing illegal hex bad block")
158-
}
159-
}
160-
for i := 0; scan.Scan(); i++ {
161-
blockDataHex := scan.Text()
162-
blockData, err := hex.DecodeString(blockDataHex)
163-
if err != nil {
164-
t.Error(err)
165-
continue
166-
}
167-
168-
block := NewBlock()
169-
blockData, err = block.ParseFromSlice(blockData)
170-
if err == nil {
171-
t.Error("unexpected success parsing bad block")
172-
}
173-
}
174-
}
175-
176-
// Checks on the first 20 blocks from mainnet genesis.
177-
func TestGenesisBlockParser(t *testing.T) {
178-
blockFile, err := os.Open("../testdata/mainnet_genesis")
179-
if err != nil {
180-
t.Fatal(err)
181-
}
182-
defer blockFile.Close()
183-
184-
scan := bufio.NewScanner(blockFile)
185-
for i := 0; scan.Scan(); i++ {
186-
blockDataHex := scan.Text()
187-
blockData, err := hex.DecodeString(blockDataHex)
188-
if err != nil {
189-
t.Error(err)
190-
continue
191-
}
192-
193-
block := NewBlock()
194-
blockData, err = block.ParseFromSlice(blockData)
195-
if err != nil {
196-
t.Error(err)
197-
continue
198-
}
199-
if len(blockData) > 0 {
200-
t.Error("Extra data remaining")
201-
}
202-
203-
// Some basic sanity checks
204-
if block.hdr.Version != 4 {
205-
t.Error("Read wrong version in genesis block.")
206-
break
207-
}
208-
209-
if block.GetHeight() != i {
210-
t.Errorf("Got wrong height for block %d: %d", i, block.GetHeight())
211-
}
212-
}
213-
}
214-
21519
func TestCompactBlocks(t *testing.T) {
21620
type compactTest struct {
21721
BlockHeight int `json:"block"`

0 commit comments

Comments
 (0)