Skip to content

Commit 0be25db

Browse files
committed
Log transaction changes for non-initial rescans
For all rescans except for the initial one when a wallet is first synced (during reseed, or after process restart), log those transactions that are changed status from unmined to mined in a block, and any newly-observed transaction that is added to the wallet. These later rescans are typically done to fix a problem syncing blocks and/or transactions, and these transaction hashes should be useful information to discover what previously went wrong.
1 parent a38abe2 commit 0be25db

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

wallet/rescan.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,29 @@ func (f *RescanFilter) RemoveUnspentOutPoint(op *wire.OutPoint) {
148148
delete(f.unspent, *op)
149149
}
150150

151+
// logRescannedTx logs a newly-observed transaction that was added by the
152+
// rescan or a transaction that was changed from unmined to mined. It should
153+
// only be called if the wallet field logRescannedTransactions is true, which
154+
// will be set after the very first rescan during the process lifetime.
155+
func (w *Wallet) logRescannedTx(txmgrNs walletdb.ReadBucket, height int32, tx *wire.MsgTx) {
156+
txHash := tx.TxHash()
157+
haveMined, haveUnmined := w.txStore.ExistsTxMinedOrUnmined(txmgrNs, &txHash)
158+
if haveUnmined {
159+
log.Infof("Rescan of block %d discovered previously unmined "+
160+
"transaction %v", height, &txHash)
161+
} else if !haveMined {
162+
log.Infof("Rescan of block %d discovered new transaction %v",
163+
height, &txHash)
164+
}
165+
}
166+
151167
// saveRescanned records transactions from a rescanned block. This
152168
// does not update the network backend with data to watch for future
153169
// relevant transactions as the rescanner is assumed to handle this
154170
// task.
155-
func (w *Wallet) saveRescanned(ctx context.Context, hash *chainhash.Hash, txs []*wire.MsgTx) error {
171+
func (w *Wallet) saveRescanned(ctx context.Context, hash *chainhash.Hash,
172+
txs []*wire.MsgTx, logTxs bool) error {
173+
156174
const op errors.Op = "wallet.saveRescanned"
157175

158176
defer w.lockedOutpointMu.Unlock()
@@ -170,6 +188,10 @@ func (w *Wallet) saveRescanned(ctx context.Context, hash *chainhash.Hash, txs []
170188
}
171189

172190
for _, tx := range txs {
191+
if logTxs {
192+
w.logRescannedTx(txmgrNs, blockMeta.Height, tx)
193+
}
194+
173195
rec, err := udb.NewTxRecordFromMsgTx(tx, time.Now())
174196
if err != nil {
175197
return err
@@ -194,6 +216,11 @@ func (w *Wallet) saveRescanned(ctx context.Context, hash *chainhash.Hash, txs []
194216
func (w *Wallet) rescan(ctx context.Context, n NetworkBackend,
195217
startHash *chainhash.Hash, height int32, p chan<- RescanProgress) error {
196218

219+
w.logRescannedTransactionsMu.Lock()
220+
logTxs := w.logRescannedTransactions
221+
w.logRescannedTransactions = true
222+
w.logRescannedTransactionsMu.Unlock()
223+
197224
blockHashStorage := make([]chainhash.Hash, maxBlocksPerRescan)
198225
rescanFrom := *startHash
199226
inclusive := true
@@ -230,7 +257,7 @@ func (w *Wallet) rescan(ctx context.Context, n NetworkBackend,
230257
}
231258
log.Infof("Rescanning block range [%v, %v]...", height, through)
232259
saveRescanned := func(block *chainhash.Hash, txs []*wire.MsgTx) error {
233-
return w.saveRescanned(ctx, block, txs)
260+
return w.saveRescanned(ctx, block, txs, logTxs)
234261
}
235262
err = n.Rescan(ctx, rescanBlocks, saveRescanned)
236263
if err != nil {

wallet/udb/txquery.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,17 +276,19 @@ func (s *Store) Tx(ns walletdb.ReadBucket, txHash *chainhash.Hash) (*wire.MsgTx,
276276

277277
// ExistsTx checks to see if a transaction exists in the database.
278278
func (s *Store) ExistsTx(ns walletdb.ReadBucket, txHash *chainhash.Hash) bool {
279-
// First, check whether there exists an unmined transaction with this
280-
// hash. Use it if found.
279+
mined, unmined := s.ExistsTxMinedOrUnmined(ns, txHash)
280+
return mined || unmined
281+
}
282+
283+
// ExistsTxMinedOrUnmined checks if a transaction is recorded as a mined or
284+
// unmined transaction.
285+
func (s *Store) ExistsTxMinedOrUnmined(ns walletdb.ReadBucket, txHash *chainhash.Hash) (mined, unmined bool) {
281286
v := existsRawUnmined(ns, txHash[:])
282287
if v != nil {
283-
return true
288+
return false, true
284289
}
285-
286-
// Otherwise, if there exists a mined transaction with this matching
287-
// hash, skip over to the newest and begin fetching the msgTx.
288290
_, v = latestTxRecord(ns, txHash[:])
289-
return v != nil
291+
return v != nil, false
290292
}
291293

292294
// ExistsUTXO checks to see if op refers to an unspent transaction output or a

wallet/wallet.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,14 @@ type Wallet struct {
141141
lockedOutpoints map[outpoint]struct{}
142142
lockedOutpointMu sync.Mutex
143143

144-
relayFee dcrutil.Amount
145-
relayFeeMu sync.Mutex
146-
allowHighFees bool
147-
disableCoinTypeUpgrades bool
148-
recentlyPublished map[chainhash.Hash]struct{}
149-
recentlyPublishedMu sync.Mutex
144+
relayFee dcrutil.Amount
145+
relayFeeMu sync.Mutex
146+
allowHighFees bool
147+
disableCoinTypeUpgrades bool
148+
recentlyPublished map[chainhash.Hash]struct{}
149+
recentlyPublishedMu sync.Mutex
150+
logRescannedTransactions bool
151+
logRescannedTransactionsMu sync.Mutex
150152

151153
// Internal address handling.
152154
ticketAddress stdaddr.StakeAddress

0 commit comments

Comments
 (0)