10 "github.com/tendermint/go-wire/data/base58"
11 dbm "github.com/tendermint/tmlibs/db"
13 "github.com/bytom/account"
14 "github.com/bytom/asset"
15 "github.com/bytom/blockchain/pseudohsm"
16 "github.com/bytom/blockchain/txbuilder"
17 "github.com/bytom/consensus"
18 "github.com/bytom/crypto/ed25519/chainkd"
19 "github.com/bytom/crypto/sha3pool"
20 "github.com/bytom/database/leveldb"
21 "github.com/bytom/protocol"
22 "github.com/bytom/protocol/bc"
23 "github.com/bytom/protocol/bc/types"
26 func TestWalletUpdate(t *testing.T) {
27 dirPath, err := ioutil.TempDir(".", "")
31 defer os.RemoveAll(dirPath)
33 testDB := dbm.NewDB("testdb", "leveldb", "temp")
34 defer os.RemoveAll("temp")
36 store := leveldb.NewStore(testDB)
37 txPool := protocol.NewTxPool()
39 chain, err := protocol.NewChain(store, txPool)
44 accountManager := account.NewManager(testDB, chain)
45 hsm, err := pseudohsm.New(dirPath)
50 xpub1, err := hsm.XCreate("test_pub1", "password")
55 testAccount, err := accountManager.Create(nil, []chainkd.XPub{xpub1.XPub}, 1, "testAccount")
60 controlProg, err := accountManager.CreateAddress(nil, testAccount.ID, false)
65 controlProg.KeyIndex = 1
67 reg := asset.NewRegistry(testDB, chain)
68 asset, err := reg.Define([]chainkd.XPub{xpub1.XPub}, 1, nil, "TESTASSET")
73 utxos := []*account.UTXO{}
74 btmUtxo := mockUTXO(controlProg, consensus.BTMAssetID)
75 utxos = append(utxos, btmUtxo)
76 OtherUtxo := mockUTXO(controlProg, &asset.AssetID)
77 utxos = append(utxos, OtherUtxo)
79 _, txData, err := mockTxData(utxos, testAccount)
84 tx := types.NewTx(*txData)
85 block := mockSingleBlock(tx)
86 txStatus := bc.NewTransactionStatus()
87 store.SaveBlock(block, txStatus)
89 w := mockWallet(testDB, accountManager, reg, chain)
90 err = w.AttachBlock(block)
95 want, err := w.GetTransactionsByTxID(tx.ID.String())
100 wants, err := w.GetTransactionsByTxID("")
106 func TestExportAndImportPrivKey(t *testing.T) {
107 dirPath, err := ioutil.TempDir(".", "")
111 defer os.RemoveAll(dirPath)
113 testDB := dbm.NewDB("testdb", "leveldb", "temp")
114 defer os.RemoveAll("temp")
116 store := leveldb.NewStore(testDB)
117 txPool := protocol.NewTxPool()
119 chain, err := protocol.NewChain(store, txPool)
124 acntManager := account.NewManager(testDB, chain)
125 reg := asset.NewRegistry(testDB, chain)
127 hsm, err := pseudohsm.New(dirPath)
133 xpub, err := hsm.XCreate("alias", pwd)
138 w, err := NewWallet(testDB, acntManager, reg, hsm, chain)
143 ctx := context.Background()
144 acnt1, err := w.AccountMgr.Create(ctx, []chainkd.XPub{xpub.XPub}, 1, "account-alias")
149 priv, err := w.ExportAccountPrivKey(xpub.XPub, pwd)
151 wantPriv, err := hsm.LoadChainKDKey(xpub.XPub, pwd)
156 sha3pool.Sum256(hashed[:], wantPriv[:])
158 tmp := append(wantPriv[:], hashed[:4]...)
159 res := base58.Encode(tmp)
162 t.Fatalf("XPrivs should be identical.\nBefore: %v\n After: %v\n", *priv, res)
165 rawPriv, err := base58.Decode(*priv)
170 if len(rawPriv) != 68 {
171 t.Fatal("invalid private key hash length")
175 copy(xprv[:], rawPriv[:64])
177 _, err = w.ImportAccountPrivKey(xprv, xpub.Alias, pwd, 0, acnt1.Alias)
178 if err != pseudohsm.ErrDuplicateKeyAlias {
182 hsm.XDelete(xpub.XPub, pwd)
184 _, err = w.ImportAccountPrivKey(xprv, xpub.Alias, pwd, 0, acnt1.Alias)
185 if err != account.ErrDuplicateAlias {
189 w.AccountMgr.DeleteAccount(acnt1.Alias)
191 acnt2, err := w.ImportAccountPrivKey(xprv, xpub.Alias, pwd, 0, acnt1.Alias)
196 if acnt2.XPub != acnt1.XPubs[0] {
197 t.Fatalf("XPubs should be identical.\nBefore: %v\n After: %v\n", acnt1.XPubs[0], acnt2.XPub)
201 func mockUTXO(controlProg *account.CtrlProgram, assetID *bc.AssetID) *account.UTXO {
202 utxo := &account.UTXO{}
203 utxo.OutputID = bc.Hash{V0: 1}
204 utxo.SourceID = bc.Hash{V0: 2}
205 utxo.AssetID = *assetID
206 utxo.Amount = 1000000000
208 utxo.ControlProgram = controlProg.ControlProgram
209 utxo.AccountID = controlProg.AccountID
210 utxo.Address = controlProg.Address
211 utxo.ControlProgramIndex = controlProg.KeyIndex
215 func mockTxData(utxos []*account.UTXO, testAccount *account.Account) (*txbuilder.Template, *types.TxData, error) {
216 tplBuilder := txbuilder.NewBuilder(time.Now())
218 for _, utxo := range utxos {
219 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo)
223 tplBuilder.AddInput(txInput, sigInst)
225 out := &types.TxOutput{}
226 if utxo.AssetID == *consensus.BTMAssetID {
227 out = types.NewTxOutput(utxo.AssetID, 100, utxo.ControlProgram)
229 out = types.NewTxOutput(utxo.AssetID, utxo.Amount, utxo.ControlProgram)
231 tplBuilder.AddOutput(out)
234 return tplBuilder.Build()
237 func mockWallet(walletDB dbm.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain) *Wallet {
243 rescanProgress: make(chan struct{}, 1),
245 wallet.status = StatusInfo{
246 OnChainAddresses: NewAddressSet(),
251 func mockSingleBlock(tx *types.Tx) *types.Block {
253 BlockHeader: types.BlockHeader{
256 Bits: 2305843009230471167,
258 Transactions: []*types.Tx{tx},