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