github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/bc/types/merkle_test.go (about) 1 package types 2 3 import ( 4 "encoding/hex" 5 "strings" 6 7 "testing" 8 "time" 9 10 "github.com/bytom/bytom/protocol/bc" 11 "github.com/bytom/bytom/protocol/vm" 12 "github.com/bytom/bytom/testutil" 13 ) 14 15 func TestMerkleRoot(t *testing.T) { 16 cases := []struct { 17 witnesses [][][]byte 18 want bc.Hash 19 }{{ 20 witnesses: [][][]byte{ 21 { 22 {1}, 23 []byte("00000"), 24 }, 25 }, 26 want: testutil.MustDecodeHash("fe34dbd5da0ce3656f423fd7aad7fc7e879353174d33a6446c2ed0e3f3512101"), 27 }, { 28 witnesses: [][][]byte{ 29 { 30 {1}, 31 []byte("000000"), 32 }, 33 { 34 {1}, 35 []byte("111111"), 36 }, 37 }, 38 want: testutil.MustDecodeHash("0e4b4c1af18b8f59997804d69f8f66879ad5e30027346ee003ff7c7a512e5554"), 39 }, { 40 witnesses: [][][]byte{ 41 { 42 {1}, 43 []byte("000000"), 44 }, 45 { 46 {2}, 47 []byte("111111"), 48 []byte("222222"), 49 }, 50 }, 51 want: testutil.MustDecodeHash("0e4b4c1af18b8f59997804d69f8f66879ad5e30027346ee003ff7c7a512e5554"), 52 }} 53 54 for _, c := range cases { 55 var txs []*bc.Tx 56 for _, wit := range c.witnesses { 57 txs = append(txs, NewTx(TxData{ 58 Inputs: []*TxInput{ 59 &TxInput{ 60 AssetVersion: 1, 61 TypedInput: &SpendInput{ 62 Arguments: wit, 63 SpendCommitment: SpendCommitment{ 64 AssetAmount: bc.AssetAmount{ 65 AssetId: &bc.AssetID{V0: 0}, 66 }, 67 }, 68 }, 69 }, 70 }, 71 }).Tx) 72 } 73 got, err := TxMerkleRoot(txs) 74 if err != nil { 75 t.Fatalf("unexpected error %s", err) 76 } 77 if got != c.want { 78 t.Log("witnesses", c.witnesses) 79 t.Errorf("got merkle root = %x want %x", got.Bytes(), c.want.Bytes()) 80 } 81 } 82 } 83 84 func TestMerkleRootRealTx(t *testing.T) { 85 rawTxs := []string{ 86 strings.Join([]string{ 87 "07", 88 "01", 89 "00", 90 "01", 91 "01", 92 "61", 93 "01", 94 "5f", 95 "5ac79a73db78e5c9215b37cb752f0147d1157c542bb4884908ceb97abc33fe0a", 96 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 97 "a0f280d42b", 98 "00", 99 "01", 100 "16", 101 "0014085a02ecdf934a56343aa59a3dec9d9feb86ee43", 102 "00", 103 "63", 104 "02", 105 "40", 106 "035e1ef422b4901997ad3c20c50d82e726d03cb6e8ccb5dddc20e0c09e0a6f2e0055331e2b54d9ec52cffb1c47d8fdf2f8887d55c336753637cbf8f832c7af0b", 107 "20", 108 "a29601468f08c57ca9c383d28736a9d5c7737cd483126d8db3d85490fe497b35", 109 "02", 110 "01", 111 "00", 112 "3e", 113 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 114 "a0aad1b306", 115 "01", 116 "16", 117 "0014991b78d1bf731390e2dd838c05ff37ec5146886b", 118 "00", 119 "00", 120 "01", 121 "00", 122 "3e", 123 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 124 "8086d8f024", 125 "01", 126 "16", 127 "00145ade29df622cc68d0473aa1a20fb89690451c66e", 128 "00", 129 "00", 130 }, ""), 131 strings.Join([]string{ 132 "07", 133 "01", 134 "00", 135 "02", 136 "01", 137 "61", // input + state length 138 "01", 139 "5f", // output + state length 140 "4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea", 141 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 142 "80c480c124", 143 "02", 144 "01", 145 "16", 146 "0014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e", 147 "00", // state data 148 "63", 149 "02", 150 "40", 151 "d96b8f31519c5e34ef983bb7dfb92e807df7fc1ae5a4c08846d00d4f84ebd2f8634b9e0b0374eb2508d0f989520f622aef051862c26daba0e466944e3d55d00b", 152 "20", 153 "1381d35e235813ad1e62f9a602c82abee90565639cc4573568206b55bcd2aed9", 154 "01", 155 "30", 156 "00", 157 "08", 158 "ede605460cacbf10", 159 "7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad14", 160 "80d0dbc3f402b001467b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d0125ae2054a71277cc162eb3eb21b5bd9fe54402829a53b294deaed91692a2cd8a081f9c5151ad01403a54a3ca0210d005cc9bce490478b518c405ba72e0bc1d134b739f29a73e008345229f0e061c420aa3c56a48bc1c9bf592914252ab9100e69252deeac532430f", 161 "03", 162 "0100", 163 "3e", // state length 164 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 165 "80e0e8f011", 166 "01", 167 "16", 168 "00144ab5249140ca4630729030941f59f75e507bd4d5", 169 "00", // state data 170 "00", 171 "0100", 172 "3f", // state length 173 "7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad14", 174 "80d0dbc3f402", 175 "01", 176 "16", 177 "00145ade29df622cc68d0473aa1a20fb89690451c66e", 178 "00", // state data 179 "00", 180 "0100", 181 "3e", // state length 182 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 183 "80a2c0a012", 184 "01", 185 "16", 186 "00145ade29df622cc68d0473aa1a20fb89690451c66e", 187 "00", // state data 188 "00", 189 }, ""), 190 strings.Join([]string{ 191 "07", 192 "01", 193 "00", 194 "01", 195 "01", 196 "6d", 197 "01", 198 "6b", 199 "cf24f1471d67c25a01ac84482ecdd8550229180171cae22321f87fe43d4f6a13", 200 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 201 "80b4c4c321", 202 "01", 203 "01", 204 "22", 205 "00200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac66", 206 "00", 207 "ef02", 208 "04", 209 "40", 210 "59c7a12d006fd34bf8b9b2cb2f99756e5c3c3fdca4c928b830c014819e933b01c92a99bfeb6add73a5087870a3de3465cfed2c99f736b5f77d5fbdc69d91ff00", 211 "40", 212 "b95d110d118b873a8232104a6613f0e8c6a791efa3a695c02108cebd5239c8a8471551a48f18ab8ea05d10900b485af5e95b74cd3c01044c1742e71854099c0b", 213 "40", 214 "a1b6", 215 "3dae273e3b5b757b7c61286088a934e7282e837d08d62e60d7f75eb739529cd8c6cfef2254d47a546bf8b789657ce0944fec2f7e130c8498e28cae2a9108a901ae20d441b6f375659325a04eede4fc3b74579bb08ccd05b41b99776501e22d6dca7320af6d98ca2c3cd10bf0affbfa6e86609b750523cfadb662ec963c164f05798a49209820b9f1553b03aaebe7e3f9e9222ed7db73b5079b18564042fd3b2cef74156a20271b52de5f554aa4a6f1358f1c2193617bfb3fed4546d13c4af773096a429f9420eeb4a78d8b5cb8283c221ca2d3fd96b8946b3cddee02b7ceffb8f605932588595355ad", 216 "02", 217 "0100", 218 "4a", 219 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 220 "80a0d9e61d", 221 "01", 222 "22", 223 "00206e8060ef3daca62841802dd9660b24b7dca81c1662b2d68ba8884ecbcd3e1e22", 224 "00", 225 "00", 226 "0100", 227 "3e", 228 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 229 "80d293ad03", 230 "01", 231 "16", 232 "0014ed7d3c466dbc6cc1f3a9af21267ac162f11b30a2", 233 "00", 234 "00", 235 }, ""), 236 strings.Join([]string{ 237 "07", 238 "01", 239 "00", 240 "02", 241 "01", 242 "62", 243 "01", 244 "60", 245 "4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea", 246 "0dafd0f0e42f06f3bf9a8cf5787519d3860650f27a2b3393d34e1fe06e89b469", 247 "ddc3f8c2f402", 248 "00", 249 "01", 250 "16", 251 "00141da7f908979e521bf2ba12d280b2c84fc1d02441", 252 "00", 253 "63", 254 "02", 255 "40", 256 "9524d0d817176eeb718ce45671d95831cdb138d27289aa8a920104e38a8cab8a7dc8cc3fb60d65aa337b719aed0f696fb12610bfe68add89169a47ac1241e000", 257 "20", 258 "33444e1b57524161af3899e50fdfe270a90a1ea97fe38e86019a1e252667fb2d", 259 "01", 260 "62", 261 "01", 262 "60", 263 "ed3181c99ca80db720231aee6948e1183bfe29c64208c1769afa7f938d3b2cf0", 264 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 265 "809cd2b0f402", 266 "01", 267 "01", 268 "16", 269 "0014cfbccfac5018ad4b4bfbcb1fab834e3c85037460", 270 "00", 271 "63", 272 "02", 273 "40", 274 "65beb1da2f0840188af0e3c0127b158f7a2a36f1612499694a731df1e3a9d1abe6694c42986b8700aa9856f59cb3692ee88d68b20d1278f05592fb253c58bd05", 275 "20", 276 "e5966eee4092eeefdd805b06f2ad368bb9392edec20998993ebe2a929052c1ce", 277 "03", 278 "0100", 279 "3f", 280 "0dafd0f0e42f06f3bf9a8cf5787519d3860650f27a2b3393d34e1fe06e89b469", 281 "ddfbc8a2cf02", 282 "01", 283 "16", 284 "0014583c0323603dd397ba5414255adc80b076cf232b", 285 "00", 286 "00", 287 "0100", 288 "3e", 289 "0dafd0f0e42f06f3bf9a8cf5787519d3860650f27a2b3393d34e1fe06e89b469", 290 "80c8afa025", 291 "01", 292 "16", 293 "0014fdb3e6abf7f430fdabb53484ca2469103b2af1b5", 294 "00", 295 "00", 296 "0100", 297 "3f", 298 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 299 "80dafa80f402", 300 "01", 301 "16001408e75789f47d2a39622e5a940fa918260bf44c54", 302 "00", 303 "00", 304 }, ""), 305 strings.Join([]string{ 306 "07", 307 "01", 308 "00", 309 "01", 310 "01", 311 "6e", 312 "01", 313 "6c", 314 "1f134a47da4f6df00822935e02a07514718ea99ce5ac4e07bd6c204e098eb525", 315 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 316 "808a858fa702", 317 "00", 318 "01", 319 "22", 320 "00206205ec178dc1ac6ea05ea01bb0fcda6aa978173026fa75204a101bdad7bd6b48", 321 "00", 322 "8901", 323 "02", 324 "40", 325 "d8d5bbf4969fba52df8fba06f75c5de0f51b2bd5f902bf234591f90e78bae20bfb5b7904cb83a1d6577c431f644d37722b432df9d64718b8300e3ab74a871a00", 326 "46ae", 327 "2068003e53d467b6d81beaf1e7bd9b60a5ffedc79b36ce14ecd1f30a2dcbcd0551200449030407a3a1fa0731f7f784a72c325b5ce4d534fc3cf8fb7140536ba928605152ad", 328 "02", 329 "0100", 330 "4b", 331 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 332 "80f699b2a302", 333 "01", 334 "22", 335 "00209a0b4b27fde7d29d3b465d20eb2e19f4bda3a873d19d11f4cba53958bde92ed0", 336 "00", 337 "00", 338 "0100", 339 "3e", 340 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 341 "80b3ffc403", 342 "01", 343 "16", 344 "0014ed7d3c466dbc6cc1f3a9af21267ac162f11b30a2", 345 "00", 346 "00", 347 }, ""), 348 } 349 wantMerkleRoot := "a23ae3e435a7bdfb52cb92b58be6e658982fd883283caf9547f9df50d65881df" 350 351 var txs []*bc.Tx 352 for _, rawTx := range rawTxs { 353 tx := Tx{} 354 if err := tx.UnmarshalText([]byte(rawTx)); err != nil { 355 t.Fatal(err) 356 } 357 358 txs = append(txs, tx.Tx) 359 } 360 361 gotMerkleRoot, err := TxMerkleRoot(txs) 362 if err != nil { 363 t.Fatal(err) 364 } 365 366 if wantMerkleRoot != gotMerkleRoot.String() { 367 t.Errorf("got merkle root:%s, want merkle root:%s", gotMerkleRoot.String(), wantMerkleRoot) 368 } 369 } 370 371 func TestDuplicateLeaves(t *testing.T) { 372 trueProg := []byte{byte(vm.OP_TRUE)} 373 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash) 374 txs := make([]*bc.Tx, 6) 375 for i := uint64(0); i < 6; i++ { 376 now := []byte(time.Now().String()) 377 txs[i] = NewTx(TxData{ 378 Version: 1, 379 Inputs: []*TxInput{NewIssuanceInput(now, i, trueProg, nil, nil)}, 380 Outputs: []*TxOutput{NewOriginalTxOutput(assetID, i, trueProg, nil)}, 381 }).Tx 382 } 383 384 // first, get the root of an unbalanced tree 385 txns := []*bc.Tx{txs[5], txs[4], txs[3], txs[2], txs[1], txs[0]} 386 root1, err := TxMerkleRoot(txns) 387 if err != nil { 388 t.Fatalf("unexpected error %s", err) 389 } 390 391 // now, get the root of a balanced tree that repeats leaves 0 and 1 392 txns = []*bc.Tx{txs[5], txs[4], txs[3], txs[2], txs[1], txs[0], txs[1], txs[0]} 393 root2, err := TxMerkleRoot(txns) 394 if err != nil { 395 t.Fatalf("unexpected error %s", err) 396 } 397 398 if root1 == root2 { 399 t.Error("forged merkle tree by duplicating some leaves") 400 } 401 } 402 403 func TestAllDuplicateLeaves(t *testing.T) { 404 trueProg := []byte{byte(vm.OP_TRUE)} 405 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash) 406 now := []byte(time.Now().String()) 407 issuanceInp := NewIssuanceInput(now, 1, trueProg, nil, nil) 408 409 tx := NewTx(TxData{ 410 Version: 1, 411 Inputs: []*TxInput{issuanceInp}, 412 Outputs: []*TxOutput{NewOriginalTxOutput(assetID, 1, trueProg, nil)}, 413 }).Tx 414 tx1, tx2, tx3, tx4, tx5, tx6 := tx, tx, tx, tx, tx, tx 415 416 // first, get the root of an unbalanced tree 417 txs := []*bc.Tx{tx6, tx5, tx4, tx3, tx2, tx1} 418 root1, err := TxMerkleRoot(txs) 419 if err != nil { 420 t.Fatalf("unexpected error %s", err) 421 } 422 423 // now, get the root of a balanced tree that repeats leaves 5 and 6 424 txs = []*bc.Tx{tx6, tx5, tx6, tx5, tx4, tx3, tx2, tx1} 425 root2, err := TxMerkleRoot(txs) 426 if err != nil { 427 t.Fatalf("unexpected error %s", err) 428 } 429 430 if root1 == root2 { 431 t.Error("forged merkle tree with all duplicate leaves") 432 } 433 } 434 435 func TestTxMerkleProof(t *testing.T) { 436 cases := []struct { 437 txCount int 438 relatedTxIndexes []int 439 expectHashLen int 440 expectFlags []uint8 441 }{ 442 { 443 txCount: 10, 444 relatedTxIndexes: []int{0, 3, 7, 8}, 445 expectHashLen: 9, 446 expectFlags: []uint8{1, 1, 1, 1, 2, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 2, 0}, 447 }, 448 { 449 txCount: 10, 450 relatedTxIndexes: []int{}, 451 expectHashLen: 1, 452 expectFlags: []uint8{0}, 453 }, 454 { 455 txCount: 1, 456 relatedTxIndexes: []int{0}, 457 expectHashLen: 1, 458 expectFlags: []uint8{2}, 459 }, 460 { 461 txCount: 19, 462 relatedTxIndexes: []int{1, 3, 5, 7, 11, 15}, 463 expectHashLen: 15, 464 expectFlags: []uint8{1, 1, 1, 1, 1, 0, 2, 1, 0, 2, 1, 1, 0, 2, 1, 0, 2, 1, 1, 0, 1, 0, 2, 1, 0, 1, 0, 2, 0}, 465 }, 466 } 467 for _, c := range cases { 468 txs, bcTxs := mockTransactions(c.txCount) 469 470 var nodes []merkleNode 471 for _, tx := range txs { 472 nodes = append(nodes, tx.ID) 473 } 474 tree := buildMerkleTree(nodes) 475 root, err := TxMerkleRoot(bcTxs) 476 if err != nil { 477 t.Fatalf("unexpected error %s", err) 478 } 479 if tree.hash != root { 480 t.Error("build tree fail") 481 } 482 483 var relatedTx []*Tx 484 for _, index := range c.relatedTxIndexes { 485 relatedTx = append(relatedTx, txs[index]) 486 } 487 proofHashes, flags := GetTxMerkleTreeProof(txs, relatedTx) 488 if !testutil.DeepEqual(flags, c.expectFlags) { 489 t.Error("The flags is not equals expect flags", flags, c.expectFlags) 490 } 491 if len(proofHashes) != c.expectHashLen { 492 t.Error("The length proof hashes is not equals expect length") 493 } 494 var ids []*bc.Hash 495 for _, tx := range relatedTx { 496 ids = append(ids, &tx.ID) 497 } 498 if !ValidateTxMerkleTreeProof(proofHashes, flags, ids, root) { 499 t.Error("Merkle tree validate fail") 500 } 501 } 502 } 503 504 func TestUglyValidateTxMerkleProof(t *testing.T) { 505 cases := []struct { 506 hashes []string 507 flags []uint8 508 relatedHashes []string 509 root string 510 expectResult bool 511 }{ 512 { 513 hashes: []string{}, 514 flags: []uint8{}, 515 relatedHashes: []string{}, 516 root: "", 517 expectResult: false, 518 }, 519 { 520 hashes: []string{}, 521 flags: []uint8{1, 1, 1, 1, 2, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 2, 0}, 522 relatedHashes: []string{}, 523 root: "", 524 expectResult: false, 525 }, 526 { 527 hashes: []string{ 528 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 529 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 530 }, 531 flags: []uint8{}, 532 relatedHashes: []string{}, 533 root: "", 534 expectResult: false, 535 }, 536 { 537 hashes: []string{}, 538 flags: []uint8{}, 539 relatedHashes: []string{ 540 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 541 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 542 }, 543 root: "", 544 expectResult: false, 545 }, 546 { 547 hashes: []string{}, 548 flags: []uint8{1, 1, 0, 2, 1, 2, 1, 0, 1}, 549 relatedHashes: []string{ 550 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 551 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 552 }, 553 root: "281138e0a9ea19505844bd61a2f5843787035782c093da74d12b5fba73eeeb07", 554 }, 555 { 556 hashes: []string{ 557 "68f03ea2b02a21ad944d1a43ad6152a7fa6a7ed4101d59be62594dd30ef2a558", 558 }, 559 flags: []uint8{}, 560 relatedHashes: []string{ 561 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 562 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 563 }, 564 root: "281138e0a9ea19505844bd61a2f5843787035782c093da74d12b5fba73eeeb07", 565 expectResult: false, 566 }, 567 { 568 hashes: []string{ 569 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 570 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 571 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 572 }, 573 flags: []uint8{1, 1, 0, 2, 0}, 574 relatedHashes: []string{ 575 "504af455e328e7dd39bbc059529851946d54ee8b459b11b3aac4a0feeb474487", 576 }, 577 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 578 expectResult: true, 579 }, 580 // flags and hashes is correct, but relatedHashes has hash that does not exist 581 { 582 hashes: []string{ 583 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 584 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 585 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 586 }, 587 flags: []uint8{1, 1, 0, 2, 0}, 588 relatedHashes: []string{ 589 "504af455e328e7dd39bbc059529851946d54ee8b459b11b3aac4a0feeb474487", 590 "281138e0a9ea19505844bd61a2f5843787035782c093da74d12b5fba73eeeb07", 591 }, 592 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 593 expectResult: false, 594 }, 595 // flags and hashes is correct, but relatedHashes is not enough 596 { 597 hashes: []string{ 598 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 599 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 600 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 601 }, 602 flags: []uint8{1, 1, 0, 2, 0}, 603 relatedHashes: []string{}, 604 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 605 expectResult: false, 606 }, 607 // flags is correct, but hashes has additional hash at the end 608 { 609 hashes: []string{ 610 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 611 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 612 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 613 "5a06c90136e81c0f9cad29725e69edc6d21bd6fb0641265f9c4b6bb6840b37dd", 614 }, 615 flags: []uint8{1, 1, 0, 2, 0}, 616 relatedHashes: []string{ 617 "504af455e328e7dd39bbc059529851946d54ee8b459b11b3aac4a0feeb474487", 618 }, 619 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 620 expectResult: true, 621 }, 622 } 623 624 for _, c := range cases { 625 var hashes, relatedHashes []*bc.Hash 626 var hashBytes, rootBytes [32]byte 627 var err error 628 for _, hashStr := range c.hashes { 629 if hashBytes, err = convertHashStr2Bytes(hashStr); err != nil { 630 t.Fatal(err) 631 } 632 633 hash := bc.NewHash(hashBytes) 634 hashes = append(hashes, &hash) 635 } 636 for _, hashStr := range c.relatedHashes { 637 if hashBytes, err = convertHashStr2Bytes(hashStr); err != nil { 638 t.Fatal(err) 639 } 640 641 hash := bc.NewHash(hashBytes) 642 relatedHashes = append(relatedHashes, &hash) 643 } 644 if rootBytes, err = convertHashStr2Bytes(c.root); err != nil { 645 t.Fatal(err) 646 } 647 648 root := bc.NewHash(rootBytes) 649 if ValidateTxMerkleTreeProof(hashes, c.flags, relatedHashes, root) != c.expectResult { 650 t.Error("Validate merkle tree proof fail") 651 } 652 } 653 } 654 655 func convertHashStr2Bytes(hashStr string) ([32]byte, error) { 656 var result [32]byte 657 hashBytes, err := hex.DecodeString(hashStr) 658 if err != nil { 659 return result, err 660 } 661 copy(result[:], hashBytes) 662 return result, nil 663 } 664 665 func mockTransactions(txCount int) ([]*Tx, []*bc.Tx) { 666 var txs []*Tx 667 var bcTxs []*bc.Tx 668 trueProg := []byte{byte(vm.OP_TRUE)} 669 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash) 670 for i := 0; i < txCount; i++ { 671 now := []byte(time.Now().String()) 672 issuanceInp := NewIssuanceInput(now, 1, trueProg, nil, nil) 673 tx := NewTx(TxData{ 674 Version: 1, 675 Inputs: []*TxInput{issuanceInp}, 676 Outputs: []*TxOutput{NewOriginalTxOutput(assetID, 1, trueProg, nil)}, 677 }) 678 txs = append(txs, tx) 679 bcTxs = append(bcTxs, tx.Tx) 680 } 681 return txs, bcTxs 682 }