10 "github.com/bytom/account"
11 "github.com/bytom/asset"
12 "github.com/bytom/blockchain/pseudohsm"
13 "github.com/bytom/blockchain/signers"
14 "github.com/bytom/blockchain/txbuilder"
15 "github.com/bytom/config"
16 "github.com/bytom/consensus"
17 "github.com/bytom/crypto/ed25519/chainkd"
18 "github.com/bytom/database"
19 dbm "github.com/bytom/database/leveldb"
20 "github.com/bytom/event"
21 "github.com/bytom/protocol"
22 "github.com/bytom/protocol/bc"
23 "github.com/bytom/protocol/bc/types"
26 func TestWalletVersion(t *testing.T) {
28 dirPath, err := ioutil.TempDir(".", "")
32 defer os.RemoveAll(dirPath)
34 testDB := dbm.NewDB("testdb", "leveldb", "temp")
35 defer os.RemoveAll("temp")
37 dispatcher := event.NewDispatcher()
38 w := mockWallet(testDB, nil, nil, nil, dispatcher, false)
40 // legacy status test case
41 type legacyStatusInfo struct {
47 rawWallet, err := json.Marshal(legacyStatusInfo{})
49 t.Fatal("Marshal legacyStatusInfo")
52 w.DB.Set(walletKey, rawWallet)
53 rawWallet = w.DB.Get(walletKey)
55 t.Fatal("fail to load wallet StatusInfo")
58 if err := json.Unmarshal(rawWallet, &w.status); err != nil {
62 if err := w.checkWalletInfo(); err != errWalletVersionMismatch {
63 t.Fatal("fail to detect legacy wallet version")
66 // lower wallet version test case
67 lowerVersion := StatusInfo{Version: currentVersion - 1}
68 rawWallet, err = json.Marshal(lowerVersion)
70 t.Fatal("save wallet info")
73 w.DB.Set(walletKey, rawWallet)
74 rawWallet = w.DB.Get(walletKey)
76 t.Fatal("fail to load wallet StatusInfo")
79 if err := json.Unmarshal(rawWallet, &w.status); err != nil {
83 if err := w.checkWalletInfo(); err != errWalletVersionMismatch {
84 t.Fatal("fail to detect expired wallet version")
88 func TestWalletUpdate(t *testing.T) {
89 dirPath, err := ioutil.TempDir(".", "")
93 defer os.RemoveAll(dirPath)
95 testDB := dbm.NewDB("testdb", "leveldb", "temp")
96 defer os.RemoveAll("temp")
98 store := database.NewStore(testDB)
99 dispatcher := event.NewDispatcher()
100 txPool := protocol.NewTxPool(store, dispatcher)
102 chain, err := protocol.NewChain(store, txPool)
107 accountManager := account.NewManager(testDB, chain)
108 hsm, err := pseudohsm.New(dirPath)
113 xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
118 testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
123 controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
128 controlProg.KeyIndex = 1
130 reg := asset.NewRegistry(testDB, chain)
131 asset, err := reg.Define([]chainkd.XPub{xpub1.XPub}, 1, nil, 0, "TESTASSET", nil)
136 utxos := []*account.UTXO{}
137 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
138 utxos = append(utxos, btmUtxo)
139 OtherUtxo := mockUTXO(controlProg, &asset.AssetID)
140 utxos = append(utxos, OtherUtxo)
142 _, txData, err := mockTxData(utxos, testAccount)
147 tx := types.NewTx(*txData)
148 block := mockSingleBlock(tx)
149 txStatus := bc.NewTransactionStatus()
150 txStatus.SetStatus(0, false)
151 txStatus.SetStatus(1, false)
152 store.SaveBlock(block, txStatus)
154 w := mockWallet(testDB, accountManager, reg, chain, dispatcher, true)
155 err = w.AttachBlock(block)
160 if _, err := w.GetTransactionByTxID(tx.ID.String()); err != nil {
164 wants, err := w.GetTransactions("")
169 if wants[0].ID != tx.ID {
170 t.Fatal("account txID mismatch")
174 func TestMemPoolTxQueryLoop(t *testing.T) {
175 dirPath, err := ioutil.TempDir(".", "")
179 defer os.RemoveAll(dirPath)
181 testDB := dbm.NewDB("testdb", "leveldb", dirPath)
183 store := database.NewStore(testDB)
184 dispatcher := event.NewDispatcher()
185 txPool := protocol.NewTxPool(store, dispatcher)
187 chain, err := protocol.NewChain(store, txPool)
192 accountManager := account.NewManager(testDB, chain)
193 hsm, err := pseudohsm.New(dirPath)
198 xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
203 testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
208 controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
213 controlProg.KeyIndex = 1
215 reg := asset.NewRegistry(testDB, chain)
216 asset, err := reg.Define([]chainkd.XPub{xpub1.XPub}, 1, nil, 0, "TESTASSET", nil)
221 utxos := []*account.UTXO{}
222 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
223 utxos = append(utxos, btmUtxo)
224 OtherUtxo := mockUTXO(controlProg, &asset.AssetID)
225 utxos = append(utxos, OtherUtxo)
227 _, txData, err := mockTxData(utxos, testAccount)
232 tx := types.NewTx(*txData)
233 //block := mockSingleBlock(tx)
234 txStatus := bc.NewTransactionStatus()
235 txStatus.SetStatus(0, false)
236 w, err := NewWallet(testDB, accountManager, reg, hsm, chain, dispatcher, false)
237 go w.memPoolTxQueryLoop()
238 w.eventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgNewTx}})
239 time.Sleep(time.Millisecond * 10)
240 if _, err = w.GetUnconfirmedTxByTxID(tx.ID.String()); err != nil {
241 t.Fatal("disaptch new tx msg error:", err)
243 w.eventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: protocol.MsgRemoveTx}})
244 time.Sleep(time.Millisecond * 10)
245 txs, err := w.GetUnconfirmedTxs(testAccount.ID)
247 t.Fatal("get unconfirmed tx error:", err)
251 t.Fatal("disaptch remove tx msg error")
254 w.eventDispatcher.Post(protocol.TxMsgEvent{TxMsg: &protocol.TxPoolMsg{TxDesc: &protocol.TxDesc{Tx: tx}, MsgType: 2}})
257 func mockUTXO(controlProg *account.CtrlProgram, assetID *bc.AssetID) *account.UTXO {
258 utxo := &account.UTXO{}
259 utxo.OutputID = bc.Hash{V0: 1}
260 utxo.SourceID = bc.Hash{V0: 2}
261 utxo.AssetID = *assetID
262 utxo.Amount = 1000000000
264 utxo.ControlProgram = controlProg.ControlProgram
265 utxo.AccountID = controlProg.AccountID
266 utxo.Address = controlProg.Address
267 utxo.ControlProgramIndex = controlProg.KeyIndex
271 func mockTxData(utxos []*account.UTXO, testAccount *account.Account) (*txbuilder.Template, *types.TxData, error) {
272 tplBuilder := txbuilder.NewBuilder(time.Now())
274 for _, utxo := range utxos {
275 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo)
279 tplBuilder.AddInput(txInput, sigInst)
281 out := &types.TxOutput{}
282 if utxo.AssetID == *consensus.BTMAssetID {
283 out = types.NewTxOutput(utxo.AssetID, 100, utxo.ControlProgram)
285 out = types.NewTxOutput(utxo.AssetID, utxo.Amount, utxo.ControlProgram)
287 tplBuilder.AddOutput(out)
290 return tplBuilder.Build()
293 func mockWallet(walletDB dbm.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain, dispatcher *event.Dispatcher, txIndexFlag bool) *Wallet {
299 RecoveryMgr: newRecoveryManager(walletDB, account),
300 eventDispatcher: dispatcher,
301 TxIndexFlag: txIndexFlag,
303 wallet.txMsgSub, _ = wallet.eventDispatcher.Subscribe(protocol.TxMsgEvent{})
307 func mockSingleBlock(tx *types.Tx) *types.Block {
309 BlockHeader: types.BlockHeader{
312 Bits: 2305843009230471167,
314 Transactions: []*types.Tx{config.GenesisTx(), tx},