htlc_test.go raw
1 package script
2
3 import (
4 "encoding/hex"
5 "testing"
6 )
7
8 // The vector below came out of the rig node itself: `utxoupdatepsbt` filled in the witness
9 // script for this descriptor, and `deriveaddresses` gave the address. It is the only thing
10 // that makes this compiler trustworthy.
11 const (
12 nodeClaimer = "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd"
13 nodeRefunder = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
14 nodeHash = "0000000000000000000000000000000000000000000000000000000000000001"
15 nodeLocktime = 500
16 nodeScript = "632103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdad82012088a820" +
17 "0000000000000000000000000000000000000000000000000000000000000001876702f401b169210279be66" +
18 "7ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac68"
19 nodeAddress = "bcrt1qvsxuue8tp8gnfw02ynzxv5ns4ecpp8k4kjrx7eav02qv3jgad7tqzur2fy"
20 )
21
22 // fixture decodes the vector.
23 func fixture(t *testing.T) (claimer, refunder []byte, hash [32]byte) {
24 t.Helper()
25
26 var err error
27
28 if claimer, err = hex.DecodeString(nodeClaimer); err != nil {
29 t.Fatal(err)
30 }
31
32 if refunder, err = hex.DecodeString(nodeRefunder); err != nil {
33 t.Fatal(err)
34 }
35
36 raw, err := hex.DecodeString(nodeHash)
37
38 if err != nil {
39 t.Fatal(err)
40 }
41
42 copy(hash[:], raw)
43
44 return claimer, refunder, hash
45 }
46
47 // TestHTLCMatchesTheNode: the compiler produces the bytes the node compiled.
48 func TestHTLCMatchesTheNode(t *testing.T) {
49 claimer, refunder, hash := fixture(t)
50
51 witness, err := HTLC(claimer, refunder, hash, nodeLocktime)
52
53 if err != nil {
54 t.Fatal(err)
55 }
56
57 if got := hex.EncodeToString(witness); got != nodeScript {
58 t.Fatalf("the script is\n%s\nwant\n%s", got, nodeScript)
59 }
60 }
61
62 // TestHTLCAddressMatchesTheNode: and the address that script pays to.
63 func TestHTLCAddressMatchesTheNode(t *testing.T) {
64 claimer, refunder, hash := fixture(t)
65
66 address, err := HTLCAddress("bcrt", claimer, refunder, hash, nodeLocktime)
67
68 if err != nil {
69 t.Fatal(err)
70 }
71
72 if address != nodeAddress {
73 t.Fatalf("the address is %s, want %s", address, nodeAddress)
74 }
75 }
76
77 // TestHTLCRejectsNonsense: a short key or a zero locktime would pay a script nobody can spend
78 // as intended, so it is refused rather than built.
79 func TestHTLCRejectsNonsense(t *testing.T) {
80 claimer, refunder, hash := fixture(t)
81
82 if _, err := HTLC(claimer[:32], refunder, hash, nodeLocktime); err == nil {
83 t.Fatal("a 32-byte claimer key was accepted")
84 }
85
86 if _, err := HTLC(claimer, refunder, hash, 0); err == nil {
87 t.Fatal("a zero locktime was accepted")
88 }
89
90 if _, err := HTLC(claimer, nil, hash, nodeLocktime); err == nil {
91 t.Fatal("an empty refunder key was accepted")
92 }
93 }
94
95 // TestLocktimeIsPushedMinimally: 500 needs two bytes, 16 needs one, 70000 needs three.
96 func TestLocktimeIsPushedMinimally(t *testing.T) {
97 cases := map[uint32]int{1: 1, 255: 1, 256: 2, 500: 2, 65535: 2, 65536: 3, 1 << 24: 4}
98
99 for locktime, want := range cases {
100 if got := len(locktimeBytes(locktime)); got != want {
101 t.Fatalf("%d is %d bytes, want %d", locktime, got, want)
102 }
103 }
104 }
105