10 "github.com/vapor/account"
11 "github.com/vapor/asset"
12 "github.com/vapor/blockchain/pseudohsm"
13 "github.com/vapor/blockchain/signers"
14 "github.com/vapor/blockchain/txbuilder"
15 "github.com/vapor/config"
16 "github.com/vapor/consensus"
17 "github.com/vapor/crypto/ed25519/chainkd"
18 "github.com/vapor/database"
19 dbm "github.com/vapor/database/leveldb"
20 "github.com/vapor/event"
21 "github.com/vapor/protocol"
22 "github.com/vapor/protocol/bc"
23 "github.com/vapor/protocol/bc/types"
24 wt "github.com/vapor/wallet"
27 func TestWalletUpdate(t *testing.T) {
28 dirPath, err := ioutil.TempDir(".", "")
32 defer os.RemoveAll(dirPath)
34 config.CommonConfig = config.DefaultConfig()
35 testDB := dbm.NewDB("testdb", "leveldb", "temp")
41 store := database.NewStore(testDB)
42 walletStore := database.NewWalletStore(testDB)
43 dispatcher := event.NewDispatcher()
44 txPool := protocol.NewTxPool(store, dispatcher)
46 chain, err := protocol.NewChain(store, txPool, dispatcher)
51 accountStore := database.NewAccountStore(testDB)
52 accountManager := account.NewManager(accountStore, chain)
53 hsm, err := pseudohsm.New(dirPath)
58 xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
63 testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
68 controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
73 controlProg.KeyIndex = 1
75 reg := asset.NewRegistry(testDB, chain)
76 asset := bc.AssetID{V0: 5}
78 utxos := []*account.UTXO{}
79 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
80 utxos = append(utxos, btmUtxo)
81 OtherUtxo := mockUTXO(controlProg, &asset)
82 utxos = append(utxos, OtherUtxo)
84 _, txData, err := mockTxData(utxos, testAccount)
89 tx := types.NewTx(*txData)
90 block := mockSingleBlock(tx)
91 txStatus := bc.NewTransactionStatus()
92 txStatus.SetStatus(0, false)
93 txStatus.SetStatus(1, false)
94 store.SaveBlock(block, txStatus)
96 w := newMockWallet(walletStore, accountManager, reg, chain, dispatcher, true)
97 err = w.AttachBlock(block)
102 if _, err := w.GetTransactionByTxID(tx.ID.String()); err != nil {
106 wants, err := w.GetTransactions(testAccount.ID, "", 1, false)
111 if wants[0].ID != tx.ID {
112 t.Fatal("account txID mismatch")
115 for position, tx := range block.Transactions {
116 get := testDB.Get(database.CalcGlobalTxIndexKey(tx.ID.String()))
117 bh := block.BlockHeader.Hash()
118 expect := database.CalcGlobalTxIndex(&bh, uint64(position))
119 if !reflect.DeepEqual(get, expect) {
120 t.Fatalf("position#%d: compare retrieved globalTxIdx err", position)
125 func TestRescanWallet(t *testing.T) {
126 // prepare wallet & db.
127 dirPath, err := ioutil.TempDir(".", "")
131 defer os.RemoveAll(dirPath)
133 config.CommonConfig = config.DefaultConfig()
134 testDB := dbm.NewDB("testdb", "leveldb", "temp")
135 walletStore := database.NewWalletStore(testDB)
141 store := database.NewStore(testDB)
142 dispatcher := event.NewDispatcher()
143 txPool := protocol.NewTxPool(store, dispatcher)
144 chain, err := protocol.NewChain(store, txPool, dispatcher)
149 statusInfo := wt.StatusInfo{
151 WorkHash: bc.Hash{V0: 0xff},
153 if err := walletStore.SetWalletInfo(&statusInfo); err != nil {
156 walletInfo, err := walletStore.GetWalletInfo()
161 accountStore := database.NewAccountStore(testDB)
162 accountManager := account.NewManager(accountStore, chain)
163 w := newMockWallet(walletStore, accountManager, nil, chain, dispatcher, false)
167 w.Status = *walletInfo
170 if err := w.LoadWalletInfo(); err != nil {
174 block := config.GenesisBlock()
175 if w.Status.WorkHash != block.Hash() {
176 t.Fatal("reattach from genesis block")
180 func TestMemPoolTxQueryLoop(t *testing.T) {
181 dirPath, err := ioutil.TempDir(".", "")
185 config.CommonConfig = config.DefaultConfig()
186 testDB := dbm.NewDB("testdb", "leveldb", dirPath)
189 os.RemoveAll(dirPath)
192 store := database.NewStore(testDB)
193 dispatcher := event.NewDispatcher()
194 txPool := protocol.NewTxPool(store, dispatcher)
196 chain, err := protocol.NewChain(store, txPool, dispatcher)
201 accountStore := database.NewAccountStore(testDB)
202 accountManager := account.NewManager(accountStore, chain)
203 hsm, err := pseudohsm.New(dirPath)
208 xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
213 testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
218 controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
223 controlProg.KeyIndex = 1
225 reg := asset.NewRegistry(testDB, chain)
226 asset := bc.AssetID{V0: 5}
228 utxos := []*account.UTXO{}
229 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
230 utxos = append(utxos, btmUtxo)
231 OtherUtxo := mockUTXO(controlProg, &asset)
232 utxos = append(utxos, OtherUtxo)
234 _, txData, err := mockTxData(utxos, testAccount)
239 tx := types.NewTx(*txData)
240 txStatus := bc.NewTransactionStatus()
241 txStatus.SetStatus(0, false)
242 walletStore := database.NewWalletStore(testDB)
243 w := newMockWallet(walletStore, accountManager, reg, chain, dispatcher, false)
244 go w.MemPoolTxQueryLoop()
245 w.EventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgNewTx}})
246 time.Sleep(time.Millisecond * 10)
247 if _, err := w.GetUnconfirmedTxByTxID(tx.ID.String()); err != nil {
248 t.Fatal("dispatch new tx msg error:", err)
250 w.EventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgRemoveTx}})
251 time.Sleep(time.Millisecond * 10)
252 txs, err := w.GetUnconfirmedTxs(testAccount.ID)
254 t.Fatal("get unconfirmed tx error:", err)
258 t.Fatal("dispatch remove tx msg error")
261 w.EventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: 2}})
264 func mockUTXO(controlProg *account.CtrlProgram, assetID *bc.AssetID) *account.UTXO {
265 utxo := &account.UTXO{}
266 utxo.OutputID = bc.Hash{V0: 1}
267 utxo.SourceID = bc.Hash{V0: 2}
268 utxo.AssetID = *assetID
269 utxo.Amount = 1000000000
271 utxo.ControlProgram = controlProg.ControlProgram
272 utxo.AccountID = controlProg.AccountID
273 utxo.Address = controlProg.Address
274 utxo.ControlProgramIndex = controlProg.KeyIndex
278 func mockTxData(utxos []*account.UTXO, testAccount *account.Account) (*txbuilder.Template, *types.TxData, error) {
279 tplBuilder := txbuilder.NewBuilder(time.Now())
281 for _, utxo := range utxos {
282 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo)
286 tplBuilder.AddInput(txInput, sigInst)
288 out := &types.TxOutput{}
289 if utxo.AssetID == *consensus.BTMAssetID {
290 out = types.NewIntraChainOutput(utxo.AssetID, 100, utxo.ControlProgram)
292 out = types.NewIntraChainOutput(utxo.AssetID, utxo.Amount, utxo.ControlProgram)
294 tplBuilder.AddOutput(out)
297 return tplBuilder.Build()
300 type mockWallet struct {
304 func newMockWallet(store wt.WalletStore, account *account.Manager, asset *asset.Registry, chain *protocol.Chain, dispatcher *event.Dispatcher, txIndexFlag bool) *wt.Wallet {
305 wallet := &wt.Wallet{
310 RecoveryMgr: wt.NewRecoveryManager(store, account),
311 EventDispatcher: dispatcher,
312 TxIndexFlag: txIndexFlag,
314 wallet.TxMsgSub, _ = wallet.EventDispatcher.Subscribe(protocol.TxMsgEvent{})
318 func mockSingleBlock(tx *types.Tx) *types.Block {
320 BlockHeader: types.BlockHeader{
324 Transactions: []*types.Tx{config.GenesisTx(), tx},