decred.org/dcrdex@v1.0.5/dex/networks/zec/tx_test.go (about) 1 package zec 2 3 import ( 4 "bytes" 5 _ "embed" 6 "encoding/binary" 7 "encoding/hex" 8 "fmt" 9 "testing" 10 11 "github.com/btcsuite/btcd/txscript" 12 ) 13 14 var ( 15 //go:embed test-data/shielded_sapling_tx.dat 16 shieldedSaplingTx []byte 17 //go:embed test-data/unshielded_sapling_tx.dat 18 unshieldedSaplingTx []byte // mainnet 19 //go:embed test-data/unshielded_orchard_tx.dat 20 unshieldedOrchardTx []byte // testnet 21 //go:embed test-data/v4_sighash_vector_tx.dat 22 v4SighashVectorTx []byte 23 //go:embed test-data/v3_tx.dat 24 v3Tx []byte 25 //go:embed test-data/v2_joinsplit_tx.dat 26 v2JoinSplit []byte 27 ) 28 29 func TestTxDeserializeV2(t *testing.T) { 30 // testnet tx 66bd29f14043843327fae377bd47659c6f02efd3aa62992a6ffa15ddd5fcbaff 31 tx, err := DeserializeTx(v2JoinSplit) 32 if err != nil { 33 t.Fatalf("error decoding tx: %v", err) 34 } 35 if len(tx.VJoinSplit) != 1 { 36 t.Fatalf("expected 1 vJoinSplit. saw %d", len(tx.VJoinSplit)) 37 } 38 if tx.SerializeSize() != uint64(len(v2JoinSplit)) { 39 t.Fatalf("wrong serialized size. wanted %d, got %d", len(v2JoinSplit), tx.SerializeSize()) 40 } 41 js := tx.VJoinSplit[0] 42 const expNew = 5338489 43 if js.New != expNew { 44 t.Fatalf("wrong joinsplit new. expected %d, got %d", expNew, js.New) 45 } 46 } 47 48 func TestTxDeserializeV3(t *testing.T) { 49 tx, err := DeserializeTx(v3Tx) 50 if err != nil { 51 t.Fatalf("error decoding tx: %v", err) 52 } 53 54 const expHash = "fc546132ad9c7bee2a2390ccafc54f29c23bf2f311233f89294665a6c4b7cfa7" 55 if tx.TxHash().String() != expHash { 56 t.Fatalf("wrong v3 hash") 57 } 58 if tx.SerializeSize() != uint64(len(v3Tx)) { 59 t.Fatalf("wrong serialized size. wanted %d, got %d", len(v3Tx), tx.SerializeSize()) 60 } 61 } 62 63 func TestTxDeserializeV4(t *testing.T) { 64 tx, err := DeserializeTx(unshieldedSaplingTx) 65 if err != nil { 66 t.Fatalf("error decoding tx: %v", err) 67 } 68 69 const expHash = "fb70397806afddcc07b9607e844ff29f2fb09e9972a051c3fe4d56fe18147e77" 70 if tx.TxHash().String() != expHash { 71 t.Fatalf("wrong v4 hash") 72 } 73 if tx.SerializeSize() != uint64(len(unshieldedSaplingTx)) { 74 t.Fatalf("wrong serialized size. wanted %d, got %d", len(unshieldedSaplingTx), tx.SerializeSize()) 75 } 76 77 if len(tx.TxIn) != 1 { 78 t.Fatalf("expected 1 input, got %d", len(tx.TxIn)) 79 } 80 81 txIn := tx.TxIn[0] 82 if txIn.PreviousOutPoint.Hash.String() != "df0547ac001d335441bd621779e8946a1224949a014871b5f2a349352a270d69" { 83 t.Fatal("wrong previous outpoint hash") 84 } 85 if txIn.PreviousOutPoint.Index != 0 { 86 t.Fatal("wrong previous outpoint index") 87 } 88 if hex.EncodeToString(txIn.SignatureScript) != "47304402201656a4834651f39ac52eb866042ca7ede052ac843a914da4790573122c8e2ab302200af617e856abf4f8fb8d8086825dc63766943b4866ad3d6b4c8f222017c9b402012102d547eb1c5672a4d212de3c797a87b2b8fe731c2b502db6d7ad044850fe11d78f" { 89 t.Fatal("wrong signature script") 90 } 91 if txIn.Sequence != 4294967295 { 92 t.Fatalf("wrong sequence") 93 } 94 95 if len(tx.TxOut) != 2 { 96 t.Fatalf("expected 2 outputs, got %d", len(tx.TxOut)) 97 } 98 txOut := tx.TxOut[1] 99 if txOut.Value != 41408718 { 100 t.Fatal("wrong value") 101 } 102 if hex.EncodeToString(txOut.PkScript) != "76a9144ff496917bae33309a8ad70bec81355bbf92988988ac" { 103 t.Fatalf("wrong pk script") 104 } 105 106 if sz := CalcTxSize(tx.MsgTx); sz != uint64(len(unshieldedSaplingTx)) { 107 t.Fatalf("wrong calculated tx size. wanted %d, got %d", len(unshieldedSaplingTx), sz) 108 } 109 110 serializedTx, err := tx.Bytes() 111 if err != nil { 112 t.Fatalf("error re-serializing: %v", err) 113 } 114 if !bytes.Equal(serializedTx, unshieldedSaplingTx) { 115 t.Fatalf("re-encoding does not match original") 116 } 117 } 118 119 func TestTxDeserializeV5(t *testing.T) { 120 tx, err := DeserializeTx(unshieldedOrchardTx) 121 if err != nil { 122 t.Fatalf("error decoding tx: %v", err) 123 } 124 125 const expHash = "a2a3e99169bad144e490708bbd9d4daf8dc9017397ad11e7a1e75a62f9919324" // testnet 126 if tx.TxHash().String() != expHash { 127 t.Fatalf("wrong v5 hash") 128 } 129 if tx.SerializeSize() != uint64(len(unshieldedOrchardTx)) { 130 t.Fatalf("wrong serialized size. wanted %d, got %d", len(unshieldedOrchardTx), tx.SerializeSize()) 131 } 132 133 serializedTx, err := tx.Bytes() 134 if err != nil { 135 t.Fatalf("error re-serializing: %v", err) 136 } 137 if !bytes.Equal(serializedTx, unshieldedOrchardTx) { 138 fmt.Println("original:", hex.EncodeToString(unshieldedOrchardTx)) 139 fmt.Println("re-encode:", hex.EncodeToString(serializedTx)) 140 t.Fatalf("re-encoding does not match original") 141 } 142 } 143 144 func TestShieldedTx(t *testing.T) { 145 // Just make sure it doesn't error. 146 tx, err := DeserializeTx(shieldedSaplingTx) 147 if err != nil { 148 t.Fatalf("error decoding tx: %v", err) 149 } 150 if tx.SerializeSize() != uint64(len(shieldedSaplingTx)) { 151 t.Fatalf("wrong serialized size. wanted %d, got %d", len(shieldedSaplingTx), tx.SerializeSize()) 152 } 153 } 154 155 func TestV5SigDigest(t *testing.T) { 156 // test vector generated with github.com/zcash-hackworks/zcash-testvectors 157 txB, _ := hex.DecodeString("050000800a27a726b4d0d6c27a8f739a2d6f2c0201e152a" + 158 "8049e294c4d6e66b164939daffa2ef6ee6921481cdd86b3cc4318d9614fc820905d045" + 159 "3516aaca3f2498800000000") 160 sigDigest, _ := hex.DecodeString("19e9b271cf0b6f9d60b2834eb16802ce1aa41cd8e96f50bd38dd8f4c4c82616f") 161 transparentDigest, _ := hex.DecodeString("f31a4521a8d04d8e1f01a614ad0627278c870b7c9a48306cc74587a349dd92b9") 162 163 const vin = 0 164 prevScript, _ := hex.DecodeString("650051") 165 const prevValue = 1800841178198868 166 167 tx, err := DeserializeTx(txB) 168 if err != nil { 169 t.Fatalf("error decoding tx: %v", err) 170 } 171 172 prevs, _ := hex.DecodeString("223b625f83e3cd9c127ad107fdb5402bfcd5f10681867f2fde8bcfb2aa2447ae") 173 amts, _ := hex.DecodeString("765008be6611a6e2a6520aa72fb67dc2d944577c26544d924a00d50ea7c58855") 174 scripts, _ := hex.DecodeString("1e43079ba1fa40d65beee6dd9b77b48017283b16438a852def75a5096cfea9b7") 175 seqs, _ := hex.DecodeString("17de0287f8f0c573fe74c52d1bd0e6b429cc9201390ededf4a625f5769e41716") 176 outputs, _ := hex.DecodeString("25f311cc149ecccef0e8ca8c9facd897ef88806008bc15818069470db9f84a37") 177 txinDigest, _ := hex.DecodeString("bb4ab0249df12a12df3d0d160f9ca6fbb0658c30dd44fd62d237994e77f2c1c6") 178 179 prevoutsDigest, err := tx.hashPrevOutsSigV5(false) 180 if err != nil { 181 return 182 } 183 if !bytes.Equal(prevs, prevoutsDigest[:]) { 184 t.Fatalf("wrong prevoutsDigest") 185 } 186 187 amtsDigest, err := tx.hashAmountsSig(false, []int64{prevValue}) 188 if err != nil { 189 return 190 } 191 if !bytes.Equal(amts, amtsDigest[:]) { 192 t.Fatalf("wrong amtsDigest") 193 } 194 195 prevScriptsDigest, err := tx.hashPrevScriptsSig(false, [][]byte{prevScript}) 196 if err != nil { 197 return 198 } 199 if !bytes.Equal(scripts, prevScriptsDigest[:]) { 200 t.Fatalf("wrong prevScriptsDigest") 201 } 202 203 seqsDigest, err := tx.hashSequenceSigV5(false) 204 if err != nil { 205 return 206 } 207 if !bytes.Equal(seqs, seqsDigest[:]) { 208 t.Fatalf("wrong seqsDigest") 209 } 210 211 outputsDigest, err := tx.hashOutputsSigV5(false) 212 if err != nil { 213 return 214 } 215 if !bytes.Equal(outputs, outputsDigest[:]) { 216 t.Fatalf("wrong outputsDigest") 217 } 218 219 txInsDigest, err := tx.hashTxInSig(vin, prevValue, prevScript) 220 if err != nil { 221 return 222 } 223 if !bytes.Equal(txinDigest, txInsDigest[:]) { 224 t.Fatalf("wrong txInsDigest") 225 } 226 227 td, err := tx.transparentSigDigestV5(0, txscript.SigHashAll, []int64{prevValue}, [][]byte{prevScript}) 228 if err != nil { 229 t.Fatalf("transparentSigDigest error: %v", err) 230 } 231 232 if !bytes.Equal(td[:], transparentDigest) { 233 t.Fatalf("wrong digest") 234 } 235 236 sd, err := tx.SignatureDigest(0, txscript.SigHashAll, nil, []int64{prevValue}, [][]byte{prevScript}) 237 if err != nil { 238 t.Fatalf("transparentSigDigest error: %v", err) 239 } 240 241 if !bytes.Equal(sd[:], sigDigest) { 242 t.Fatalf("wrong signatureDigest") 243 } 244 } 245 246 func TestV4SigDigest(t *testing.T) { 247 // Test Vector 3 from ZIP-0243, but fixed. 248 // Preimage and test vector in ZIP-0243 are WRONG!!!! 249 // The test vector's preimage DOES NOT include a varint for script size, but 250 // it should, and I modified zclassicd to log the preimage just to make 251 // sure. I had run into this problem in the Zcash docs before too. When they 252 // say "(serialized as scripts inside CTxOuts)", that's apparently code for 253 // adding the varint, but the guy tasked with generating test vectors 254 // apparently didn't get it either. 255 tx, err := DeserializeTx(v4SighashVectorTx) 256 if err != nil { 257 t.Fatalf("error decoding tx: %v", err) 258 } 259 amtLE, _ := hex.DecodeString("80f0fa0200000000") 260 val := binary.LittleEndian.Uint64(amtLE) 261 vals := []int64{int64(val)} 262 263 script, _ := hex.DecodeString("1976a914507173527b4c3318a2aecd793bf1cfed705950cf88ac") 264 pimg, err := tx.sighashPreimageV4(txscript.SigHashAll, 0, vals, script) 265 if err != nil { 266 t.Fatalf("sighashPreimageV4 error: %v", err) 267 } 268 269 expPimg, _ := hex.DecodeString( 270 "0400008085202f89fae31b8dec7b0b77e2c8d6b6eb0e7e4e55abc6574c26dd44464d94" + 271 "08a8e33f116c80d37f12d89b6f17ff198723e7db1247c4811d1a695d74d930f99e9841" + 272 "8790d2b04118469b7810a0d1cc59568320aad25a84f407ecac40b4f605a4e686845400" + 273 "0000000000000000000000000000000000000000000000000000000000000000000000" + 274 "0000000000000000000000000000000000000000000000000000000000000000000000" + 275 "0000000000000000000000000000000000000000000000000029b0040048b004000000" + 276 "00000000000001000000a8c685478265f4c14dada651969c45a65e1aeb8cd6791f2f5b" + 277 "b6a1d9952104d9010000001a1976a914507173527b4c3318a2aecd793bf1cfed705950" + 278 "cf88ac80f0fa0200000000feffffff", 279 ) 280 if !bytes.Equal(pimg, expPimg) { 281 fmt.Println("preimage:", hex.EncodeToString(pimg)) 282 t.Fatal("wrong preimage") 283 } 284 // After fixing the vector's preimage, the sighash obviously changed, but 285 // I'll leave this here to maintain expected behavior in case of future code 286 // updates. 287 expSighash, _ := hex.DecodeString("a358eb2ce8b214facba92761be09cc3e889e91a2e301146e8e40b5a6417da3d8") 288 h, err := tx.SignatureDigest(0, txscript.SigHashAll, script, vals, nil) 289 if err != nil { 290 t.Fatalf("SignatureDigest error: %v", err) 291 } 292 if !bytes.Equal(expSighash, h[:]) { 293 fmt.Println("sighash:", hex.EncodeToString(h[:])) 294 t.Fatal("wrong sighash") 295 } 296 }