From: Chengcheng Zhang <943420582@qq.com> Date: Thu, 18 Jul 2019 16:31:08 +0000 (+0800) Subject: Wallet store test (#312) X-Git-Tag: v1.0.5~104 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fvapor.git;a=commitdiff_plain;h=e278744e6d00511a70af4e03161151fb88d1f542;hp=947a1eb467d61c388785d9625c93713437da7608 Wallet store test (#312) * 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 --- diff --git a/database/account_store.go b/database/account_store.go index 619dd8d4..d050f494 100644 --- a/database/account_store.go +++ b/database/account_store.go @@ -314,7 +314,7 @@ func (store *AccountStore) ListControlPrograms() ([]*acc.CtrlProgram, error) { 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() diff --git a/database/account_store_test.go b/database/account_store_test.go index 4fdb7178..680554c9 100644 --- a/database/account_store_test.go +++ b/database/account_store_test.go @@ -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() @@ -270,11 +270,16 @@ func TestDeleteStandardUTXO(t *testing.T) { 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() diff --git a/database/wallet_store.go b/database/wallet_store.go index a0c2a36d..c0bf9f93 100644 --- a/database/wallet_store.go +++ b/database/wallet_store.go @@ -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 { @@ -381,7 +381,6 @@ func (store *WalletStore) ListTransactions(accountID string, StartTxID string, c annotatedTxs = append([]*query.AnnotatedTx{annotatedTx}, annotatedTxs...) txNum-- } - } return annotatedTxs, nil diff --git a/database/wallet_store_test.go b/database/wallet_store_test.go index f2aa9434..3c0f91e5 100644 --- a/database/wallet_store_test.go +++ b/database/wallet_store_test.go @@ -1,13 +1,23 @@ package database import ( + "bytes" + "encoding/json" "io/ioutil" "os" "reflect" + "sort" "testing" + acc "github.com/vapor/account" + "github.com/vapor/asset" "github.com/vapor/blockchain/pseudohsm" + "github.com/vapor/blockchain/query" "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) { @@ -42,3 +52,805 @@ func TestAccountIndexKey(t *testing.T) { 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") + } +}