package script import ( "encoding/hex" "testing" ) // The vector below came out of the rig node itself: `utxoupdatepsbt` filled in the witness // script for this descriptor, and `deriveaddresses` gave the address. It is the only thing // that makes this compiler trustworthy. const ( nodeClaimer = "03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd" nodeRefunder = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" nodeHash = "0000000000000000000000000000000000000000000000000000000000000001" nodeLocktime = 500 nodeScript = "632103a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bdad82012088a820" + "0000000000000000000000000000000000000000000000000000000000000001876702f401b169210279be66" + "7ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac68" nodeAddress = "bcrt1qvsxuue8tp8gnfw02ynzxv5ns4ecpp8k4kjrx7eav02qv3jgad7tqzur2fy" ) // fixture decodes the vector. func fixture(t *testing.T) (claimer, refunder []byte, hash [32]byte) { t.Helper() var err error if claimer, err = hex.DecodeString(nodeClaimer); err != nil { t.Fatal(err) } if refunder, err = hex.DecodeString(nodeRefunder); err != nil { t.Fatal(err) } raw, err := hex.DecodeString(nodeHash) if err != nil { t.Fatal(err) } copy(hash[:], raw) return claimer, refunder, hash } // TestHTLCMatchesTheNode: the compiler produces the bytes the node compiled. func TestHTLCMatchesTheNode(t *testing.T) { claimer, refunder, hash := fixture(t) witness, err := HTLC(claimer, refunder, hash, nodeLocktime) if err != nil { t.Fatal(err) } if got := hex.EncodeToString(witness); got != nodeScript { t.Fatalf("the script is\n%s\nwant\n%s", got, nodeScript) } } // TestHTLCAddressMatchesTheNode: and the address that script pays to. func TestHTLCAddressMatchesTheNode(t *testing.T) { claimer, refunder, hash := fixture(t) address, err := HTLCAddress("bcrt", claimer, refunder, hash, nodeLocktime) if err != nil { t.Fatal(err) } if address != nodeAddress { t.Fatalf("the address is %s, want %s", address, nodeAddress) } } // TestHTLCRejectsNonsense: a short key or a zero locktime would pay a script nobody can spend // as intended, so it is refused rather than built. func TestHTLCRejectsNonsense(t *testing.T) { claimer, refunder, hash := fixture(t) if _, err := HTLC(claimer[:32], refunder, hash, nodeLocktime); err == nil { t.Fatal("a 32-byte claimer key was accepted") } if _, err := HTLC(claimer, refunder, hash, 0); err == nil { t.Fatal("a zero locktime was accepted") } if _, err := HTLC(claimer, nil, hash, nodeLocktime); err == nil { t.Fatal("an empty refunder key was accepted") } } // TestLocktimeIsPushedMinimally: 500 needs two bytes, 16 needs one, 70000 needs three. func TestLocktimeIsPushedMinimally(t *testing.T) { cases := map[uint32]int{1: 1, 255: 1, 256: 2, 500: 2, 65535: 2, 65536: 3, 1 << 24: 4} for locktime, want := range cases { if got := len(locktimeBytes(locktime)); got != want { t.Fatalf("%d is %d bytes, want %d", locktime, got, want) } } }