10 "github.com/tendermint/go-wire/data/base58"
11 dbm "github.com/tendermint/tmlibs/db"
13 "github.com/bytom/blockchain/account"
14 "github.com/bytom/blockchain/asset"
15 "github.com/bytom/blockchain/pseudohsm"
16 "github.com/bytom/blockchain/txbuilder"
17 "github.com/bytom/blockchain/txdb"
18 cfg "github.com/bytom/config"
19 "github.com/bytom/consensus"
20 "github.com/bytom/crypto/ed25519/chainkd"
21 "github.com/bytom/crypto/sha3pool"
22 "github.com/bytom/protocol"
23 "github.com/bytom/protocol/bc"
24 "github.com/bytom/protocol/bc/legacy"
27 func TestWalletUpdate(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 store := txdb.NewStore(testDB)
38 txPool := protocol.NewTxPool()
40 chain, err := protocol.NewChain(bc.Hash{}, store, txPool)
45 accountManager := account.NewManager(testDB, chain)
46 hsm, err := pseudohsm.New(dirPath)
51 xpub1, err := hsm.XCreate("test_pub1", "password")
56 testAccount, err := accountManager.Create(nil, []chainkd.XPub{xpub1.XPub}, 1, "testAccount", nil)
61 controlProg, err := accountManager.CreateAddress(nil, testAccount.ID, false)
66 controlProg.KeyIndex = 1
68 utxo := mockUTXO(controlProg)
69 _, txData, err := mockTxData(utxo, testAccount)
74 tx := legacy.NewTx(*txData)
76 reg := asset.NewRegistry(testDB, chain)
78 w := mockWallet(testDB, accountManager, reg, chain)
80 block := mockSingleBlock(tx)
82 err = w.attachBlock(block)
87 want, err := w.GetTransactionsByTxID(tx.ID.String())
92 wants, err := w.GetTransactionsByTxID("")
98 func TestExportAndImportPrivKey(t *testing.T) {
99 dirPath, err := ioutil.TempDir(".", "")
103 defer os.RemoveAll(dirPath)
105 testDB := dbm.NewDB("testdb", "leveldb", "temp")
106 defer os.RemoveAll("temp")
108 store := txdb.NewStore(testDB)
109 txPool := protocol.NewTxPool()
111 chain, err := protocol.NewChain(bc.Hash{}, store, txPool)
116 genesisBlock := cfg.GenerateGenesisBlock()
118 chain.SaveBlock(genesisBlock)
119 chain.ConnectBlock(genesisBlock)
121 acntManager := account.NewManager(testDB, chain)
122 reg := asset.NewRegistry(testDB, chain)
124 hsm, err := pseudohsm.New(dirPath)
130 xpub, err := hsm.XCreate("alias", pwd)
135 w, err := NewWallet(testDB, acntManager, reg, chain, nil)
140 ctx := context.Background()
141 acnt1, err := w.AccountMgr.Create(ctx, []chainkd.XPub{xpub.XPub}, 1, "account-alias", nil)
146 priv, err := w.ExportAccountPrivKey(hsm, xpub.XPub, pwd)
148 wantPriv, err := hsm.LoadChainKDKey(xpub.XPub, pwd)
153 sha3pool.Sum256(hashed[:], wantPriv[:])
155 tmp := append(wantPriv[:], hashed[:4]...)
156 res := base58.Encode(tmp)
159 t.Fatalf("XPrivs should be identical.\nBefore: %v\n After: %v\n", *priv, res)
162 rawPriv, err := base58.Decode(*priv)
167 if len(rawPriv) != 68 {
168 t.Fatal("invalid private key hash length")
172 copy(xprv[:], rawPriv[:64])
174 _, err = w.ImportAccountPrivKey(hsm, xprv, xpub.Alias, pwd, 0, acnt1.Alias)
175 if err != pseudohsm.ErrDuplicateKeyAlias {
179 hsm.XDelete(xpub.XPub, pwd)
181 _, err = w.ImportAccountPrivKey(hsm, xprv, xpub.Alias, pwd, 0, acnt1.Alias)
182 if err != account.ErrDuplicateAlias {
186 accountInfo := struct {
187 AccountInfo string `json:"account_info"`
188 }{AccountInfo: acnt1.Alias}
190 w.AccountMgr.DeleteAccount(accountInfo)
192 acnt2, err := w.ImportAccountPrivKey(hsm, xprv, xpub.Alias, pwd, 0, acnt1.Alias)
197 if acnt2.XPub != acnt1.XPubs[0] {
198 t.Fatalf("XPubs should be identical.\nBefore: %v\n After: %v\n", acnt1.XPubs[0], acnt2.XPub)
202 func mockUTXO(controlProg *account.CtrlProgram) *account.UTXO {
203 utxo := &account.UTXO{}
204 utxo.OutputID = bc.Hash{V0: 1}
205 utxo.SourceID = bc.Hash{V0: 2}
206 utxo.AssetID = *consensus.BTMAssetID
207 utxo.Amount = 1000000000
209 utxo.ControlProgram = controlProg.ControlProgram
210 utxo.AccountID = controlProg.AccountID
211 utxo.Address = controlProg.Address
212 utxo.ControlProgramIndex = controlProg.KeyIndex
216 func mockTxData(utxo *account.UTXO, testAccount *account.Account) (*txbuilder.Template, *legacy.TxData, error) {
217 txInput, sigInst, err := account.UtxoToInputs(testAccount.Signer, utxo, nil)
222 b := txbuilder.NewBuilder(time.Now())
223 b.AddInput(txInput, sigInst)
224 out := legacy.NewTxOutput(*consensus.BTMAssetID, 100, utxo.ControlProgram, nil)
229 func mockWallet(walletDB dbm.DB, account *account.Manager, asset *asset.Registry, chain *protocol.Chain) *Wallet {
235 rescanProgress: make(chan struct{}, 1),
239 func mockSingleBlock(tx *legacy.Tx) *legacy.Block {
240 return &legacy.Block{
241 BlockHeader: legacy.BlockHeader{
244 Bits: 2305843009230471167,
246 Transactions: []*legacy.Tx{tx},