Sync wallet files to disk as needed, instead of waiting for a timer.
While fixing this code, the dirty flag was also cleared so that unneeded syncs wouldn't be needed later. The dirty flag set and sync was also added for the 'getnewaddress' handler, as it was previously missing.
This commit is contained in:
parent
a5c7079fdf
commit
2782b7815e
3 changed files with 39 additions and 54 deletions
23
cmd.go
23
cmd.go
|
@ -107,17 +107,15 @@ func (s *BtcWalletStore) Rollback(height int64, hash *btcwire.ShaHash) {
|
|||
func (w *BtcWallet) Rollback(height int64, hash *btcwire.ShaHash) {
|
||||
w.UtxoStore.Lock()
|
||||
w.UtxoStore.dirty = w.UtxoStore.dirty || w.UtxoStore.s.Rollback(height, hash)
|
||||
if w.UtxoStore.dirty {
|
||||
AddDirtyAccount(w)
|
||||
}
|
||||
w.UtxoStore.Unlock()
|
||||
|
||||
w.TxStore.Lock()
|
||||
w.TxStore.dirty = w.TxStore.dirty || w.TxStore.s.Rollback(height, hash)
|
||||
if w.TxStore.dirty {
|
||||
AddDirtyAccount(w)
|
||||
}
|
||||
w.TxStore.Unlock()
|
||||
|
||||
if err := w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// walletdir returns the directory path which holds the wallet, utxo,
|
||||
|
@ -455,8 +453,11 @@ func (w *BtcWallet) newBlockTxHandler(result interface{}, e *btcjson.Error) bool
|
|||
txs := w.TxStore.s
|
||||
w.TxStore.s = append(txs, t)
|
||||
w.TxStore.dirty = true
|
||||
AddDirtyAccount(w)
|
||||
w.TxStore.Unlock()
|
||||
|
||||
if err = w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Do not add output to utxo store if spent.
|
||||
|
@ -476,8 +477,11 @@ func (w *BtcWallet) newBlockTxHandler(result interface{}, e *btcjson.Error) bool
|
|||
w.UtxoStore.Lock()
|
||||
w.UtxoStore.s = append(w.UtxoStore.s, u)
|
||||
w.UtxoStore.dirty = true
|
||||
AddDirtyAccount(w)
|
||||
w.UtxoStore.Unlock()
|
||||
if err = w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
|
||||
confirmed := w.CalculateBalance(6)
|
||||
unconfirmed := w.CalculateBalance(0) - confirmed
|
||||
NotifyWalletBalance(frontendNotificationMaster, w.name, confirmed)
|
||||
|
@ -538,9 +542,6 @@ func main() {
|
|||
// Begin generating new IDs for JSON calls.
|
||||
go JSONIDGenerator(NewJSONID)
|
||||
|
||||
// Begin wallet to disk syncer.
|
||||
go DirtyAccountUpdater()
|
||||
|
||||
for {
|
||||
replies := make(chan error)
|
||||
done := make(chan int)
|
||||
|
|
16
cmdmgr.go
16
cmdmgr.go
|
@ -334,6 +334,10 @@ func GetNewAddress(reply chan []byte, msg *btcjson.Message) {
|
|||
ReplyError(reply, msg.Id, &e)
|
||||
return
|
||||
}
|
||||
w.dirty = true
|
||||
if err = w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
w.ReqNewTxsForAddress(addr)
|
||||
ReplySuccess(reply, msg.Id, addr)
|
||||
} else {
|
||||
|
@ -493,8 +497,10 @@ func SendFrom(reply chan []byte, msg *btcjson.Message) {
|
|||
modified := w.UtxoStore.s.Remove(inputs)
|
||||
if modified {
|
||||
w.UtxoStore.dirty = true
|
||||
AddDirtyAccount(w)
|
||||
w.UtxoStore.Unlock()
|
||||
if err := w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
|
||||
// Notify all frontends of new account balances.
|
||||
confirmed := w.CalculateBalance(6)
|
||||
|
@ -638,8 +644,10 @@ func SendMany(reply chan []byte, msg *btcjson.Message) {
|
|||
modified := w.UtxoStore.s.Remove(inputs)
|
||||
if modified {
|
||||
w.UtxoStore.dirty = true
|
||||
AddDirtyAccount(w)
|
||||
w.UtxoStore.Unlock()
|
||||
if err := w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
|
||||
// Notify all frontends of new account balances.
|
||||
confirmed := w.CalculateBalance(6)
|
||||
|
@ -778,7 +786,9 @@ func CreateEncryptedWallet(reply chan []byte, msg *btcjson.Message) {
|
|||
bw.Track()
|
||||
|
||||
wallets.m[wname] = bw
|
||||
AddDirtyAccount(bw)
|
||||
if err := bw.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
ReplySuccess(reply, msg.Id, nil)
|
||||
}
|
||||
|
||||
|
|
54
disksync.go
54
disksync.go
|
@ -23,43 +23,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var dirtyAccountSet = make(map[*BtcWallet]bool)
|
||||
var addDirtyAccount = make(chan *BtcWallet)
|
||||
|
||||
// DirtyAccountUpdater is responsible for listening for listens for new
|
||||
// dirty wallets (changed in memory with updaets not yet saved to disk)
|
||||
// to add to dirtyAccountSet. This is designed to run as a single goroutine.
|
||||
func DirtyAccountUpdater() {
|
||||
timer := time.Tick(time.Minute)
|
||||
for {
|
||||
select {
|
||||
case w := <-addDirtyAccount:
|
||||
dirtyAccountSet[w] = true
|
||||
|
||||
case <-timer:
|
||||
for w := range dirtyAccountSet {
|
||||
if err := w.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet '%v': %v", w.name, err)
|
||||
} else {
|
||||
delete(dirtyAccountSet, w)
|
||||
log.Infof("removed dirty wallet '%v'", w.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddDirtyAccount adds w to a set of items to be synced to disk. The
|
||||
// dirty flag must still be set on the various dirty elements of the
|
||||
// account (wallet, transactions, and/or utxos) or nothing will be
|
||||
// written to disk during the next scheduled sync.
|
||||
func AddDirtyAccount(w *BtcWallet) {
|
||||
addDirtyAccount <- w
|
||||
}
|
||||
|
||||
// writeDirtyToDisk checks for the dirty flag on an account's wallet,
|
||||
// txstore, and utxostore, writing them to disk if any are dirty.
|
||||
func (w *BtcWallet) writeDirtyToDisk() error {
|
||||
fmt.Println("entered")
|
||||
|
||||
// Temporary files append the current time to the normal file name.
|
||||
// In caes of failure, the most recent temporary file can be inspected
|
||||
// for validity, and moved to replace the main file.
|
||||
|
@ -72,8 +40,8 @@ func (w *BtcWallet) writeDirtyToDisk() error {
|
|||
|
||||
// Wallet
|
||||
if w.dirty {
|
||||
w.mtx.RLock()
|
||||
defer w.mtx.RUnlock()
|
||||
w.mtx.Lock()
|
||||
defer w.mtx.Unlock()
|
||||
tmpfilepath := wfilepath + "-" + timeStr
|
||||
tmpfile, err := os.Create(tmpfilepath)
|
||||
if err != nil {
|
||||
|
@ -88,12 +56,14 @@ func (w *BtcWallet) writeDirtyToDisk() error {
|
|||
if err = os.Rename(tmpfilepath, wfilepath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.dirty = false
|
||||
}
|
||||
|
||||
// Transactions
|
||||
if w.TxStore.dirty {
|
||||
w.TxStore.RLock()
|
||||
defer w.TxStore.RUnlock()
|
||||
w.TxStore.Lock()
|
||||
defer w.TxStore.Unlock()
|
||||
tmpfilepath := txfilepath + "-" + timeStr
|
||||
tmpfile, err := os.Create(tmpfilepath)
|
||||
if err != nil {
|
||||
|
@ -108,12 +78,14 @@ func (w *BtcWallet) writeDirtyToDisk() error {
|
|||
if err = os.Rename(tmpfilepath, txfilepath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.TxStore.dirty = false
|
||||
}
|
||||
|
||||
// UTXOs
|
||||
if w.UtxoStore.dirty {
|
||||
w.UtxoStore.RLock()
|
||||
defer w.UtxoStore.RUnlock()
|
||||
w.UtxoStore.Lock()
|
||||
defer w.UtxoStore.Unlock()
|
||||
tmpfilepath := utxofilepath + "-" + timeStr
|
||||
tmpfile, err := os.Create(tmpfilepath)
|
||||
if err != nil {
|
||||
|
@ -128,6 +100,8 @@ func (w *BtcWallet) writeDirtyToDisk() error {
|
|||
if err = os.Rename(tmpfilepath, utxofilepath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.UtxoStore.dirty = false
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue