+
+ if wants[0].ID != tx.ID {
+ t.Fatal("account txID mismatch")
+ }
+
+ for position, tx := range block.Transactions {
+ get := w.DB.Get(calcGlobalTxIndexKey(tx.ID.String()))
+ bh := block.BlockHeader.Hash()
+ expect := calcGlobalTxIndex(&bh, uint64(position))
+ if !reflect.DeepEqual(get, expect) {
+ t.Fatalf("position#%d: compare retrieved globalTxIdx err", position)
+ }
+ }
+}
+
+func TestRescanWallet(t *testing.T) {
+ // prepare wallet & db
+ dirPath, err := ioutil.TempDir(".", "")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(dirPath)
+
+ testDB := dbm.NewDB("testdb", "leveldb", "temp")
+ defer os.RemoveAll("temp")
+
+ store := database.NewStore(testDB)
+ dispatcher := event.NewDispatcher()
+ txPool := protocol.NewTxPool(store, dispatcher)
+ chain, err := protocol.NewChain(store, txPool)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ statusInfo := StatusInfo{
+ Version: currentVersion,
+ WorkHash: bc.Hash{V0: 0xff},
+ }
+ rawWallet, err := json.Marshal(statusInfo)
+ if err != nil {
+ t.Fatal("save wallet info")
+ }
+
+ w := mockWallet(testDB, nil, nil, chain, dispatcher, false)
+ w.DB.Set(walletKey, rawWallet)
+ rawWallet = w.DB.Get(walletKey)
+ if rawWallet == nil {
+ t.Fatal("fail to load wallet StatusInfo")
+ }
+
+ if err := json.Unmarshal(rawWallet, &w.status); err != nil {
+ t.Fatal(err)
+ }
+
+ // rescan wallet
+ if err := w.loadWalletInfo(); err != nil {
+ t.Fatal(err)
+ }
+
+ block := config.GenesisBlock()
+ if w.status.WorkHash != block.Hash() {
+ t.Fatal("reattach from genesis block")
+ }
+}
+
+func TestMemPoolTxQueryLoop(t *testing.T) {
+ dirPath, err := ioutil.TempDir(".", "")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(dirPath)
+
+ testDB := dbm.NewDB("testdb", "leveldb", dirPath)
+
+ store := database.NewStore(testDB)
+ dispatcher := event.NewDispatcher()
+ txPool := protocol.NewTxPool(store, dispatcher)
+
+ chain, err := protocol.NewChain(store, txPool)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ accountManager := account.NewManager(testDB, chain)
+ hsm, err := pseudohsm.New(dirPath)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ controlProg.KeyIndex = 1
+
+ reg := asset.NewRegistry(testDB, chain)
+ asset := bc.AssetID{V0: 5}
+
+ utxos := []*account.UTXO{}
+ btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
+ utxos = append(utxos, btmUtxo)
+ OtherUtxo := mockUTXO(controlProg, &asset)
+ utxos = append(utxos, OtherUtxo)
+
+ _, txData, err := mockTxData(utxos, testAccount)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ tx := types.NewTx(*txData)
+ //block := mockSingleBlock(tx)
+ txStatus := bc.NewTransactionStatus()
+ txStatus.SetStatus(0, false)
+ w, err := NewWallet(testDB, accountManager, reg, hsm, chain, dispatcher, false)
+ go w.memPoolTxQueryLoop()
+ w.eventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgNewTx}})
+ time.Sleep(time.Millisecond * 10)
+ if _, err = w.GetUnconfirmedTxByTxID(tx.ID.String()); err != nil {
+ t.Fatal("disaptch new tx msg error:", err)
+ }
+ w.eventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgRemoveTx}})
+ time.Sleep(time.Millisecond * 10)
+ txs, err := w.GetUnconfirmedTxs(testAccount.ID)
+ if err != nil {
+ t.Fatal("get unconfirmed tx error:", err)
+ }
+
+ if len(txs) != 0 {
+ t.Fatal("disaptch remove tx msg error")
+ }
+
+ w.eventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: 2}})