github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/bc/types/merkle_test.go (about) 1 package types 2 3 import ( 4 "encoding/hex" 5 6 "math/rand" 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 "070100010160015e5ac79a73db78e5c9215b37cb752f0147d1157c542bb4884908ceb97abc33fe0affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0f280d42b0001160014085a02ecdf934a56343aa59a3dec9d9feb86ee43630240035e1ef422b4901997ad3c20c50d82e726d03cb6e8ccb5dddc20e0c09e0a6f2e0055331e2b54d9ec52cffb1c47d8fdf2f8887d55c336753637cbf8f832c7af0b20a29601468f08c57ca9c383d28736a9d5c7737cd483126d8db3d85490fe497b3502013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0aad1b30601160014991b78d1bf731390e2dd838c05ff37ec5146886b00013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8086d8f024011600145ade29df622cc68d0473aa1a20fb89690451c66e00", 87 "070100020160015e4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80c480c1240201160014cb9f2391bafe2bc1159b2c4c8a0f17ba1b4dd94e630240d96b8f31519c5e34ef983bb7dfb92e807df7fc1ae5a4c08846d00d4f84ebd2f8634b9e0b0374eb2508d0f989520f622aef051862c26daba0e466944e3d55d00b201381d35e235813ad1e62f9a602c82abee90565639cc4573568206b55bcd2aed901300008ede605460cacbf107b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad1480d0dbc3f402b001467b0a202022646563696d616c73223a20382c0a2020226465736372697074696f6e223a207b7d2c0a2020226e616d65223a2022222c0a20202273796d626f6c223a2022220a7d0125ae2054a71277cc162eb3eb21b5bd9fe54402829a53b294deaed91692a2cd8a081f9c5151ad01403a54a3ca0210d005cc9bce490478b518c405ba72e0bc1d134b739f29a73e008345229f0e061c420aa3c56a48bc1c9bf592914252ab9100e69252deeac532430f03013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80e0e8f011011600144ab5249140ca4630729030941f59f75e507bd4d500013e7b38dc897329a288ea31031724f5c55bcafec80468a546955023380af2faad1480d0dbc3f402011600145ade29df622cc68d0473aa1a20fb89690451c66e00013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80a2c0a012011600145ade29df622cc68d0473aa1a20fb89690451c66e00", 88 "07010001016c016acf24f1471d67c25a01ac84482ecdd8550229180171cae22321f87fe43d4f6a13ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80b4c4c32101012200200824e931fb806bd77fdcd291aad3bd0a4493443a4120062bd659e64a3e0bac66ef02044059c7a12d006fd34bf8b9b2cb2f99756e5c3c3fdca4c928b830c014819e933b01c92a99bfeb6add73a5087870a3de3465cfed2c99f736b5f77d5fbdc69d91ff0040b95d110d118b873a8232104a6613f0e8c6a791efa3a695c02108cebd5239c8a8471551a48f18ab8ea05d10900b485af5e95b74cd3c01044c1742e71854099c0b40a1b63dae273e3b5b757b7c61286088a934e7282e837d08d62e60d7f75eb739529cd8c6cfef2254d47a546bf8b789657ce0944fec2f7e130c8498e28cae2a9108a901ae20d441b6f375659325a04eede4fc3b74579bb08ccd05b41b99776501e22d6dca7320af6d98ca2c3cd10bf0affbfa6e86609b750523cfadb662ec963c164f05798a49209820b9f1553b03aaebe7e3f9e9222ed7db73b5079b18564042fd3b2cef74156a20271b52de5f554aa4a6f1358f1c2193617bfb3fed4546d13c4af773096a429f9420eeb4a78d8b5cb8283c221ca2d3fd96b8946b3cddee02b7ceffb8f605932588595355ad020149ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80a0d9e61d012200206e8060ef3daca62841802dd9660b24b7dca81c1662b2d68ba8884ecbcd3e1e2200013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80d293ad0301160014ed7d3c466dbc6cc1f3a9af21267ac162f11b30a200", 89 "070100020161015f4b5cb973f5bef4eadde4c89b92ee73312b940e84164da0594149554cc8a2adea0dafd0f0e42f06f3bf9a8cf5787519d3860650f27a2b3393d34e1fe06e89b469ddc3f8c2f40200011600141da7f908979e521bf2ba12d280b2c84fc1d024416302409524d0d817176eeb718ce45671d95831cdb138d27289aa8a920104e38a8cab8a7dc8cc3fb60d65aa337b719aed0f696fb12610bfe68add89169a47ac1241e0002033444e1b57524161af3899e50fdfe270a90a1ea97fe38e86019a1e252667fb2d0161015fed3181c99ca80db720231aee6948e1183bfe29c64208c1769afa7f938d3b2cf0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff809cd2b0f4020101160014cfbccfac5018ad4b4bfbcb1fab834e3c8503746063024065beb1da2f0840188af0e3c0127b158f7a2a36f1612499694a731df1e3a9d1abe6694c42986b8700aa9856f59cb3692ee88d68b20d1278f05592fb253c58bd0520e5966eee4092eeefdd805b06f2ad368bb9392edec20998993ebe2a929052c1ce03013e0dafd0f0e42f06f3bf9a8cf5787519d3860650f27a2b3393d34e1fe06e89b469ddfbc8a2cf0201160014583c0323603dd397ba5414255adc80b076cf232b00013d0dafd0f0e42f06f3bf9a8cf5787519d3860650f27a2b3393d34e1fe06e89b46980c8afa02501160014fdb3e6abf7f430fdabb53484ca2469103b2af1b500013effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80dafa80f4020116001408e75789f47d2a39622e5a940fa918260bf44c5400", 90 "07010001016d016b1f134a47da4f6df00822935e02a07514718ea99ce5ac4e07bd6c204e098eb525ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a858fa70200012200206205ec178dc1ac6ea05ea01bb0fcda6aa978173026fa75204a101bdad7bd6b4889010240d8d5bbf4969fba52df8fba06f75c5de0f51b2bd5f902bf234591f90e78bae20bfb5b7904cb83a1d6577c431f644d37722b432df9d64718b8300e3ab74a871a0046ae2068003e53d467b6d81beaf1e7bd9b60a5ffedc79b36ce14ecd1f30a2dcbcd0551200449030407a3a1fa0731f7f784a72c325b5ce4d534fc3cf8fb7140536ba928605152ad02014affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80f699b2a302012200209a0b4b27fde7d29d3b465d20eb2e19f4bda3a873d19d11f4cba53958bde92ed000013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80b3ffc40301160014ed7d3c466dbc6cc1f3a9af21267ac162f11b30a200", 91 } 92 wantMerkleRoot := "0f07b8a453771c2dc628f3895ebb33fea82a8de42e11aa588bec26419af22065" 93 94 var txs []*bc.Tx 95 for _, rawTx := range rawTxs { 96 tx := Tx{} 97 if err := tx.UnmarshalText([]byte(rawTx)); err != nil { 98 t.Fatal(err) 99 } 100 101 txs = append(txs, tx.Tx) 102 } 103 104 gotMerkleRoot, err := TxMerkleRoot(txs) 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 if wantMerkleRoot != gotMerkleRoot.String() { 110 t.Errorf("got merkle root:%s, want merkle root:%s", gotMerkleRoot.String(), wantMerkleRoot) 111 } 112 } 113 114 func TestDuplicateLeaves(t *testing.T) { 115 trueProg := []byte{byte(vm.OP_TRUE)} 116 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash) 117 txs := make([]*bc.Tx, 6) 118 for i := uint64(0); i < 6; i++ { 119 now := []byte(time.Now().String()) 120 txs[i] = NewTx(TxData{ 121 Version: 1, 122 Inputs: []*TxInput{NewIssuanceInput(now, i, trueProg, nil, nil)}, 123 Outputs: []*TxOutput{NewTxOutput(assetID, i, trueProg)}, 124 }).Tx 125 } 126 127 // first, get the root of an unbalanced tree 128 txns := []*bc.Tx{txs[5], txs[4], txs[3], txs[2], txs[1], txs[0]} 129 root1, err := TxMerkleRoot(txns) 130 if err != nil { 131 t.Fatalf("unexpected error %s", err) 132 } 133 134 // now, get the root of a balanced tree that repeats leaves 0 and 1 135 txns = []*bc.Tx{txs[5], txs[4], txs[3], txs[2], txs[1], txs[0], txs[1], txs[0]} 136 root2, err := TxMerkleRoot(txns) 137 if err != nil { 138 t.Fatalf("unexpected error %s", err) 139 } 140 141 if root1 == root2 { 142 t.Error("forged merkle tree by duplicating some leaves") 143 } 144 } 145 146 func TestAllDuplicateLeaves(t *testing.T) { 147 trueProg := []byte{byte(vm.OP_TRUE)} 148 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash) 149 now := []byte(time.Now().String()) 150 issuanceInp := NewIssuanceInput(now, 1, trueProg, nil, nil) 151 152 tx := NewTx(TxData{ 153 Version: 1, 154 Inputs: []*TxInput{issuanceInp}, 155 Outputs: []*TxOutput{NewTxOutput(assetID, 1, trueProg)}, 156 }).Tx 157 tx1, tx2, tx3, tx4, tx5, tx6 := tx, tx, tx, tx, tx, tx 158 159 // first, get the root of an unbalanced tree 160 txs := []*bc.Tx{tx6, tx5, tx4, tx3, tx2, tx1} 161 root1, err := TxMerkleRoot(txs) 162 if err != nil { 163 t.Fatalf("unexpected error %s", err) 164 } 165 166 // now, get the root of a balanced tree that repeats leaves 5 and 6 167 txs = []*bc.Tx{tx6, tx5, tx6, tx5, tx4, tx3, tx2, tx1} 168 root2, err := TxMerkleRoot(txs) 169 if err != nil { 170 t.Fatalf("unexpected error %s", err) 171 } 172 173 if root1 == root2 { 174 t.Error("forged merkle tree with all duplicate leaves") 175 } 176 } 177 178 func TestTxMerkleProof(t *testing.T) { 179 cases := []struct { 180 txCount int 181 relatedTxIndexes []int 182 expectHashLen int 183 expectFlags []uint8 184 }{ 185 { 186 txCount: 10, 187 relatedTxIndexes: []int{0, 3, 7, 8}, 188 expectHashLen: 9, 189 expectFlags: []uint8{1, 1, 1, 1, 2, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 2, 0}, 190 }, 191 { 192 txCount: 10, 193 relatedTxIndexes: []int{}, 194 expectHashLen: 1, 195 expectFlags: []uint8{0}, 196 }, 197 { 198 txCount: 1, 199 relatedTxIndexes: []int{0}, 200 expectHashLen: 1, 201 expectFlags: []uint8{2}, 202 }, 203 { 204 txCount: 19, 205 relatedTxIndexes: []int{1, 3, 5, 7, 11, 15}, 206 expectHashLen: 15, 207 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}, 208 }, 209 } 210 for _, c := range cases { 211 txs, bcTxs := mockTransactions(c.txCount) 212 213 var nodes []merkleNode 214 for _, tx := range txs { 215 nodes = append(nodes, tx.ID) 216 } 217 tree := buildMerkleTree(nodes) 218 root, err := TxMerkleRoot(bcTxs) 219 if err != nil { 220 t.Fatalf("unexpected error %s", err) 221 } 222 if tree.hash != root { 223 t.Error("build tree fail") 224 } 225 226 var relatedTx []*Tx 227 for _, index := range c.relatedTxIndexes { 228 relatedTx = append(relatedTx, txs[index]) 229 } 230 proofHashes, flags := GetTxMerkleTreeProof(txs, relatedTx) 231 if !testutil.DeepEqual(flags, c.expectFlags) { 232 t.Error("The flags is not equals expect flags", flags, c.expectFlags) 233 } 234 if len(proofHashes) != c.expectHashLen { 235 t.Error("The length proof hashes is not equals expect length") 236 } 237 var ids []*bc.Hash 238 for _, tx := range relatedTx { 239 ids = append(ids, &tx.ID) 240 } 241 if !ValidateTxMerkleTreeProof(proofHashes, flags, ids, root) { 242 t.Error("Merkle tree validate fail") 243 } 244 } 245 } 246 247 func TestStatusMerkleProof(t *testing.T) { 248 cases := []struct { 249 statusCount int 250 relatedIndexes []int 251 flags []uint8 252 expectHashLen int 253 }{ 254 { 255 statusCount: 10, 256 relatedIndexes: []int{0, 3, 7, 8}, 257 flags: []uint8{1, 1, 1, 1, 2, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 2, 0}, 258 expectHashLen: 9, 259 }, 260 { 261 statusCount: 10, 262 relatedIndexes: []int{}, 263 flags: []uint8{0}, 264 expectHashLen: 1, 265 }, 266 { 267 statusCount: 1, 268 relatedIndexes: []int{0}, 269 flags: []uint8{2}, 270 expectHashLen: 1, 271 }, 272 { 273 statusCount: 19, 274 relatedIndexes: []int{1, 3, 5, 7, 11, 15}, 275 flags: []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}, 276 expectHashLen: 15, 277 }, 278 } 279 for _, c := range cases { 280 statuses := mockStatuses(c.statusCount) 281 var relatedStatuses []*bc.TxVerifyResult 282 for _, index := range c.relatedIndexes { 283 relatedStatuses = append(relatedStatuses, statuses[index]) 284 } 285 hashes := GetStatusMerkleTreeProof(statuses, c.flags) 286 if len(hashes) != c.expectHashLen { 287 t.Error("The length proof hashes is not equals expect length") 288 } 289 root, _ := TxStatusMerkleRoot(statuses) 290 if !ValidateStatusMerkleTreeProof(hashes, c.flags, relatedStatuses, root) { 291 t.Error("Merkle tree validate fail") 292 } 293 } 294 } 295 296 func TestUglyValidateTxMerkleProof(t *testing.T) { 297 cases := []struct { 298 hashes []string 299 flags []uint8 300 relatedHashes []string 301 root string 302 expectResult bool 303 }{ 304 { 305 hashes: []string{}, 306 flags: []uint8{}, 307 relatedHashes: []string{}, 308 root: "", 309 expectResult: false, 310 }, 311 { 312 hashes: []string{}, 313 flags: []uint8{1, 1, 1, 1, 2, 0, 1, 0, 2, 1, 0, 1, 0, 2, 1, 2, 0}, 314 relatedHashes: []string{}, 315 root: "", 316 expectResult: false, 317 }, 318 { 319 hashes: []string{ 320 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 321 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 322 }, 323 flags: []uint8{}, 324 relatedHashes: []string{}, 325 root: "", 326 expectResult: false, 327 }, 328 { 329 hashes: []string{}, 330 flags: []uint8{}, 331 relatedHashes: []string{ 332 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 333 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 334 }, 335 root: "", 336 expectResult: false, 337 }, 338 { 339 hashes: []string{}, 340 flags: []uint8{1, 1, 0, 2, 1, 2, 1, 0, 1}, 341 relatedHashes: []string{ 342 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 343 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 344 }, 345 root: "281138e0a9ea19505844bd61a2f5843787035782c093da74d12b5fba73eeeb07", 346 }, 347 { 348 hashes: []string{ 349 "68f03ea2b02a21ad944d1a43ad6152a7fa6a7ed4101d59be62594dd30ef2a558", 350 }, 351 flags: []uint8{}, 352 relatedHashes: []string{ 353 "0093370a8e19f8f131fd7e75c576615950d5672ee5e18c63f105a95bcab4332c", 354 "c9b7779847fb7ab74cf4b1e7f4557133918faa2bc130042753417dfb62b12dfa", 355 }, 356 root: "281138e0a9ea19505844bd61a2f5843787035782c093da74d12b5fba73eeeb07", 357 expectResult: false, 358 }, 359 { 360 hashes: []string{ 361 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 362 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 363 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 364 }, 365 flags: []uint8{1, 1, 0, 2, 0}, 366 relatedHashes: []string{ 367 "504af455e328e7dd39bbc059529851946d54ee8b459b11b3aac4a0feeb474487", 368 }, 369 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 370 expectResult: true, 371 }, 372 // flags and hashes is correct, but relatedHashes has hash that does not exist 373 { 374 hashes: []string{ 375 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 376 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 377 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 378 }, 379 flags: []uint8{1, 1, 0, 2, 0}, 380 relatedHashes: []string{ 381 "504af455e328e7dd39bbc059529851946d54ee8b459b11b3aac4a0feeb474487", 382 "281138e0a9ea19505844bd61a2f5843787035782c093da74d12b5fba73eeeb07", 383 }, 384 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 385 expectResult: false, 386 }, 387 // flags and hashes is correct, but relatedHashes is not enough 388 { 389 hashes: []string{ 390 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 391 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 392 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 393 }, 394 flags: []uint8{1, 1, 0, 2, 0}, 395 relatedHashes: []string{}, 396 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 397 expectResult: false, 398 }, 399 // flags is correct, but hashes has additional hash at the end 400 { 401 hashes: []string{ 402 "8ec3ee7589f95eee9b534f71fcd37142bcc839a0dbfe78124df9663827b90c35", 403 "011bd3380852b2946df507e0c6234222c559eec8f545e4bc58a89e960892259b", 404 "c205988d9c864083421f1bdb95e6cf8b52070facfcc87e46a6e8197f5389fca2", 405 "5a06c90136e81c0f9cad29725e69edc6d21bd6fb0641265f9c4b6bb6840b37dd", 406 }, 407 flags: []uint8{1, 1, 0, 2, 0}, 408 relatedHashes: []string{ 409 "504af455e328e7dd39bbc059529851946d54ee8b459b11b3aac4a0feeb474487", 410 }, 411 root: "aff81a46fe79204ef9007243f374d54104a59762b9f74d80d56b5291753db6fb", 412 expectResult: true, 413 }, 414 } 415 416 for _, c := range cases { 417 var hashes, relatedHashes []*bc.Hash 418 var hashBytes, rootBytes [32]byte 419 var err error 420 for _, hashStr := range c.hashes { 421 if hashBytes, err = convertHashStr2Bytes(hashStr); err != nil { 422 t.Fatal(err) 423 } 424 425 hash := bc.NewHash(hashBytes) 426 hashes = append(hashes, &hash) 427 } 428 for _, hashStr := range c.relatedHashes { 429 if hashBytes, err = convertHashStr2Bytes(hashStr); err != nil { 430 t.Fatal(err) 431 } 432 433 hash := bc.NewHash(hashBytes) 434 relatedHashes = append(relatedHashes, &hash) 435 } 436 if rootBytes, err = convertHashStr2Bytes(c.root); err != nil { 437 t.Fatal(err) 438 } 439 440 root := bc.NewHash(rootBytes) 441 if ValidateTxMerkleTreeProof(hashes, c.flags, relatedHashes, root) != c.expectResult { 442 t.Error("Validate merkle tree proof fail") 443 } 444 } 445 } 446 447 func convertHashStr2Bytes(hashStr string) ([32]byte, error) { 448 var result [32]byte 449 hashBytes, err := hex.DecodeString(hashStr) 450 if err != nil { 451 return result, err 452 } 453 copy(result[:], hashBytes) 454 return result, nil 455 } 456 457 func mockTransactions(txCount int) ([]*Tx, []*bc.Tx) { 458 var txs []*Tx 459 var bcTxs []*bc.Tx 460 trueProg := []byte{byte(vm.OP_TRUE)} 461 assetID := bc.ComputeAssetID(trueProg, 1, &bc.EmptyStringHash) 462 for i := 0; i < txCount; i++ { 463 now := []byte(time.Now().String()) 464 issuanceInp := NewIssuanceInput(now, 1, trueProg, nil, nil) 465 tx := NewTx(TxData{ 466 Version: 1, 467 Inputs: []*TxInput{issuanceInp}, 468 Outputs: []*TxOutput{NewTxOutput(assetID, 1, trueProg)}, 469 }) 470 txs = append(txs, tx) 471 bcTxs = append(bcTxs, tx.Tx) 472 } 473 return txs, bcTxs 474 } 475 476 func mockStatuses(statusCount int) []*bc.TxVerifyResult { 477 var statuses []*bc.TxVerifyResult 478 for i := 0; i < statusCount; i++ { 479 status := &bc.TxVerifyResult{} 480 fail := rand.Intn(2) 481 if fail == 0 { 482 status.StatusFail = true 483 } else { 484 status.StatusFail = false 485 } 486 statuses = append(statuses, status) 487 } 488 return statuses 489 }