OSDN Git Service

update LoadWalletInfo
[bytom/vapor.git] / test / wallet_test.go
1 package test
2
3 import (
4         "io/ioutil"
5         "os"
6         "reflect"
7         "testing"
8         "time"
9
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"
25 )
26
27 func TestWalletUpdate(t *testing.T) {
28         dirPath, err := ioutil.TempDir(".", "")
29         if err != nil {
30                 t.Fatal(err)
31         }
32         defer os.RemoveAll(dirPath)
33
34         config.CommonConfig = config.DefaultConfig()
35         testDB := dbm.NewDB("testdb", "leveldb", "temp")
36         defer func() {
37                 testDB.Close()
38                 os.RemoveAll("temp")
39         }()
40
41         store := database.NewStore(testDB)
42         walletStore := database.NewWalletStore(testDB)
43         dispatcher := event.NewDispatcher()
44         txPool := protocol.NewTxPool(store, dispatcher)
45
46         chain, err := protocol.NewChain(store, txPool, dispatcher)
47         if err != nil {
48                 t.Fatal(err)
49         }
50
51         accountStore := database.NewAccountStore(testDB)
52         accountManager := account.NewManager(accountStore, chain)
53         hsm, err := pseudohsm.New(dirPath)
54         if err != nil {
55                 t.Fatal(err)
56         }
57
58         xpub1, _, err := hsm.XCreate("test_pub1", "password", "en")
59         if err != nil {
60                 t.Fatal(err)
61         }
62
63         testAccount, err := accountManager.Create([]chainkd.XPub{xpub1.XPub}, 1, "testAccount", signers.BIP0044)
64         if err != nil {
65                 t.Fatal(err)
66         }
67
68         controlProg, err := accountManager.CreateAddress(testAccount.ID, false)
69         if err != nil {
70                 t.Fatal(err)
71         }
72
73         controlProg.KeyIndex = 1
74
75         reg := asset.NewRegistry(testDB, chain)
76         // reg := asset.NewRegistry(testDB, nil)
77         asset := bc.AssetID{V0: 5}
78
79         utxos := []*account.UTXO{}
80         btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
81         utxos = append(utxos, btmUtxo)
82         OtherUtxo := mockUTXO(controlProg, &asset)
83         utxos = append(utxos, OtherUtxo)
84
85         _, txData, err := mockTxData(utxos, testAccount)
86         if err != nil {
87                 t.Fatal(err)
88         }
89
90         tx := types.NewTx(*txData)
91         block := mockSingleBlock(tx)
92         txStatus := bc.NewTransactionStatus()
93         txStatus.SetStatus(0, false)
94         txStatus.SetStatus(1, false)
95         store.SaveBlock(block, txStatus)
96
97         w := newMockWallet(walletStore, accountManager, reg, chain, dispatcher, true)
98         err = w.Wallet.AttachBlock(block)
99         if err != nil {
100                 t.Fatal(err)
101         }
102
103         if _, err := w.Wallet.GetTransactionByTxID(tx.ID.String()); err != nil {
104                 t.Fatal(err)
105         }
106
107         wants, err := w.Wallet.GetTransactions(testAccount.ID, "", 1, false)
108         if len(wants) != 1 {
109                 t.Fatal(err)
110         }
111
112         if wants[0].ID != tx.ID {
113                 t.Fatal("account txID mismatch")
114         }
115
116         for position, tx := range block.Transactions {
117                 get := testDB.Get(database.CalcGlobalTxIndexKey(tx.ID.String()))
118                 bh := block.BlockHeader.Hash()
119                 expect := database.CalcGlobalTxIndex(&bh, uint64(position))
120                 if !reflect.DeepEqual(get, expect) {
121                         t.Fatalf("position#%d: compare retrieved globalTxIdx err", position)
122                 }
123         }
124 }
125
126 // func TestRescanWallet(t *testing.T) {
127 //      // prepare wallet & db
128 //      dirPath, err := ioutil.TempDir(".", "")
129 //      if err != nil {
130 //              t.Fatal(err)
131 //      }
132 //      defer os.RemoveAll(dirPath)
133
134 //      config.CommonConfig = config.DefaultConfig()
135 //      testDB := dbm.NewDB("testdb", "leveldb", "temp")
136 //      walletStore := database.NewWalletStore(testDB)
137 //      defer func() {
138 //              testDB.Close()
139 //              os.RemoveAll("temp")
140 //      }()
141
142 //      store := database.NewStore(testDB)
143 //      dispatcher := event.NewDispatcher()
144 //      txPool := protocol.NewTxPool(store, dispatcher)
145 //      chain, err := protocol.NewChain(store, txPool, dispatcher)
146 //      if err != nil {
147 //              t.Fatal(err)
148 //      }
149
150 //      statusInfo := wt.StatusInfo{
151 //              Version:  uint(1),
152 //              WorkHash: bc.Hash{V0: 0xff},
153 //      }
154 //      if err := walletStore.SetWalletInfo(&statusInfo); err != nil {
155 //              t.Fatal(err)
156 //      }
157 //      walletInfo, err := walletStore.GetWalletInfo()
158 //      if err != nil {
159 //              t.Fatal(err)
160 //      }
161 //      // w.status =
162
163 //      // rawWallet, err := json.Marshal(statusInfo)
164 //      // if err != nil {
165 //      //      t.Fatal("save wallet info")
166 //      // }
167
168 //      w := newMockWallet(walletStore, nil, nil, chain, dispatcher, false)
169
170 //      // w.store.SetWalletInfo(rawWallet)
171 //      // rawWallet = w.store.GetWalletInfo()
172 //      // if rawWallet == nil {
173 //      //      t.Fatal("fail to load wallet StatusInfo")
174 //      // }
175
176 //      if err := json.Unmarshal(rawWallet, &w.status); err != nil {
177 //              t.Fatal(err)
178 //      }
179
180 //      // rescan wallet
181 //      if err := w.LoadWalletInfo(); err != nil {
182 //              t.Fatal(err)
183 //      }
184
185 //      block := config.GenesisBlock()
186 //      if w.status.WorkHash != block.Hash() {
187 //              t.Fatal("reattach from genesis block")
188 //      }
189 // }
190
191 func mockUTXO(controlProg *account.CtrlProgram, assetID *bc.AssetID) *account.UTXO {
192         utxo := &account.UTXO{}
193         utxo.OutputID = bc.Hash{V0: 1}
194         utxo.SourceID = bc.Hash{V0: 2}
195         utxo.AssetID = *assetID
196         utxo.Amount = 1000000000
197         utxo.SourcePos = 0
198         utxo.ControlProgram = controlProg.ControlProgram
199         utxo.AccountID = controlProg.AccountID
200         utxo.Address = controlProg.Address
201         utxo.ControlProgramIndex = controlProg.KeyIndex
202         return utxo
203 }
204
205 func mockTxData(utxos []*account.UTXO, testAccount *account.Account) (*txbuilder.Template, *types.TxData, error) {
206         tplBuilder := txbuilder.NewBuilder(time.Now())
207
208         for _, utxo := range utxos {
209                 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo)
210                 if err != nil {
211                         return nil, nil, err
212                 }
213                 tplBuilder.AddInput(txInput, sigInst)
214
215                 out := &types.TxOutput{}
216                 if utxo.AssetID == *consensus.BTMAssetID {
217                         out = types.NewIntraChainOutput(utxo.AssetID, 100, utxo.ControlProgram)
218                 } else {
219                         out = types.NewIntraChainOutput(utxo.AssetID, utxo.Amount, utxo.ControlProgram)
220                 }
221                 tplBuilder.AddOutput(out)
222         }
223
224         return tplBuilder.Build()
225 }
226
227 type mockWallet struct {
228         Wallet *wt.Wallet
229 }
230
231 func newMockWallet(store wt.WalletStore, account *account.Manager, asset *asset.Registry, chain *protocol.Chain, dispatcher *event.Dispatcher, txIndexFlag bool) *mockWallet {
232         w, err := wt.NewWallet(store, account, asset, nil, chain, dispatcher, txIndexFlag)
233         if err != nil {
234                 panic(err)
235         }
236         return &mockWallet{w}
237 }
238
239 func mockSingleBlock(tx *types.Tx) *types.Block {
240         return &types.Block{
241                 BlockHeader: types.BlockHeader{
242                         Version: 1,
243                         Height:  1,
244                         PreviousBlockHash: bc.Hash{
245                                 V0: uint64(14952355164967094643),
246                                 V1: uint64(2960316323621296529),
247                                 V2: uint64(4202730371317372163),
248                                 V3: uint64(7569611631634777133),
249                         },
250                 },
251                 Transactions: []*types.Tx{config.GenesisTx(), tx},
252         }
253 }