import (
"encoding/json"
+ "sync"
log "github.com/sirupsen/logrus"
"github.com/tendermint/tmlibs/db"
const (
//SINGLE single sign
SINGLE = 1
-
- // txChanSize is the size of channel listening to Txpool newTxCh.
- maxTxChanSize = 1000
)
var walletKey = []byte("walletInfo")
//Wallet is related to storing account unspent outputs
type Wallet struct {
DB db.DB
+ rw sync.RWMutex
status StatusInfo
AccountMgr *account.Manager
AssetReg *asset.Registry
Hsm *pseudohsm.HSM
chain *protocol.Chain
rescanCh chan struct{}
- txCh chan *types.Tx
}
//NewWallet return a new wallet instance
chain: chain,
Hsm: hsm,
rescanCh: make(chan struct{}, 1),
- txCh: make(chan *types.Tx, maxTxChanSize),
}
if err := w.loadWalletInfo(); err != nil {
}
go w.walletUpdater()
-
+ go w.delUnconfirmedTx()
return w, nil
}
// AttachBlock attach a new block
func (w *Wallet) AttachBlock(block *types.Block) error {
+ w.rw.Lock()
+ defer w.rw.Unlock()
+
if block.PreviousBlockHash != w.status.WorkHash {
log.Warn("wallet skip attachBlock due to status hash not equal to previous hash")
return nil
storeBatch := w.DB.NewBatch()
w.indexTransactions(storeBatch, block, txStatus)
- w.buildAccountUTXOs(storeBatch, block, txStatus)
+ w.attachUtxos(storeBatch, block, txStatus)
w.status.WorkHeight = block.Height
w.status.WorkHash = block.Hash()
// DetachBlock detach a block and rollback state
func (w *Wallet) DetachBlock(block *types.Block) error {
+ w.rw.Lock()
+ defer w.rw.Unlock()
+
blockHash := block.Hash()
txStatus, err := w.chain.GetTransactionStatus(&blockHash)
if err != nil {
}
storeBatch := w.DB.NewBatch()
- w.reverseAccountUTXOs(storeBatch, block, txStatus)
+ w.detachUtxos(storeBatch, block, txStatus)
w.deleteTransactions(storeBatch, w.status.BestHeight)
w.status.BestHeight = block.Height - 1
}
if err := w.DetachBlock(block); err != nil {
- log.WithField("err", err).Error("walletUpdater detachBlock")
+ log.WithField("err", err).Error("walletUpdater detachBlock stop")
return
}
}
block, _ := w.chain.GetBlockByHeight(w.status.WorkHeight + 1)
if block == nil {
- <-w.chain.BlockWaiter(w.status.WorkHeight + 1)
+ w.walletBlockWaiter()
continue
}
if err := w.AttachBlock(block); err != nil {
- log.WithField("err", err).Error("walletUpdater stop")
+ log.WithField("err", err).Error("walletUpdater AttachBlock stop")
return
}
-
- // rescan txpool transaction and delete unconfirmed transactions from database
- txIDs := w.RescanWalletTxPool()
- w.DeleteUnconfirmedTxs(txIDs)
}
}
func (w *Wallet) getRescanNotification() {
select {
case <-w.rescanCh:
- block, _ := w.chain.GetBlockByHeight(0)
- w.status.WorkHash = bc.Hash{}
- w.AttachBlock(block)
- case newTx := <-w.txCh:
- w.SaveUnconfirmedTx(newTx)
+ w.setRescanStatus()
default:
return
}
}
-func (w *Wallet) createProgram(account *account.Account, XPub *pseudohsm.XPub, index uint64) error {
- for i := uint64(0); i < index; i++ {
- if _, err := w.AccountMgr.CreateAddress(nil, account.ID, false); err != nil {
- return err
- }
+func (w *Wallet) setRescanStatus() {
+ block, _ := w.chain.GetBlockByHeight(0)
+ w.status.WorkHash = bc.Hash{}
+ w.AttachBlock(block)
+}
+
+func (w *Wallet) walletBlockWaiter() {
+ select {
+ case <-w.chain.BlockWaiter(w.status.WorkHeight + 1):
+ case <-w.rescanCh:
+ w.setRescanStatus()
}
- return nil
}
-//SetTxCh set wallet txCh
-func (w *Wallet) SetTxCh(txCh *types.Tx) {
- w.txCh <- txCh
+// GetWalletStatusInfo return current wallet StatusInfo
+func (w *Wallet) GetWalletStatusInfo() StatusInfo {
+ w.rw.RLock()
+ defer w.rw.RUnlock()
+
+ return w.status
}