11 "github.com/vapor/account"
12 "github.com/vapor/asset"
13 "github.com/vapor/blockchain/pseudohsm"
14 "github.com/vapor/blockchain/signers"
15 "github.com/vapor/blockchain/txbuilder"
16 "github.com/vapor/config"
17 "github.com/vapor/consensus"
18 "github.com/vapor/crypto/ed25519/chainkd"
19 "github.com/vapor/database"
20 dbm "github.com/vapor/database/leveldb"
21 "github.com/vapor/event"
22 "github.com/vapor/protocol"
23 "github.com/vapor/protocol/bc"
24 "github.com/vapor/protocol/bc/types"
25 wt "github.com/vapor/wallet"
28 func TestWalletUpdate(t *testing.T) {
30 dirPath, err := ioutil.TempDir(".", "")
34 defer os.RemoveAll(dirPath)
36 config.CommonConfig = config.DefaultConfig()
37 testDB := dbm.NewDB("testdb", "leveldb", "temp")
43 store := database.NewStore(testDB)
44 walletStore := database.NewWalletStore(testDB)
45 dispatcher := event.NewDispatcher()
46 txPool := protocol.NewTxPool(store, dispatcher)
48 chain, err := protocol.NewChain(store, txPool, dispatcher)
53 accountStore := database.NewAccountStore(testDB)
54 accountManager := account.NewManager(accountStore, chain)
55 hsm, err := pseudohsm.New(dirPath)
60 xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
65 testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
70 controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
75 controlProg.KeyIndex = 1
77 reg := asset.NewRegistry(testDB, chain)
78 asset := bc.AssetID{V0: 5}
80 utxos := []*account.UTXO{}
81 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
82 utxos = append(utxos, btmUtxo)
83 OtherUtxo := mockUTXO(controlProg, &asset)
84 utxos = append(utxos, OtherUtxo)
86 _, txData, err := mockTxData(utxos, testAccount)
91 tx := types.NewTx(*txData)
92 block := mockSingleBlock(tx)
93 txStatus := bc.NewTransactionStatus()
94 txStatus.SetStatus(0, false)
95 txStatus.SetStatus(1, false)
96 store.SaveBlock(block, txStatus)
98 w := newMockWallet(walletStore, accountManager, reg, chain, dispatcher, true)
99 err = w.Wallet.AttachBlock(block)
104 if _, err := w.Wallet.GetTransactionByTxID(tx.ID.String()); err != nil {
108 wants, err := w.Wallet.GetTransactions(testAccount.ID, "", 1, false)
113 if wants[0].ID != tx.ID {
114 t.Fatal("account txID mismatch")
117 for position, tx := range block.Transactions {
118 get := testDB.Get(database.CalcGlobalTxIndexKey(tx.ID.String()))
119 bh := block.BlockHeader.Hash()
120 expect := database.CalcGlobalTxIndex(&bh, uint64(position))
121 if !reflect.DeepEqual(get, expect) {
122 t.Fatalf("position#%d: compare retrieved globalTxIdx err", position)
126 for i := 0; i < 100; i++ {
127 fmt.Printf("case i: %v\n", i)
132 func TestRescanWallet(t *testing.T) {
134 // prepare wallet & db.
135 dirPath, err := ioutil.TempDir(".", "")
139 defer os.RemoveAll(dirPath)
141 config.CommonConfig = config.DefaultConfig()
142 testDB := dbm.NewDB("testdb", "leveldb", "temp")
143 walletStore := database.NewWalletStore(testDB)
149 store := database.NewStore(testDB)
150 dispatcher := event.NewDispatcher()
151 txPool := protocol.NewTxPool(store, dispatcher)
152 chain, err := protocol.NewChain(store, txPool, dispatcher)
157 statusInfo := wt.StatusInfo{
159 WorkHash: bc.Hash{V0: 0xff},
161 if err := walletStore.SetWalletInfo(&statusInfo); err != nil {
164 walletInfo, err := walletStore.GetWalletInfo()
169 accountStore := database.NewAccountStore(testDB)
170 accountManager := account.NewManager(accountStore, chain)
171 w := newMockWallet(walletStore, accountManager, nil, chain, dispatcher, false)
175 w.Wallet.Status = *walletInfo
178 if err := w.Wallet.LoadWalletInfo(); err != nil {
182 block := config.GenesisBlock()
183 if w.Wallet.Status.WorkHash != block.Hash() {
184 t.Fatal("reattach from genesis block")
188 for i := 0; i < 100; i++ {
189 fmt.Printf("case i: %v\n", i)
194 func TestMemPoolTxQueryLoop(t *testing.T) {
196 dirPath, err := ioutil.TempDir(".", "")
200 config.CommonConfig = config.DefaultConfig()
201 testDB := dbm.NewDB("testdb", "leveldb", dirPath)
204 os.RemoveAll(dirPath)
207 store := database.NewStore(testDB)
208 dispatcher := event.NewDispatcher()
209 txPool := protocol.NewTxPool(store, dispatcher)
211 chain, err := protocol.NewChain(store, txPool, dispatcher)
216 accountStore := database.NewAccountStore(testDB)
217 accountManager := account.NewManager(accountStore, chain)
218 hsm, err := pseudohsm.New(dirPath)
223 xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
228 testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
233 controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
238 controlProg.KeyIndex = 1
240 reg := asset.NewRegistry(testDB, chain)
241 asset := bc.AssetID{V0: 5}
243 utxos := []*account.UTXO{}
244 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
245 utxos = append(utxos, btmUtxo)
246 OtherUtxo := mockUTXO(controlProg, &asset)
247 utxos = append(utxos, OtherUtxo)
249 _, txData, err := mockTxData(utxos, testAccount)
254 tx := types.NewTx(*txData)
255 txStatus := bc.NewTransactionStatus()
256 txStatus.SetStatus(0, false)
257 walletStore := database.NewWalletStore(testDB)
258 w := newMockWallet(walletStore, accountManager, reg, chain, dispatcher, false)
259 go w.Wallet.MemPoolTxQueryLoop()
260 w.Wallet.EventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgNewTx}})
261 time.Sleep(time.Millisecond * 10)
262 if _, err := w.Wallet.GetUnconfirmedTxByTxID(tx.ID.String()); err != nil {
263 t.Fatal("dispatch new tx msg error:", err)
265 w.Wallet.EventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgRemoveTx}})
266 time.Sleep(time.Millisecond * 10)
267 txs, err := w.Wallet.GetUnconfirmedTxs(testAccount.ID)
269 t.Fatal("get unconfirmed tx error:", err)
273 t.Fatal("dispatch remove tx msg error")
276 w.Wallet.EventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: 2}})
278 for i := 0; i < 1; i++ {
279 fmt.Printf("case i: %v\n", i)
284 func mockUTXO(controlProg *account.CtrlProgram, assetID *bc.AssetID) *account.UTXO {
285 utxo := &account.UTXO{}
286 utxo.OutputID = bc.Hash{V0: 1}
287 utxo.SourceID = bc.Hash{V0: 2}
288 utxo.AssetID = *assetID
289 utxo.Amount = 1000000000
291 utxo.ControlProgram = controlProg.ControlProgram
292 utxo.AccountID = controlProg.AccountID
293 utxo.Address = controlProg.Address
294 utxo.ControlProgramIndex = controlProg.KeyIndex
298 func mockTxData(utxos []*account.UTXO, testAccount *account.Account) (*txbuilder.Template, *types.TxData, error) {
299 tplBuilder := txbuilder.NewBuilder(time.Now())
301 for _, utxo := range utxos {
302 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo)
306 tplBuilder.AddInput(txInput, sigInst)
308 out := &types.TxOutput{}
309 if utxo.AssetID == *consensus.BTMAssetID {
310 out = types.NewIntraChainOutput(utxo.AssetID, 100, utxo.ControlProgram)
312 out = types.NewIntraChainOutput(utxo.AssetID, utxo.Amount, utxo.ControlProgram)
314 tplBuilder.AddOutput(out)
317 return tplBuilder.Build()
320 type mockWallet struct {
324 // func newMockWallet(store wt.WalletStore, account *account.Manager, asset *asset.Registry, chain *protocol.Chain, dispatcher *event.Dispatcher, txIndexFlag bool) *mockWallet {
325 // w, err := wt.NewWallet(store, account, asset, nil, chain, dispatcher, txIndexFlag)
330 // w.Status.WorkHash = bc.NewHash(hash)
331 // return &mockWallet{w}
334 func newMockWallet(store wt.WalletStore, account *account.Manager, asset *asset.Registry, chain *protocol.Chain, dispatcher *event.Dispatcher, txIndexFlag bool) *mockWallet {
335 wallet := &wt.Wallet{
340 RecoveryMgr: wt.NewRecoveryManager(store, account),
341 EventDispatcher: dispatcher,
342 TxIndexFlag: txIndexFlag,
344 wallet.TxMsgSub, _ = wallet.EventDispatcher.Subscribe(protocol.TxMsgEvent{})
345 return &mockWallet{wallet}
349 func mockSingleBlock(tx *types.Tx) *types.Block {
351 BlockHeader: types.BlockHeader{
355 Transactions: []*types.Tx{config.GenesisTx(), tx},