block_test.go raw
1 package domain
2
3 import (
4 "encoding/hex"
5 "os"
6 "strings"
7 "testing"
8 )
9
10 // loadBlock reads the regtest block 1 fixture, which is the same block pkg/block pins its
11 // parser against.
12 func loadBlock(t *testing.T) []byte {
13 t.Helper()
14
15 text, err := os.ReadFile("testdata/block1.hex")
16
17 if err != nil {
18 t.Fatal(err)
19 }
20
21 raw, err := hex.DecodeString(strings.TrimSpace(string(text)))
22
23 if err != nil {
24 t.Fatal(err)
25 }
26
27 return raw
28 }
29
30 // TestScanBlockAddsNothingItDoesNotOwn: a valid block whose outputs pay somebody else leaves the
31 // coin table alone.
32 func TestScanBlockAddsNothingItDoesNotOwn(t *testing.T) {
33 r := newRig(t)
34
35 if _, err := r.domain.Restore("btc", phrase, "pass"); err != nil {
36 t.Fatal(err)
37 }
38
39 added, err := r.domain.ScanBlock("btc", loadBlock(t), 1)
40
41 if err != nil {
42 t.Fatal(err)
43 }
44
45 if added != 0 {
46 t.Fatalf("%d coins were added for a block that pays somebody else", added)
47 }
48
49 coins, err := r.domain.Unspent()
50
51 if err != nil {
52 t.Fatal(err)
53 }
54
55 if len(coins) != 0 {
56 t.Fatalf("the table holds %d coins", len(coins))
57 }
58 }
59
60 // TestScanBlockRefusesAFabricatedBlock: the merkle root is the only thing tying bytes to a
61 // header, so a block that fails it must add nothing.
62 func TestScanBlockRefusesAFabricatedBlock(t *testing.T) {
63 r := newRig(t)
64
65 if _, err := r.domain.Restore("btc", phrase, "pass"); err != nil {
66 t.Fatal(err)
67 }
68
69 raw := loadBlock(t)
70 raw[81] ^= 0xff
71
72 if _, err := r.domain.ScanBlock("btc", raw, 1); err == nil {
73 t.Fatal("a fabricated block was accepted")
74 }
75 }
76
77 // TestScanBlockNeedsAWallet: there are no scripts to match before setup.
78 func TestScanBlockNeedsAWallet(t *testing.T) {
79 r := newRig(t)
80
81 if _, err := r.domain.ScanBlock("btc", loadBlock(t), 1); err == nil {
82 t.Fatal("a block was scanned for a wallet that does not exist")
83 }
84 }
85