Merge pull request #2868 from cfromknecht/commit-bitcoind-spendhints
chainntnfs: Always commit bitcoind spendhints
This commit is contained in:
commit
fa73a60167
@ -25,13 +25,6 @@ const (
|
|||||||
notifierType = "bitcoind"
|
notifierType = "bitcoind"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrTransactionNotFound is an error returned when we attempt to find a
|
|
||||||
// transaction by manually scanning the chain within a specific range
|
|
||||||
// but it is not found.
|
|
||||||
ErrTransactionNotFound = errors.New("transaction not found within range")
|
|
||||||
)
|
|
||||||
|
|
||||||
// chainUpdate encapsulates an update to the current main chain. This struct is
|
// chainUpdate encapsulates an update to the current main chain. This struct is
|
||||||
// used as an element within an unbounded queue in order to avoid blocking the
|
// used as an element within an unbounded queue in order to avoid blocking the
|
||||||
// main rpc dispatch rule.
|
// main rpc dispatch rule.
|
||||||
@ -235,7 +228,13 @@ out:
|
|||||||
msg.StartHeight, msg.EndHeight,
|
msg.StartHeight, msg.EndHeight,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chainntnfs.Log.Error(err)
|
chainntnfs.Log.Errorf("Rescan to "+
|
||||||
|
"determine the conf "+
|
||||||
|
"details of %v within "+
|
||||||
|
"range %d-%d failed: %v",
|
||||||
|
msg.ConfRequest,
|
||||||
|
msg.StartHeight,
|
||||||
|
msg.EndHeight, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +249,10 @@ out:
|
|||||||
msg.ConfRequest, confDetails,
|
msg.ConfRequest, confDetails,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chainntnfs.Log.Error(err)
|
chainntnfs.Log.Errorf("Unable "+
|
||||||
|
"to update conf "+
|
||||||
|
"details of %v: %v",
|
||||||
|
msg.ConfRequest, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -264,7 +266,10 @@ out:
|
|||||||
go func() {
|
go func() {
|
||||||
defer b.wg.Done()
|
defer b.wg.Done()
|
||||||
|
|
||||||
err := b.dispatchSpendDetailsManually(msg)
|
spendDetails, err := b.historicalSpendDetails(
|
||||||
|
msg.SpendRequest,
|
||||||
|
msg.StartHeight, msg.EndHeight,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
chainntnfs.Log.Errorf("Rescan to "+
|
chainntnfs.Log.Errorf("Rescan to "+
|
||||||
"determine the spend "+
|
"determine the spend "+
|
||||||
@ -273,6 +278,24 @@ out:
|
|||||||
msg.SpendRequest,
|
msg.SpendRequest,
|
||||||
msg.StartHeight,
|
msg.StartHeight,
|
||||||
msg.EndHeight, err)
|
msg.EndHeight, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the historical dispatch finished
|
||||||
|
// without error, we will invoke
|
||||||
|
// UpdateSpendDetails even if none were
|
||||||
|
// found. This allows the notifier to
|
||||||
|
// begin safely updating the height hint
|
||||||
|
// cache at tip, since any pending
|
||||||
|
// rescans have now completed.
|
||||||
|
err = b.txNotifier.UpdateSpendDetails(
|
||||||
|
msg.SpendRequest, spendDetails,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
chainntnfs.Log.Errorf("Unable "+
|
||||||
|
"to update spend "+
|
||||||
|
"details of %v: %v",
|
||||||
|
msg.SpendRequest, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -823,16 +846,13 @@ func (b *BitcoindNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
|
|||||||
return ntfn.Event, nil
|
return ntfn.Event, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// disaptchSpendDetailsManually attempts to manually scan the chain within the
|
// historicalSpendDetails attempts to manually scan the chain within the given
|
||||||
// given height range for a transaction that spends the given outpoint/output
|
// height range for a transaction that spends the given outpoint/output script.
|
||||||
// script. If one is found, it's spending details are sent to the TxNotifier,
|
// If one is found, the spend details are assembled and returned to the caller.
|
||||||
// which will then dispatch the notification to all of its clients.
|
// If the spend is not found, a nil spend detail will be returned.
|
||||||
func (b *BitcoindNotifier) dispatchSpendDetailsManually(
|
func (b *BitcoindNotifier) historicalSpendDetails(
|
||||||
historicalDispatchDetails *chainntnfs.HistoricalSpendDispatch) error {
|
spendRequest chainntnfs.SpendRequest, startHeight, endHeight uint32) (
|
||||||
|
*chainntnfs.SpendDetail, error) {
|
||||||
spendRequest := historicalDispatchDetails.SpendRequest
|
|
||||||
startHeight := historicalDispatchDetails.StartHeight
|
|
||||||
endHeight := historicalDispatchDetails.EndHeight
|
|
||||||
|
|
||||||
// Begin scanning blocks at every height to determine if the outpoint
|
// Begin scanning blocks at every height to determine if the outpoint
|
||||||
// was spent.
|
// was spent.
|
||||||
@ -841,20 +861,20 @@ func (b *BitcoindNotifier) dispatchSpendDetailsManually(
|
|||||||
// processing the next height.
|
// processing the next height.
|
||||||
select {
|
select {
|
||||||
case <-b.quit:
|
case <-b.quit:
|
||||||
return chainntnfs.ErrChainNotifierShuttingDown
|
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we'll fetch the block for the current height.
|
// First, we'll fetch the block for the current height.
|
||||||
blockHash, err := b.chainConn.GetBlockHash(int64(height))
|
blockHash, err := b.chainConn.GetBlockHash(int64(height))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve hash for block "+
|
return nil, fmt.Errorf("unable to retrieve hash for "+
|
||||||
"with height %d: %v", height, err)
|
"block with height %d: %v", height, err)
|
||||||
}
|
}
|
||||||
block, err := b.chainConn.GetBlock(blockHash)
|
block, err := b.chainConn.GetBlock(blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve block with hash "+
|
return nil, fmt.Errorf("unable to retrieve block "+
|
||||||
"%v: %v", blockHash, err)
|
"with hash %v: %v", blockHash, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then, we'll manually go over every input in every transaction
|
// Then, we'll manually go over every input in every transaction
|
||||||
@ -863,29 +883,24 @@ func (b *BitcoindNotifier) dispatchSpendDetailsManually(
|
|||||||
for _, tx := range block.Transactions {
|
for _, tx := range block.Transactions {
|
||||||
matches, inputIdx, err := spendRequest.MatchesTx(tx)
|
matches, inputIdx, err := spendRequest.MatchesTx(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !matches {
|
if !matches {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
txHash := tx.TxHash()
|
txHash := tx.TxHash()
|
||||||
details := &chainntnfs.SpendDetail{
|
return &chainntnfs.SpendDetail{
|
||||||
SpentOutPoint: &tx.TxIn[inputIdx].PreviousOutPoint,
|
SpentOutPoint: &tx.TxIn[inputIdx].PreviousOutPoint,
|
||||||
SpenderTxHash: &txHash,
|
SpenderTxHash: &txHash,
|
||||||
SpendingTx: tx,
|
SpendingTx: tx,
|
||||||
SpenderInputIndex: inputIdx,
|
SpenderInputIndex: inputIdx,
|
||||||
SpendingHeight: int32(height),
|
SpendingHeight: int32(height),
|
||||||
}
|
}, nil
|
||||||
|
|
||||||
return b.txNotifier.UpdateSpendDetails(
|
|
||||||
historicalDispatchDetails.SpendRequest,
|
|
||||||
details,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrTransactionNotFound
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterConfirmationsNtfn registers an intent to be notified once the target
|
// RegisterConfirmationsNtfn registers an intent to be notified once the target
|
||||||
|
Loading…
Reference in New Issue
Block a user