From de0adc4d52718c4ec952c54a318558eee86161d3 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Thu, 6 Dec 2018 21:13:32 -0800 Subject: [PATCH] chainntnfs/txnotifier: add ConfRequest and SpendRequest structs These structs allow us to request notifications for either txids/outpoints or output scripts. We'll be using these in later commits to index confirmation and spend requests within the TxNotifier. --- chainntnfs/txnotifier.go | 99 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/chainntnfs/txnotifier.go b/chainntnfs/txnotifier.go index 4e670e2e..e0cfe1c5 100644 --- a/chainntnfs/txnotifier.go +++ b/chainntnfs/txnotifier.go @@ -23,6 +23,20 @@ const ( MaxNumConfs = ReorgSafetyLimit ) +var ( + // ZeroHash is the value that should be used as the txid when + // registering for the confirmation of a script on-chain. This allows + // the notifier to match _and_ dispatch upon the inclusion of the script + // on-chain, rather than the txid. + ZeroHash chainhash.Hash + + // ZeroOutPoint is the value that should be used as the outpoint when + // registering for the spend of a script on-chain. This allows the + // notifier to match _and_ dispatch upon detecting the spend of the + // script on-chain, rather than the outpoint. + ZeroOutPoint wire.OutPoint +) + var ( // ErrTxNotifierExiting is an error returned when attempting to interact // with the TxNotifier but it been shut down. @@ -108,6 +122,49 @@ func newSpendNtfnSet() *spendNtfnSet { } } +// ConfRequest encapsulates a request for a confirmation notification of either +// a txid or output script. +type ConfRequest struct { + // TxID is the hash of the transaction for which confirmation + // notifications are requested. If set to a zero hash, then a + // confirmation notification will be dispatched upon inclusion of the + // _script_, rather than the txid. + TxID chainhash.Hash + + // PkScript is the public key script of an outpoint created in this + // transaction. + PkScript txscript.PkScript +} + +// NewConfRequest creates a request for a confirmation notification of either a +// txid or output script. A nil txid or an allocated ZeroHash can be used to +// dispatch the confirmation notification on the script. +func NewConfRequest(txid *chainhash.Hash, pkScript []byte) (ConfRequest, error) { + var r ConfRequest + outputScript, err := txscript.ParsePkScript(pkScript) + if err != nil { + return r, err + } + + // We'll only set a txid for which we'll dispatch a confirmation + // notification on this request if one was provided. Otherwise, we'll + // default to dispatching on the confirmation of the script instead. + if txid != nil { + r.TxID = *txid + } + r.PkScript = outputScript + + return r, nil +} + +// String returns the string representation of the ConfRequest. +func (r ConfRequest) String() string { + if r.TxID != ZeroHash { + return fmt.Sprintf("txid=%v", r.TxID) + } + return fmt.Sprintf("script=%v", r.PkScript) +} + // ConfNtfn represents a notifier client's request to receive a notification // once the target transaction gets sufficient confirmations. The client is // asynchronously notified via the ConfirmationEvent channels. @@ -166,6 +223,48 @@ type HistoricalConfDispatch struct { EndHeight uint32 } +// SpendRequest encapsulates a request for a spend notification of either an +// outpoint or output script. +type SpendRequest struct { + // OutPoint is the outpoint for which a client has requested a spend + // notification for. If set to a zero outpoint, then a spend + // notification will be dispatched upon detecting the spend of the + // _script_, rather than the outpoint. + OutPoint wire.OutPoint + + // PkScript is the script of the outpoint. + PkScript txscript.PkScript +} + +// NewSpendRequest creates a request for a spend notification of either an +// outpoint or output script. A nil outpoint or an allocated ZeroOutPoint can be +// used to dispatch the confirmation notification on the script. +func NewSpendRequest(op *wire.OutPoint, pkScript []byte) (SpendRequest, error) { + var r SpendRequest + outputScript, err := txscript.ParsePkScript(pkScript) + if err != nil { + return r, err + } + + // We'll only set an outpoint for which we'll dispatch a spend + // notification on this request if one was provided. Otherwise, we'll + // default to dispatching on the spend of the script instead. + if op != nil { + r.OutPoint = *op + } + r.PkScript = outputScript + + return r, nil +} + +// String returns the string representation of the SpendRequest. +func (r SpendRequest) String() string { + if r.OutPoint != ZeroOutPoint { + return fmt.Sprintf("outpoint=%v", r.OutPoint) + } + return fmt.Sprintf("script=%v", r.PkScript) +} + // SpendNtfn represents a client's request to receive a notification once an // outpoint has been spent on-chain. The client is asynchronously notified via // the SpendEvent channels.