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", nil)
60 controlProg, err := accountManager.CreateAddress(nil, testAccount.ID, false)
65 controlProg.KeyIndex = 1
67 utxo := mockUTXO(controlProg)
68 _, txData, err := mockTxData(utxo, testAccount)
73 tx := types.NewTx(*txData)
75 reg := asset.NewRegistry(testDB, chain)
77 w := mockWallet(testDB, accountManager, reg, chain)
79 block := mockSingleBlock(tx)
81 txStatus := bc.NewTransactionStatus()
82 store.SaveBlock(block, txStatus)
84 err = w.attachBlock(block)
89 want, err := w.GetTransactionsByTxID(tx.ID.String())
94 wants, err := w.GetTransactionsByTxID("")
100 func TestExportAndImportPrivKey(t *testing.T) {
101 dirPath, err := ioutil.TempDir(".", "")
105 defer os.RemoveAll(dirPath)
107 testDB := dbm.NewDB("testdb", "leveldb", "temp")
108 defer os.RemoveAll("temp")
110 store := leveldb.NewStore(testDB)
111 txPool := protocol.NewTxPool()
113 chain, err := protocol.NewChain(store, txPool)
118 acntManager := account.NewManager(testDB, chain)
119 reg := asset.NewRegistry(testDB, chain)
121 hsm, err := pseudohsm.New(dirPath)
127 xpub, err := hsm.XCreate("alias", pwd)
132 w, err := NewWallet(testDB, acntManager, reg, hsm, chain)
137 ctx := context.Background()
138 acnt1, err := w.AccountMgr.Create(ctx, []chainkd.XPub{xpub.XPub}, 1, "account-alias", nil)
143 priv, err := w.ExportAccountPrivKey(xpub.XPub, pwd)
145 wantPriv, err := hsm.LoadChainKDKey(xpub.XPub, pwd)
150 sha3pool.Sum256(hashed[:], wantPriv[:])
152 tmp := append(wantPriv[:], hashed[:4]...)
153 res := base58.Encode(tmp)
156 t.Fatalf("XPrivs should be identical.\nBefore: %v\n After: %v\n", *priv, res)
159 rawPriv, err := base58.Decode(*priv)
164 if len(rawPriv) != 68 {
165 t.Fatal("invalid private key hash length")
169 copy(xprv[:], rawPriv[:64])
171 _, err = w.ImportAccountPrivKey(xprv, xpub.Alias, pwd, 0, acnt1.Alias)
172 if err != pseudohsm.ErrDuplicateKeyAlias {
176 hsm.XDelete(xpub.XPub, pwd)
178 _, err = w.ImportAccountPrivKey(xprv, xpub.Alias, pwd, 0, acnt1.Alias)
179 if err != account.ErrDuplicateAlias {
183 accountInfo := struct {
184 AccountInfo string `json:"account_info"`
185 }{AccountInfo: acnt1.Alias}
187 w.AccountMgr.DeleteAccount(accountInfo)
189 acnt2, err := w.ImportAccountPrivKey(xprv, xpub.Alias, pwd, 0, acnt1.Alias)
194 if acnt2.XPub != acnt1.XPubs[0] {
195 t.Fatalf("XPubs should be identical.\nBefore: %v\n After: %v\n", acnt1.XPubs[0], acnt2.XPub)
199 func mockUTXO(controlProg *account.CtrlProgram) *account.UTXO {
200 utxo := &account.UTXO{}
201 utxo.OutputID = bc.Hash{V0: 1}
202 utxo.SourceID = bc.Hash{V0: 2}
203 utxo.AssetID = *consensus.BTMAssetID
204 utxo.Amount = 1000000000
206 utxo.ControlProgram = controlProg.ControlProgram
207 utxo.AccountID = controlProg.AccountID
208 utxo.Address = controlProg.Address
209 utxo.ControlProgramIndex = controlProg.KeyIndex
213 func mockTxData(utxo *account.UTXO, testAccount *account.Account) (*txbuilder.Template, *types.TxData, error) {
214 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo)
219 b := txbuilder.NewBuilder(time.Now())
220 b.AddInput(txInput, sigInst)
221 out := types.NewTxOutput(*consensus.BTMAssetID, 100, utxo.ControlProgram)
226 func mockWallet(walletDB dbm.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain) *Wallet {
232 rescanProgress: make(chan struct{}, 1),
236 func mockSingleBlock(tx *types.Tx) *types.Block {
238 BlockHeader: types.BlockHeader{
241 Bits: 2305843009230471167,
243 Transactions: []*types.Tx{tx},