github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/wallet/utxo_test.go (about) 1 package wallet 2 3 import ( 4 "encoding/hex" 5 "encoding/json" 6 "fmt" 7 "os" 8 "sort" 9 "testing" 10 11 "github.com/bytom/bytom/account" 12 "github.com/bytom/bytom/consensus" 13 dbm "github.com/bytom/bytom/database/leveldb" 14 "github.com/bytom/bytom/protocol/bc" 15 "github.com/bytom/bytom/protocol/bc/types" 16 "github.com/bytom/bytom/testutil" 17 ) 18 19 func TestGetAccountUtxos(t *testing.T) { 20 testDB := dbm.NewDB("testdb", "leveldb", "temp") 21 defer os.RemoveAll("temp") 22 23 cases := []struct { 24 dbUtxos map[string]*account.UTXO 25 unconfirmedUtxos []*account.UTXO 26 id string 27 unconfirmed bool 28 isSmartContract bool 29 wantUtxos []*account.UTXO 30 }{ 31 { 32 dbUtxos: map[string]*account.UTXO{}, 33 id: "", 34 unconfirmed: false, 35 isSmartContract: false, 36 wantUtxos: []*account.UTXO{}, 37 }, 38 { 39 dbUtxos: map[string]*account.UTXO{ 40 string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ 41 OutputID: bc.Hash{V0: 1}, 42 }, 43 string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ 44 OutputID: bc.Hash{V0: 2}, 45 }, 46 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ 47 OutputID: bc.Hash{V0: 3}, 48 }, 49 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ 50 OutputID: bc.Hash{V0: 4}, 51 }, 52 }, 53 unconfirmedUtxos: []*account.UTXO{}, 54 id: "", 55 isSmartContract: false, 56 wantUtxos: []*account.UTXO{ 57 &account.UTXO{OutputID: bc.Hash{V0: 1}}, 58 &account.UTXO{OutputID: bc.Hash{V0: 2}}, 59 &account.UTXO{OutputID: bc.Hash{V0: 3}}, 60 }, 61 }, 62 { 63 dbUtxos: map[string]*account.UTXO{ 64 string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ 65 OutputID: bc.Hash{V0: 1}, 66 }, 67 string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ 68 OutputID: bc.Hash{V0: 2}, 69 }, 70 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ 71 OutputID: bc.Hash{V0: 3}, 72 }, 73 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ 74 OutputID: bc.Hash{V0: 4}, 75 }, 76 }, 77 unconfirmedUtxos: []*account.UTXO{ 78 &account.UTXO{ 79 OutputID: bc.Hash{V0: 5}, 80 ControlProgram: []byte("smart contract"), 81 }, 82 }, 83 id: "", 84 unconfirmed: false, 85 isSmartContract: true, 86 wantUtxos: []*account.UTXO{ 87 &account.UTXO{OutputID: bc.Hash{V0: 4}}, 88 }, 89 }, 90 { 91 dbUtxos: map[string]*account.UTXO{ 92 string(account.StandardUTXOKey(bc.Hash{V0: 1})): &account.UTXO{ 93 OutputID: bc.Hash{V0: 1}, 94 }, 95 string(account.StandardUTXOKey(bc.Hash{V0: 1, V1: 2})): &account.UTXO{ 96 OutputID: bc.Hash{V0: 1, V1: 2}, 97 }, 98 string(account.StandardUTXOKey(bc.Hash{V0: 2})): &account.UTXO{ 99 OutputID: bc.Hash{V0: 2}, 100 }, 101 string(account.StandardUTXOKey(bc.Hash{V0: 2, V1: 2})): &account.UTXO{ 102 OutputID: bc.Hash{V0: 2, V1: 2}, 103 }, 104 }, 105 unconfirmedUtxos: []*account.UTXO{ 106 &account.UTXO{ 107 OutputID: bc.Hash{V0: 6}, 108 ControlProgram: []byte{0x51}, 109 }, 110 }, 111 id: "0000000000000002", 112 unconfirmed: false, 113 isSmartContract: false, 114 wantUtxos: []*account.UTXO{ 115 &account.UTXO{OutputID: bc.Hash{V0: 2}}, 116 &account.UTXO{OutputID: bc.Hash{V0: 2, V1: 2}}, 117 }, 118 }, 119 { 120 dbUtxos: map[string]*account.UTXO{ 121 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ 122 OutputID: bc.Hash{V0: 3}, 123 }, 124 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ 125 OutputID: bc.Hash{V0: 4}, 126 }, 127 }, 128 unconfirmedUtxos: []*account.UTXO{ 129 &account.UTXO{ 130 OutputID: bc.Hash{V0: 5}, 131 ControlProgram: []byte("smart contract"), 132 }, 133 &account.UTXO{ 134 OutputID: bc.Hash{V0: 6}, 135 ControlProgram: []byte{0x51}, 136 }, 137 }, 138 id: "", 139 unconfirmed: true, 140 isSmartContract: true, 141 wantUtxos: []*account.UTXO{ 142 &account.UTXO{ 143 OutputID: bc.Hash{V0: 5}, 144 ControlProgram: []byte("smart contract"), 145 }, 146 &account.UTXO{ 147 OutputID: bc.Hash{V0: 4}, 148 }, 149 }, 150 }, 151 { 152 dbUtxos: map[string]*account.UTXO{ 153 string(account.StandardUTXOKey(bc.Hash{V0: 3})): &account.UTXO{ 154 OutputID: bc.Hash{V0: 3}, 155 }, 156 string(account.ContractUTXOKey(bc.Hash{V0: 4})): &account.UTXO{ 157 OutputID: bc.Hash{V0: 4}, 158 }, 159 }, 160 unconfirmedUtxos: []*account.UTXO{ 161 &account.UTXO{ 162 OutputID: bc.Hash{V0: 5}, 163 ControlProgram: []byte("smart contract"), 164 }, 165 &account.UTXO{ 166 OutputID: bc.Hash{V0: 6}, 167 ControlProgram: []byte{0x51}, 168 }, 169 }, 170 id: "", 171 unconfirmed: true, 172 isSmartContract: false, 173 wantUtxos: []*account.UTXO{ 174 &account.UTXO{ 175 OutputID: bc.Hash{V0: 6}, 176 ControlProgram: []byte{0x51}, 177 }, 178 &account.UTXO{ 179 OutputID: bc.Hash{V0: 3}, 180 }, 181 }, 182 }, 183 } 184 185 w := &Wallet{DB: testDB} 186 for i, c := range cases { 187 for k, u := range c.dbUtxos { 188 data, err := json.Marshal(u) 189 if err != nil { 190 t.Error(err) 191 } 192 testDB.Set([]byte(k), data) 193 } 194 195 w.AccountMgr = account.NewManager(testDB, nil) 196 w.AccountMgr.AddUnconfirmedUtxo(c.unconfirmedUtxos) 197 gotUtxos := w.GetAccountUtxos("", c.id, c.unconfirmed, c.isSmartContract, false) 198 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) { 199 t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos) 200 } 201 202 for k := range c.dbUtxos { 203 testDB.Delete([]byte(k)) 204 } 205 } 206 } 207 208 //because can not pass by btm2.0 branch 209 func TestFilterAccountUtxo(t *testing.T) { 210 testDB := dbm.NewDB("testdb", "leveldb", "temp") 211 defer os.RemoveAll("temp") 212 213 cases := []struct { 214 dbPrograms map[string]*account.CtrlProgram 215 input []*account.UTXO 216 wantUtxos []*account.UTXO 217 }{ 218 { 219 dbPrograms: map[string]*account.CtrlProgram{}, 220 input: []*account.UTXO{}, 221 wantUtxos: []*account.UTXO{}, 222 }, 223 { 224 dbPrograms: map[string]*account.CtrlProgram{ 225 "436f6e74726163743a2a37a64a4e15a772ab43bf3f5956d0d1f353946496788e7f40d0ff1796286a6f": &account.CtrlProgram{ 226 AccountID: "testAccount", 227 Address: "testAddress", 228 KeyIndex: 53, 229 Change: true, 230 }, 231 }, 232 input: []*account.UTXO{ 233 &account.UTXO{ 234 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 235 AssetID: bc.AssetID{V0: 1}, 236 Amount: 3, 237 }, 238 &account.UTXO{ 239 ControlProgram: []byte{0x91}, 240 AssetID: bc.AssetID{V0: 1}, 241 Amount: 4, 242 }, 243 }, 244 wantUtxos: []*account.UTXO{ 245 &account.UTXO{ 246 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 247 AssetID: bc.AssetID{V0: 1}, 248 Amount: 3, 249 AccountID: "testAccount", 250 Address: "testAddress", 251 ControlProgramIndex: 53, 252 Change: true, 253 }, 254 }, 255 }, 256 { 257 dbPrograms: map[string]*account.CtrlProgram{}, 258 input: []*account.UTXO{ 259 &account.UTXO{ 260 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 261 AssetID: bc.AssetID{V0: 1}, 262 Amount: 3, 263 }, 264 &account.UTXO{ 265 ControlProgram: []byte{0x91}, 266 AssetID: bc.AssetID{V0: 1}, 267 Amount: 3, 268 }, 269 }, 270 wantUtxos: []*account.UTXO{}, 271 }, 272 { 273 dbPrograms: map[string]*account.CtrlProgram{ 274 "436f6e74726163743a2a37a64a4e15a772ab43bf3f5956d0d1f353946496788e7f40d0ff1796286a6f": &account.CtrlProgram{ 275 AccountID: "testAccount", 276 Address: "testAddress", 277 KeyIndex: 53, 278 Change: true, 279 }, 280 "436f6e74726163743adb4d86262c12ba70d50b3ca3ae102d5682436243bd1e8c79569603f75675036a": &account.CtrlProgram{ 281 AccountID: "testAccount2", 282 Address: "testAddress2", 283 KeyIndex: 72, 284 Change: false, 285 }, 286 }, 287 input: []*account.UTXO{ 288 &account.UTXO{ 289 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 290 AssetID: bc.AssetID{V0: 1}, 291 Amount: 3, 292 }, 293 &account.UTXO{ 294 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 295 AssetID: bc.AssetID{V0: 1}, 296 Amount: 5, 297 }, 298 &account.UTXO{ 299 ControlProgram: []byte{0x00, 0x14, 0xc6, 0xbf, 0x22, 0x19, 0x64, 0x2a, 0xc5, 0x9e, 0x5b, 0xe4, 0xeb, 0xdf, 0x5b, 0x22, 0x49, 0x56, 0xa7, 0x98, 0xa4, 0xdf}, 300 AssetID: bc.AssetID{V0: 1}, 301 Amount: 7, 302 }, 303 }, 304 wantUtxos: []*account.UTXO{ 305 &account.UTXO{ 306 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 307 AssetID: bc.AssetID{V0: 1}, 308 Amount: 3, 309 AccountID: "testAccount", 310 Address: "testAddress", 311 ControlProgramIndex: 53, 312 Change: true, 313 }, 314 &account.UTXO{ 315 ControlProgram: []byte{0x00, 0x14, 0x62, 0x50, 0x18, 0xb6, 0x85, 0x77, 0xba, 0x9b, 0x26, 0x19, 0xc8, 0x1d, 0x2e, 0x96, 0xba, 0x22, 0xbe, 0x77, 0x77, 0xd7}, 316 AssetID: bc.AssetID{V0: 1}, 317 Amount: 5, 318 AccountID: "testAccount", 319 Address: "testAddress", 320 ControlProgramIndex: 53, 321 Change: true, 322 }, 323 &account.UTXO{ 324 ControlProgram: []byte{0x00, 0x14, 0xc6, 0xbf, 0x22, 0x19, 0x64, 0x2a, 0xc5, 0x9e, 0x5b, 0xe4, 0xeb, 0xdf, 0x5b, 0x22, 0x49, 0x56, 0xa7, 0x98, 0xa4, 0xdf}, 325 AssetID: bc.AssetID{V0: 1}, 326 Amount: 7, 327 AccountID: "testAccount2", 328 Address: "testAddress2", 329 ControlProgramIndex: 72, 330 Change: false, 331 }, 332 }, 333 }, 334 } 335 336 w := &Wallet{DB: testDB} 337 for i, c := range cases { 338 for s, p := range c.dbPrograms { 339 data, err := json.Marshal(p) 340 if err != nil { 341 t.Error(err) 342 } 343 key, err := hex.DecodeString(s) 344 if err != nil { 345 t.Error(err) 346 } 347 testDB.Set(key, data) 348 } 349 gotUtxos := w.filterAccountUtxo(c.input) 350 sort.Slice(gotUtxos[:], func(i, j int) bool { 351 return gotUtxos[i].Amount < gotUtxos[j].Amount 352 }) 353 354 if !testutil.DeepEqual(gotUtxos, c.wantUtxos) { 355 t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos) 356 } 357 for s := range c.dbPrograms { 358 key, err := hex.DecodeString(s) 359 if err != nil { 360 t.Error(err) 361 } 362 testDB.Delete(key) 363 } 364 } 365 } 366 367 func TestTxInToUtxos(t *testing.T) { 368 cases := []struct { 369 tx *types.Tx 370 statusFail bool 371 wantUtxos []*account.UTXO 372 }{ 373 { 374 tx: types.NewTx(types.TxData{ 375 Inputs: []*types.TxInput{ 376 types.NewCoinbaseInput([]byte{0x51}), 377 }, 378 Outputs: []*types.TxOutput{ 379 types.NewOriginalTxOutput(*consensus.BTMAssetID, 41250000000, []byte{0x51}, nil), 380 }, 381 }), 382 statusFail: false, 383 wantUtxos: []*account.UTXO{}, 384 }, 385 { 386 tx: types.NewTx(types.TxData{ 387 Inputs: []*types.TxInput{ 388 types.NewIssuanceInput([]byte{}, 4125, []byte{0x51}, [][]byte{}, []byte{}), 389 }, 390 Outputs: []*types.TxOutput{ 391 types.NewOriginalTxOutput(*consensus.BTMAssetID, 4125, []byte{0x51}, nil), 392 }, 393 }), 394 statusFail: false, 395 wantUtxos: []*account.UTXO{}, 396 }, 397 { 398 tx: types.NewTx(types.TxData{ 399 Inputs: []*types.TxInput{ 400 types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 1, 1, []byte{0x51}, nil), 401 types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, bc.AssetID{V0: 1}, 3, 2, []byte{0x52}, nil), 402 types.NewSpendInput([][]byte{}, bc.Hash{V0: 3}, *consensus.BTMAssetID, 5, 3, []byte{0x53}, nil), 403 types.NewSpendInput([][]byte{}, bc.Hash{V0: 4}, *consensus.BTMAssetID, 7, 4, []byte{0x54}, nil), 404 }, 405 Outputs: []*types.TxOutput{ 406 types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 4, []byte{0x51}, nil), 407 types.NewOriginalTxOutput(*consensus.BTMAssetID, 12, []byte{0x53}, nil), 408 }, 409 }), 410 statusFail: false, 411 wantUtxos: []*account.UTXO{ 412 &account.UTXO{ 413 OutputID: testutil.MustDecodeHash("d7317174b78e6efdd060f19031b9b4d8dfdc8218b8fe7d86324f8c35b9cc572c"), 414 AssetID: bc.AssetID{V0: 1}, 415 Amount: 1, 416 ControlProgram: []byte{0x51}, 417 SourceID: bc.Hash{V0: 1}, 418 SourcePos: 1, 419 }, 420 &account.UTXO{ 421 OutputID: testutil.MustDecodeHash("2170b5a9ed124f4c2f691292dc44cc9a5b834c286a39738aa159c646cce14d95"), 422 AssetID: bc.AssetID{V0: 1}, 423 Amount: 3, 424 ControlProgram: []byte{0x52}, 425 SourceID: bc.Hash{V0: 2}, 426 SourcePos: 2, 427 }, 428 &account.UTXO{ 429 OutputID: testutil.MustDecodeHash("e07a0c076fcee0faccf6fc329875c3273120faaee87d273ff1cea5c64b2fb1e3"), 430 AssetID: *consensus.BTMAssetID, 431 Amount: 5, 432 ControlProgram: []byte{0x53}, 433 SourceID: bc.Hash{V0: 3}, 434 SourcePos: 3, 435 }, 436 &account.UTXO{ 437 OutputID: testutil.MustDecodeHash("30fe2e3180356a847f152ce2dabab99ebe8df97ebbf100881d9591527f9fd738"), 438 AssetID: *consensus.BTMAssetID, 439 Amount: 7, 440 ControlProgram: []byte{0x54}, 441 SourceID: bc.Hash{V0: 4}, 442 SourcePos: 4, 443 }, 444 }, 445 }, 446 { 447 tx: types.NewTx(types.TxData{ 448 Inputs: []*types.TxInput{ 449 types.NewSpendInput([][]byte{}, bc.Hash{V0: 3}, *consensus.BTMAssetID, 5, 3, []byte{0x53}, nil), 450 types.NewSpendInput([][]byte{}, bc.Hash{V0: 4}, *consensus.BTMAssetID, 7, 4, []byte{0x54}, nil), 451 }, 452 Outputs: []*types.TxOutput{ 453 types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 4, []byte{0x51}, nil), 454 types.NewOriginalTxOutput(*consensus.BTMAssetID, 12, []byte{0x53}, nil), 455 }, 456 }), 457 statusFail: true, 458 wantUtxos: []*account.UTXO{ 459 &account.UTXO{ 460 OutputID: testutil.MustDecodeHash("e07a0c076fcee0faccf6fc329875c3273120faaee87d273ff1cea5c64b2fb1e3"), 461 AssetID: *consensus.BTMAssetID, 462 Amount: 5, 463 ControlProgram: []byte{0x53}, 464 SourceID: bc.Hash{V0: 3}, 465 SourcePos: 3, 466 }, 467 &account.UTXO{ 468 OutputID: testutil.MustDecodeHash("30fe2e3180356a847f152ce2dabab99ebe8df97ebbf100881d9591527f9fd738"), 469 AssetID: *consensus.BTMAssetID, 470 Amount: 7, 471 ControlProgram: []byte{0x54}, 472 SourceID: bc.Hash{V0: 4}, 473 SourcePos: 4, 474 }, 475 }, 476 }, 477 } 478 479 for i, c := range cases { 480 if gotUtxos := txInToUtxos(c.tx); !testutil.DeepEqual(gotUtxos, c.wantUtxos) { 481 for k, v := range gotUtxos { 482 data, _ := json.Marshal(v) 483 fmt.Println(k, string(data)) 484 } 485 for k, v := range c.wantUtxos { 486 data, _ := json.Marshal(v) 487 fmt.Println(k, string(data)) 488 } 489 490 t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos) 491 } 492 } 493 } 494 495 func TestTxOutToUtxos(t *testing.T) { 496 cases := []struct { 497 tx *types.Tx 498 statusFail bool 499 blockHeight uint64 500 wantUtxos []*account.UTXO 501 }{ 502 { 503 tx: types.NewTx(types.TxData{ 504 Inputs: []*types.TxInput{ 505 types.NewCoinbaseInput([]byte{0x51}), 506 }, 507 Outputs: []*types.TxOutput{ 508 types.NewOriginalTxOutput(*consensus.BTMAssetID, 41250000000, []byte{0x51}, nil), 509 }, 510 }), 511 statusFail: false, 512 blockHeight: 0, 513 wantUtxos: []*account.UTXO{ 514 &account.UTXO{ 515 OutputID: testutil.MustDecodeHash("5ad31f023737c301190026c6e97da10715d5455d9bb32ace3104454faefd2bb6"), 516 AssetID: *consensus.BTMAssetID, 517 Amount: 41250000000, 518 ControlProgram: []byte{0x51}, 519 SourceID: bc.NewHash([32]byte{0xb4, 0x7e, 0x94, 0x31, 0x88, 0xfe, 0xd3, 0xe9, 0xac, 0x99, 0x7c, 0xfc, 0x99, 0x6d, 0xd7, 0x4d, 0x04, 0x10, 0x77, 0xcb, 0x1c, 0xf8, 0x95, 0x14, 0x00, 0xe3, 0x42, 0x00, 0x8d, 0x05, 0xec, 0xdc}), 520 SourcePos: 0, 521 ValidHeight: 10, 522 }, 523 }, 524 }, 525 { 526 tx: types.NewTx(types.TxData{ 527 Inputs: []*types.TxInput{ 528 types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}, nil), 529 types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}, nil), 530 }, 531 Outputs: []*types.TxOutput{ 532 types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}, nil), 533 types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}, nil), 534 types.NewOriginalTxOutput(*consensus.BTMAssetID, 2, []byte{0x53}, nil), 535 types.NewOriginalTxOutput(*consensus.BTMAssetID, 5, []byte{0x54}, nil), 536 }, 537 }), 538 statusFail: false, 539 blockHeight: 0, 540 wantUtxos: []*account.UTXO{ 541 &account.UTXO{ 542 OutputID: testutil.MustDecodeHash("55de32fa7e96499be625063bc4c7f66bbe5d7b60f233d3a3d7265a9501c77e96"), 543 AssetID: bc.AssetID{V0: 1}, 544 Amount: 2, 545 ControlProgram: []byte{0x51}, 546 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 547 SourcePos: 0, 548 }, 549 &account.UTXO{ 550 OutputID: testutil.MustDecodeHash("f256f40aa36df9cf954fdf82d5835815adfd21579289063525c64cff59bc6d96"), 551 AssetID: bc.AssetID{V0: 1}, 552 Amount: 3, 553 ControlProgram: []byte{0x52}, 554 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 555 SourcePos: 1, 556 }, 557 &account.UTXO{ 558 OutputID: testutil.MustDecodeHash("60da633ce48a8bf995a23c040c1b52d543e5818abd7fc0b0faa355cf54acbcca"), 559 AssetID: *consensus.BTMAssetID, 560 Amount: 2, 561 ControlProgram: []byte{0x53}, 562 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 563 SourcePos: 2, 564 }, 565 &account.UTXO{ 566 OutputID: testutil.MustDecodeHash("550c883fd09fdccd4a5671c698d0874de9d713fa0b194f0ddffeae8ae79b57fc"), 567 AssetID: *consensus.BTMAssetID, 568 Amount: 5, 569 ControlProgram: []byte{0x54}, 570 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 571 SourcePos: 3, 572 }, 573 }, 574 }, 575 { 576 tx: types.NewTx(types.TxData{ 577 Inputs: []*types.TxInput{ 578 types.NewSpendInput([][]byte{}, bc.Hash{V0: 1}, bc.AssetID{V0: 1}, 5, 1, []byte{0x51}, nil), 579 types.NewSpendInput([][]byte{}, bc.Hash{V0: 2}, *consensus.BTMAssetID, 7, 1, []byte{0x51}, nil), 580 }, 581 Outputs: []*types.TxOutput{ 582 types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 2, []byte{0x51}, nil), 583 types.NewOriginalTxOutput(bc.AssetID{V0: 1}, 3, []byte{0x52}, nil), 584 types.NewOriginalTxOutput(*consensus.BTMAssetID, 2, []byte{0x53}, nil), 585 types.NewOriginalTxOutput(*consensus.BTMAssetID, 5, []byte{0x54}, nil), 586 }, 587 }), 588 statusFail: true, 589 blockHeight: 0, 590 wantUtxos: []*account.UTXO{ 591 &account.UTXO{ 592 OutputID: testutil.MustDecodeHash("55de32fa7e96499be625063bc4c7f66bbe5d7b60f233d3a3d7265a9501c77e96"), 593 AssetID: bc.AssetID{V0: 1}, 594 Amount: 2, 595 ControlProgram: []byte{0x51}, 596 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 597 SourcePos: 0, 598 }, 599 &account.UTXO{ 600 OutputID: testutil.MustDecodeHash("f256f40aa36df9cf954fdf82d5835815adfd21579289063525c64cff59bc6d96"), 601 AssetID: bc.AssetID{V0: 1}, 602 Amount: 3, 603 ControlProgram: []byte{0x52}, 604 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 605 SourcePos: 1, 606 }, 607 &account.UTXO{ 608 OutputID: testutil.MustDecodeHash("60da633ce48a8bf995a23c040c1b52d543e5818abd7fc0b0faa355cf54acbcca"), 609 AssetID: *consensus.BTMAssetID, 610 Amount: 2, 611 ControlProgram: []byte{0x53}, 612 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 613 SourcePos: 2, 614 }, 615 &account.UTXO{ 616 OutputID: testutil.MustDecodeHash("550c883fd09fdccd4a5671c698d0874de9d713fa0b194f0ddffeae8ae79b57fc"), 617 AssetID: *consensus.BTMAssetID, 618 Amount: 5, 619 ControlProgram: []byte{0x54}, 620 SourceID: testutil.MustDecodeHash("c0e16f80a168dad26194f9ba5a4244d9d52e08e4636aa50aa58a5b8d65e969d4"), 621 SourcePos: 3, 622 }, 623 }, 624 }, 625 } 626 627 for i, c := range cases { 628 if gotUtxos := txOutToUtxos(c.tx, c.blockHeight); !testutil.DeepEqual(gotUtxos, c.wantUtxos) { 629 for k, v := range gotUtxos { 630 data, _ := json.Marshal(v) 631 fmt.Println("got:", k, string(data)) 632 } 633 for k, v := range c.wantUtxos { 634 data, _ := json.Marshal(v) 635 fmt.Println("want:", k, string(data)) 636 } 637 638 t.Errorf("case %d: got %v want %v", i, gotUtxos, c.wantUtxos) 639 } 640 } 641 }