OSDN Git Service

Wallet store test (#312)
authorChengcheng Zhang <943420582@qq.com>
Thu, 18 Jul 2019 16:31:08 +0000 (00:31 +0800)
committerPaladz <yzhu101@uottawa.ca>
Thu, 18 Jul 2019 16:31:08 +0000 (00:31 +0800)
* add TestDeleteContractUTXO

* update

* add TestDeleteRecoveryStatus

* update TestDeleteRecoveryStatus

* add TestGetWalletInfo

* add TestDeleteUnconfirmedTransaction

* update TestDeleteUnconfirmedTransaction

* add TestListUnconfirmedTransactions

* update

* add TestGetGlobalTransactionIndex

* update ListTransactions

* add TestGetAsset

* add TestDeleteTransactions

* update TestDeleteTransactions

* add TestDeleteWalletTransactions

database/account_store.go
database/account_store_test.go
database/wallet_store.go
database/wallet_store_test.go

index 619dd8d..d050f49 100644 (file)
@@ -314,7 +314,7 @@ func (store *AccountStore) ListControlPrograms() ([]*acc.CtrlProgram, error) {
        return cps, nil
 }
 
        return cps, nil
 }
 
-// ListUTXOs get utxos by accountID
+// ListUTXOs list all utxos
 func (store *AccountStore) ListUTXOs() ([]*acc.UTXO, error) {
        utxoIter := store.db.IteratorPrefix(UTXOPrefix)
        defer utxoIter.Release()
 func (store *AccountStore) ListUTXOs() ([]*acc.UTXO, error) {
        utxoIter := store.db.IteratorPrefix(UTXOPrefix)
        defer utxoIter.Release()
index 4fdb717..680554c 100644 (file)
@@ -253,7 +253,7 @@ func TestDeleteStandardUTXO(t *testing.T) {
                },
        }
 
                },
        }
 
-       for _, c := range cases {
+       for i, c := range cases {
                testDB := dbm.NewDB("testdb", "leveldb", "temp")
                accountStore := NewAccountStore(testDB)
                as := accountStore.InitBatch()
                testDB := dbm.NewDB("testdb", "leveldb", "temp")
                accountStore := NewAccountStore(testDB)
                as := accountStore.InitBatch()
@@ -270,11 +270,16 @@ func TestDeleteStandardUTXO(t *testing.T) {
                        t.Fatal(err)
                }
 
                        t.Fatal(err)
                }
 
-               // get utxo by outputID
-               for _, utxo := range c.want {
-                       if _, err := as.GetUTXO(utxo.OutputID); err != nil {
-                               t.Fatal(err)
-                       }
+               gotUTXOs, err := as.ListUTXOs()
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               sort.Sort(SortUTXOs(gotUTXOs))
+               sort.Sort(SortUTXOs(c.want))
+
+               if !testutil.DeepEqual(gotUTXOs, c.want) {
+                       t.Errorf("case %v: got Delete Standard UTXOs, got: %v, want: %v.", i, gotUTXOs, c.want)
                }
 
                testDB.Close()
                }
 
                testDB.Close()
index a0c2a36..c0bf9f9 100644 (file)
@@ -190,7 +190,7 @@ func (store *WalletStore) DeleteWalletTransactions() {
        }
 }
 
        }
 }
 
-// DeleteWalletUTXOs delete all txs in wallet
+// DeleteWalletUTXOs delete all utxos in wallet
 func (store *WalletStore) DeleteWalletUTXOs() {
        batch := store.db.NewBatch()
        if store.batch != nil {
 func (store *WalletStore) DeleteWalletUTXOs() {
        batch := store.db.NewBatch()
        if store.batch != nil {
@@ -381,7 +381,6 @@ func (store *WalletStore) ListTransactions(accountID string, StartTxID string, c
                        annotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, annotatedTxs...)
                        txNum--
                }
                        annotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, annotatedTxs...)
                        txNum--
                }
-
        }
 
        return annotatedTxs, nil
        }
 
        return annotatedTxs, nil
index f2aa943..3c0f91e 100644 (file)
@@ -1,13 +1,23 @@
 package database
 
 import (
 package database
 
 import (
+       "bytes"
+       "encoding/json"
        "io/ioutil"
        "os"
        "reflect"
        "io/ioutil"
        "os"
        "reflect"
+       "sort"
        "testing"
 
        "testing"
 
+       acc "github.com/vapor/account"
+       "github.com/vapor/asset"
        "github.com/vapor/blockchain/pseudohsm"
        "github.com/vapor/blockchain/pseudohsm"
+       "github.com/vapor/blockchain/query"
        "github.com/vapor/crypto/ed25519/chainkd"
        "github.com/vapor/crypto/ed25519/chainkd"
+       dbm "github.com/vapor/database/leveldb"
+       "github.com/vapor/protocol/bc"
+       "github.com/vapor/testutil"
+       "github.com/vapor/wallet"
 )
 
 func TestAccountIndexKey(t *testing.T) {
 )
 
 func TestAccountIndexKey(t *testing.T) {
@@ -42,3 +52,805 @@ func TestAccountIndexKey(t *testing.T) {
                t.Fatal("accountIndexKey test err")
        }
 }
                t.Fatal("accountIndexKey test err")
        }
 }
+
+func TestDeleteContractUTXO(t *testing.T) {
+       cases := []struct {
+               utxos      []*acc.UTXO
+               deleteUTXO *acc.UTXO
+               want       []*acc.UTXO
+       }{
+               {
+                       utxos:      []*acc.UTXO{},
+                       deleteUTXO: &acc.UTXO{},
+                       want:       []*acc.UTXO{},
+               },
+               {
+                       utxos: []*acc.UTXO{
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+                       deleteUTXO: &acc.UTXO{
+                               OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                       },
+                       want: []*acc.UTXO{},
+               },
+               {
+                       utxos: []*acc.UTXO{
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x2e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x3f, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x5e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x6e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x7e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+                       deleteUTXO: &acc.UTXO{},
+                       want: []*acc.UTXO{
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x2e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x3f, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x5e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x6e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x7e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+               },
+               {
+                       utxos: []*acc.UTXO{},
+                       deleteUTXO: &acc.UTXO{
+                               OutputID: bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                       },
+                       want: []*acc.UTXO{},
+               },
+               {
+                       utxos: []*acc.UTXO{
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x0e, 0x04, 0x50, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x00, 0x01, 0x02, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x02, 0x39, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+                       deleteUTXO: &acc.UTXO{
+                               OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x02, 0x39, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                       },
+                       want: []*acc.UTXO{
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x0e, 0x04, 0x50, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x00, 0x01, 0x02, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                               &acc.UTXO{
+                                       OutputID: bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+               },
+       }
+
+       for _, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               accountStore := NewAccountStore(testDB)
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               // store mock utxos
+               for _, utxo := range c.utxos {
+                       if err := ws.SetContractUTXO(utxo.OutputID, utxo); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               // delete utxo
+               ws.DeleteContractUTXO(c.deleteUTXO.OutputID)
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               // get utxo by outputID
+               for _, utxo := range c.want {
+                       if _, err := accountStore.GetUTXO(utxo.OutputID); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestDeleteRecoveryStatus(t *testing.T) {
+       cases := []struct {
+               state *wallet.RecoveryState
+       }{
+               {
+                       state: &wallet.RecoveryState{},
+               },
+               {
+                       state: &wallet.RecoveryState{
+                               XPubs: []chainkd.XPub{
+                                       chainkd.XPub([64]byte{0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+               },
+               {
+                       state: &wallet.RecoveryState{
+                               XPubs: []chainkd.XPub{
+                                       chainkd.XPub([64]byte{0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x01, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x02, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x03, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x04, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x05, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x06, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x07, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x08, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x09, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x0a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       chainkd.XPub([64]byte{0x0b, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c, 0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               },
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               if err := ws.SetRecoveryStatus(c.state); err != nil {
+                       t.Fatal(err)
+               }
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotState, err := ws.GetRecoveryStatus()
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               if !testutil.DeepEqual(gotState, c.state) {
+                       t.Errorf("case %v: got recovery status, got: %v, want: %v.", i, gotState, c.state)
+               }
+
+               ws = walletStore.InitBatch()
+               ws.DeleteRecoveryStatus()
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotState, err = ws.GetRecoveryStatus()
+               if err == nil {
+                       t.Errorf("case %v: got state should fail.", i)
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestGetWalletInfo(t *testing.T) {
+       cases := []struct {
+               state *wallet.StatusInfo
+       }{
+               {
+                       state: &wallet.StatusInfo{},
+               },
+               {
+                       state: &wallet.StatusInfo{
+                               Version:    uint(0),
+                               WorkHeight: uint64(9),
+                               WorkHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               BestHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               BestHeight: uint64(0),
+                       },
+               },
+               {
+                       state: &wallet.StatusInfo{
+                               Version:    uint(9),
+                               WorkHeight: uint64(9999999),
+                               WorkHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               BestHash:   bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               BestHeight: uint64(100000),
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               if err := ws.SetWalletInfo(c.state); err != nil {
+                       t.Fatal(err)
+               }
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotState, err := ws.GetWalletInfo()
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               if !testutil.DeepEqual(gotState, c.state) {
+                       t.Errorf("case %v: got wallet info, got: %v, want: %v.", i, gotState, c.state)
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestDeleteUnconfirmedTransaction(t *testing.T) {
+       cases := []struct {
+               tx *query.AnnotatedTx
+       }{
+               {
+                       tx: &query.AnnotatedTx{},
+               },
+               {
+                       tx: &query.AnnotatedTx{
+                               ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               Timestamp:   uint64(100),
+                               BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               BlockHeight: uint64(100),
+                               Position:    uint32(100),
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               if err := ws.SetUnconfirmedTransaction(c.tx.ID.String(), c.tx); err != nil {
+                       t.Fatal(err)
+               }
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotTx, err := ws.GetUnconfirmedTransaction(c.tx.ID.String())
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               if !testutil.DeepEqual(gotTx, c.tx) {
+                       t.Errorf("case %v: got unconfirmed transaction, got: %v, want: %v.", i, gotTx, c.tx)
+               }
+
+               ws = walletStore.InitBatch()
+               ws.DeleteUnconfirmedTransaction(c.tx.ID.String())
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotTx, err = ws.GetUnconfirmedTransaction(c.tx.ID.String())
+               if err == nil {
+                       t.Errorf("case %v: got unconfirmed transaction should fail.", i)
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestListUnconfirmedTransactions(t *testing.T) {
+       cases := []struct {
+               txs []*query.AnnotatedTx
+       }{
+               {
+                       txs: []*query.AnnotatedTx{},
+               },
+               {
+                       txs: []*query.AnnotatedTx{
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                       },
+               },
+               {
+                       txs: []*query.AnnotatedTx{
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(100),
+                                       BlockID:     bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       BlockHeight: uint64(100),
+                                       Position:    uint32(100),
+                               },
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               for _, tx := range c.txs {
+                       if err := ws.SetUnconfirmedTransaction(tx.ID.String(), tx); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotTxs, err := ws.ListUnconfirmedTransactions()
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               sort.Sort(SortUnconfirmedTxs(gotTxs))
+               sort.Sort(SortUnconfirmedTxs(c.txs))
+
+               if !testutil.DeepEqual(gotTxs, c.txs) {
+                       t.Errorf("case %v: list unconfirmed transactions, got: %v, want: %v.", i, gotTxs, c.txs)
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+type SortUnconfirmedTxs []*query.AnnotatedTx
+
+func (s SortUnconfirmedTxs) Len() int { return len(s) }
+func (s SortUnconfirmedTxs) Less(i, j int) bool {
+       return bytes.Compare(s[i].ID.Bytes(), s[j].ID.Bytes()) < 0
+}
+func (s SortUnconfirmedTxs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func TestGetGlobalTransactionIndex(t *testing.T) {
+       cases := []struct {
+               globalTxID string
+               blockHash  bc.Hash
+               position   uint64
+       }{
+               {
+                       globalTxID: "",
+                       blockHash:  bc.NewHash([32]byte{}),
+                       position:   uint64(0),
+               },
+               {
+                       globalTxID: "8838474e18e945e2f648745a362ac6988bad172b0eef5c593038a2fc8b46261e",
+                       blockHash:  bc.NewHash([32]byte{0x00, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                       position:   uint64(0),
+               },
+               {
+                       globalTxID: "d8de517917a591daa447d6be28ffb2fac866703e4feb65e86221be9a22d3033a",
+                       blockHash:  bc.NewHash([32]byte{0x00, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                       position:   uint64(99),
+               },
+               {
+                       globalTxID: "f4c64e9f72623c26b06e17f909aec7c03c927fcf681781489257097e537b8d5a",
+                       blockHash:  bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                       position:   uint64(99),
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               ws.SetGlobalTransactionIndex(c.globalTxID, &c.blockHash, c.position)
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotIndex := ws.GetGlobalTransactionIndex(c.globalTxID)
+               wantIndex := CalcGlobalTxIndex(&c.blockHash, c.position)
+
+               if !testutil.DeepEqual(gotIndex, wantIndex) {
+                       t.Errorf("case %v: got global transaction index, got: %v, want: %v.", i, gotIndex, wantIndex)
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestGetAsset(t *testing.T) {
+       cases := []struct {
+               asset *asset.Asset
+       }{
+               {
+                       asset: &asset.Asset{
+                               AssetID:       bc.NewAssetID([32]byte{}),
+                               DefinitionMap: map[string]interface{}{},
+                       },
+               },
+               {
+                       asset: &asset.Asset{
+                               AssetID:       bc.NewAssetID([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               DefinitionMap: map[string]interface{}{},
+                       },
+               },
+               {
+                       asset: &asset.Asset{
+                               AssetID: bc.NewAssetID([32]byte{}),
+                               DefinitionMap: map[string]interface{}{
+                                       "Name": "assetname",
+                               },
+                       },
+               },
+               {
+                       asset: &asset.Asset{
+                               AssetID: bc.NewAssetID([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               DefinitionMap: map[string]interface{}{
+                                       "Name": "assetname",
+                               },
+                       },
+               },
+               {
+                       asset: &asset.Asset{
+                               AssetID: bc.NewAssetID([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                               DefinitionMap: map[string]interface{}{
+                                       "Name":   "assetname",
+                                       "Amount": "1000000",
+                               },
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               definitionByte, err := json.Marshal(c.asset.DefinitionMap)
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               ws.SetAssetDefinition(&c.asset.AssetID, definitionByte)
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               gotAsset, err := ws.GetAsset(&c.asset.AssetID)
+               if err != nil {
+                       t.Fatal(err)
+               }
+
+               if !testutil.DeepEqual(gotAsset.DefinitionMap, c.asset.DefinitionMap) {
+                       t.Errorf("case %v: got asset, got: %v, want: %v.", i, gotAsset.DefinitionMap, c.asset.DefinitionMap)
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestDeleteTransactions(t *testing.T) {
+       cases := []struct {
+               height uint64
+               txs    []*query.AnnotatedTx
+       }{
+               {
+                       height: uint64(0),
+                       txs:    []*query.AnnotatedTx{},
+               },
+               {
+                       height: uint64(0),
+                       txs: []*query.AnnotatedTx{
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(0),
+                                       Position:    uint32(2333),
+                               },
+                       },
+               },
+               {
+                       height: uint64(1000000),
+                       txs: []*query.AnnotatedTx{
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(0),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(1),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(2),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(3),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(4),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(5),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(6),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(7),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x09, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(8),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x0a, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(9),
+                               },
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               // store txs by given height
+               for _, tx := range c.txs {
+                       if err := ws.SetTransaction(c.height, tx); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               // get tx by txID
+               for j := 0; j < len(c.txs); j++ {
+                       gotTx, err := ws.GetTransaction(c.txs[j].ID.String())
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+
+                       if !testutil.DeepEqual(gotTx, c.txs[j]) {
+                               t.Errorf("case %v: got transaction, got: %v, want: %v.", i, gotTx, c.txs[j])
+                       }
+               }
+
+               // delete all txs by given height
+               ws = walletStore.InitBatch()
+               ws.DeleteTransactions(c.height)
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               // get tx by txID, it should return err
+               for _, tx := range c.txs {
+                       _, err := ws.GetTransaction(tx.ID.String())
+                       if err == nil {
+                               t.Errorf("case: %v: it should return some err.", i)
+                       }
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}
+
+func TestDeleteWalletTransactions(t *testing.T) {
+       cases := []struct {
+               height uint64
+               txs    []*query.AnnotatedTx
+       }{
+               {
+                       height: uint64(0),
+                       txs:    []*query.AnnotatedTx{},
+               },
+               {
+                       height: uint64(0),
+                       txs: []*query.AnnotatedTx{
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(0),
+                                       Position:    uint32(2333),
+                               },
+                       },
+               },
+               {
+                       height: uint64(1000000),
+                       txs: []*query.AnnotatedTx{
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x01, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(0),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x02, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(1),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x03, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(2),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x04, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(3),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x05, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(4),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x06, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(5),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x07, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(6),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x08, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(7),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x09, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(8),
+                               },
+                               &query.AnnotatedTx{
+                                       ID:          bc.NewHash([32]byte{0x0a, 0x01, 0x51, 0x31, 0x71, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c}),
+                                       Timestamp:   uint64(9988000),
+                                       BlockHeight: uint64(1000000),
+                                       Position:    uint32(9),
+                               },
+                       },
+               },
+       }
+
+       for i, c := range cases {
+               testDB := dbm.NewDB("testdb", "leveldb", "temp")
+               walletStore := NewWalletStore(testDB)
+               ws := walletStore.InitBatch()
+               // store txs by given height
+               for _, tx := range c.txs {
+                       if err := ws.SetTransaction(c.height, tx); err != nil {
+                               t.Fatal(err)
+                       }
+               }
+
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               // delete all txs
+               ws = walletStore.InitBatch()
+               ws.DeleteWalletTransactions()
+               if err := ws.CommitBatch(); err != nil {
+                       t.Fatal(err)
+               }
+
+               // get tx by txID, it should return err
+               for _, tx := range c.txs {
+                       _, err := ws.GetTransaction(tx.ID.String())
+                       if err == nil {
+                               t.Errorf("case: %v: it should return some err.", i)
+                       }
+               }
+
+               testDB.Close()
+               os.RemoveAll("temp")
+       }
+}