chainntnfs/btcdnotify: populate full conf details for historical dispatch

This commit modifies the historical dispatch workflow slightly to also
obtain the full block in which the transaction was confirmed we we can
fully populate the full TxConfirmations struct which was recently added
as part of the confirmation subscription API.

With this change, confirmation triggers that a reached while the demon
is down, will now be deliver exactly as if the trigger was reached
while the daemon was up.
This commit is contained in:
Olaoluwa Osuntokun 2016-12-26 21:45:01 -06:00
parent 6e2fb4e60d
commit f8711659e6
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
1 changed files with 40 additions and 6 deletions

View File

@ -344,27 +344,61 @@ out:
}
// attemptHistoricalDispatch tries to use historical information to decide if a
// notificaiton ca be disptahced immediately, or is partially confirmed so it
// notification ca be dispatched immediately, or is partially confirmed so it
// can skip straight to the confirmations heap.
func (b *BtcdNotifier) attemptHistoricalDispatch(msg *confirmationsNotification,
currentHeight int32) bool {
chainntnfs.Log.Infof("Attempting to trigger dispatch for %v from "+
"historical chain", msg.txid)
// If the transaction already has some or all of the confirmations,
// then we may be able to
// dispatch it immediately.
// then we may be able to dispatch it immediately.
tx, err := b.chainConn.GetRawTransactionVerbose(msg.txid)
if err != nil {
if err != nil || tx == nil {
return false
}
// TODO(roasbeef): need to obtain proper hash+index info
// As we need to fully populate the returned TxConfirmation struct,
// grab the block in which the transaction was confirmed so we can
// locate its exact index within the block.
blockHash, err := wire.NewShaHashFromStr(tx.BlockHash)
if err != nil {
chainntnfs.Log.Errorf("unable to get block hash %v for "+
"historical dispatch: %v", tx.BlockHash, err)
return false
}
block, err := b.chainConn.GetBlock(blockHash)
if err != nil {
chainntnfs.Log.Errorf("unable to get block hash: %v", err)
return false
}
txHash, err := wire.NewShaHashFromStr(tx.Hash)
if err != nil {
chainntnfs.Log.Errorf("unable to convert to hash: %v", err)
return false
}
// If the block obtained, locate the transaction's index within the
// block so we can give the subscriber full confirmation details.
var txIndex uint32
for i, t := range block.Transactions {
h := t.TxSha()
if txHash.IsEqual(&h) {
txIndex = uint32(i)
}
}
confDetails := &chainntnfs.TxConfirmation{
BlockHash: blockHash,
BlockHeight: uint32(currentHeight) - uint32(tx.Confirmations),
TxIndex: txIndex,
}
// If the transaction has more that enough confirmations, then we can
// dispatch it immediately after obtaining for information w.r.t
// exaclty *when* if got all its confirmations.
// exactly *when* if got all its confirmations.
if uint32(tx.Confirmations) >= msg.numConfirmations {
msg.finConf <- confDetails
return true