@@ -244,20 +244,25 @@ type ConfNtfn struct {
244244 // notification is to be sent.
245245 NumConfirmations uint32
246246
247- // Event contains references to the channels that the notifications are to
248- // be sent over.
247+ // Event contains references to the channels that the notifications are
248+ // to be sent over.
249249 Event * ConfirmationEvent
250250
251251 // HeightHint is the minimum height in the chain that we expect to find
252252 // this txid.
253253 HeightHint uint32
254254
255- // dispatched is false if the confirmed notification has not been sent yet.
255+ // dispatched is false if the confirmed notification has not been sent
256+ // yet.
256257 dispatched bool
257258
258259 // includeBlock is true if the dispatched notification should also have
259260 // the block included with it.
260261 includeBlock bool
262+
263+ // numConfsLeft is the number of confirmations left to be sent to the
264+ // subscriber.
265+ numConfsLeft uint32
261266}
262267
263268// HistoricalConfDispatch parametrizes a manual rescan for a particular
@@ -589,6 +594,7 @@ func (n *TxNotifier) newConfNtfn(txid *chainhash.Hash,
589594 }),
590595 HeightHint : heightHint ,
591596 includeBlock : opts .includeBlock ,
597+ numConfsLeft : numConfs ,
592598 }, nil
593599}
594600
@@ -664,8 +670,8 @@ func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
664670 // already been found, we'll attempt to deliver them immediately
665671 // to this client.
666672 Log .Debugf ("Attempting to dispatch confirmation for %v on " +
667- "registration since rescan has finished" ,
668- ntfn .ConfRequest )
673+ "registration since rescan has finished, conf_id=%v " ,
674+ ntfn .ConfRequest , ntfn . ConfID )
669675
670676 // The default notification we assigned above includes the
671677 // block along with the rest of the details. However not all
@@ -679,9 +685,13 @@ func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
679685 confDetails = & confDetailsCopy
680686 }
681687
682- err := n .dispatchConfDetails (ntfn , confDetails )
683- if err != nil {
684- return nil , err
688+ // Deliver the details to the whole conf set where this ntfn
689+ // lives in.
690+ for _ , subscriber := range confSet .ntfns {
691+ err := n .dispatchConfDetails (subscriber , confDetails )
692+ if err != nil {
693+ return nil , err
694+ }
685695 }
686696
687697 return & ConfRegistration {
@@ -912,10 +922,16 @@ func (n *TxNotifier) dispatchConfDetails(
912922 // If there are no conf details to dispatch or if the notification has
913923 // already been dispatched, then we can skip dispatching to this
914924 // client.
915- if details == nil || ntfn .dispatched {
916- Log .Debugf ("Skipping dispatch of conf details(%v) for " +
917- "request %v, dispatched=%v" , details , ntfn .ConfRequest ,
918- ntfn .dispatched )
925+ if details == nil {
926+ Log .Debugf ("Skipped dispatching nil conf details for request " +
927+ "%v, conf_id=%v" , ntfn .ConfRequest , ntfn .ConfID )
928+
929+ return nil
930+ }
931+
932+ if ntfn .dispatched {
933+ Log .Debugf ("Skipped dispatched conf details for request %v " +
934+ "conf_id=%v" , ntfn .ConfRequest , ntfn .ConfID )
919935
920936 return nil
921937 }
@@ -925,16 +941,16 @@ func (n *TxNotifier) dispatchConfDetails(
925941 // we'll dispatch a confirmation notification to the caller.
926942 confHeight := details .BlockHeight + ntfn .NumConfirmations - 1
927943 if confHeight <= n .currentHeight {
928- Log .Debugf ("Dispatching %v confirmation notification for %v" ,
929- ntfn .NumConfirmations , ntfn .ConfRequest )
944+ Log .Debugf ("Dispatching %v confirmation notification for " +
945+ "conf_id=%v, %v" , ntfn .NumConfirmations , ntfn .ConfID ,
946+ ntfn .ConfRequest )
930947
931948 // We'll send a 0 value to the Updates channel,
932949 // indicating that the transaction/output script has already
933950 // been confirmed.
934- select {
935- case ntfn .Event .Updates <- 0 :
936- case <- n .quit :
937- return ErrTxNotifierExiting
951+ err := n .notifyNumConfsLeft (ntfn , 0 )
952+ if err != nil {
953+ return err
938954 }
939955
940956 select {
@@ -944,8 +960,8 @@ func (n *TxNotifier) dispatchConfDetails(
944960 return ErrTxNotifierExiting
945961 }
946962 } else {
947- Log .Debugf ("Queueing %v confirmation notification for %v at tip " ,
948- ntfn .NumConfirmations , ntfn .ConfRequest )
963+ Log .Debugf ("Queueing %v confirmation notification for %v at " +
964+ "tip" , ntfn .NumConfirmations , ntfn .ConfRequest )
949965
950966 // Otherwise, we'll keep track of the notification
951967 // request by the height at which we should dispatch the
@@ -961,10 +977,9 @@ func (n *TxNotifier) dispatchConfDetails(
961977 // confirmations are left for the transaction/output script to
962978 // be confirmed.
963979 numConfsLeft := confHeight - n .currentHeight
964- select {
965- case ntfn .Event .Updates <- numConfsLeft :
966- case <- n .quit :
967- return ErrTxNotifierExiting
980+ err := n .notifyNumConfsLeft (ntfn , numConfsLeft )
981+ if err != nil {
982+ return err
968983 }
969984 }
970985
@@ -1729,10 +1744,9 @@ func (n *TxNotifier) NotifyHeight(height uint32) error {
17291744 continue
17301745 }
17311746
1732- select {
1733- case ntfn .Event .Updates <- numConfsLeft :
1734- case <- n .quit :
1735- return ErrTxNotifierExiting
1747+ err := n .notifyNumConfsLeft (ntfn , numConfsLeft )
1748+ if err != nil {
1749+ return err
17361750 }
17371751 }
17381752 }
@@ -1743,8 +1757,9 @@ func (n *TxNotifier) NotifyHeight(height uint32) error {
17431757 for ntfn := range n .ntfnsByConfirmHeight [height ] {
17441758 confSet := n .confNotifications [ntfn .ConfRequest ]
17451759
1746- Log .Debugf ("Dispatching %v confirmation notification for %v" ,
1747- ntfn .NumConfirmations , ntfn .ConfRequest )
1760+ Log .Debugf ("Dispatching %v confirmation notification for " +
1761+ "conf_id=%v, %v" , ntfn .NumConfirmations , ntfn .ConfID ,
1762+ ntfn .ConfRequest )
17481763
17491764 // The default notification we assigned above includes the
17501765 // block along with the rest of the details. However not all
@@ -1833,6 +1848,9 @@ func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
18331848 default :
18341849 }
18351850
1851+ // We also reset the num of confs update.
1852+ ntfn .numConfsLeft = ntfn .NumConfirmations
1853+
18361854 // Then, we'll check if the current
18371855 // transaction/output script was included in the
18381856 // block currently being disconnected. If it
@@ -2069,3 +2087,30 @@ func (n *TxNotifier) TearDown() {
20692087 }
20702088 }
20712089}
2090+
2091+ // notifyNumConfsLeft sends the number of confirmations left to the
2092+ // notification subscriber through the Event.Updates channel.
2093+ //
2094+ // NOTE: must be used with the TxNotifier's lock held.
2095+ func (n * TxNotifier ) notifyNumConfsLeft (ntfn * ConfNtfn , num uint32 ) error {
2096+ // If the number left is no less than the recorded value, we can skip
2097+ // sending it as it means this same value has already been sent before.
2098+ if num >= ntfn .numConfsLeft {
2099+ Log .Debugf ("Skipped dispatched update (numConfsLeft=%v) for " +
2100+ "request %v conf_id=%v" , num , ntfn .ConfRequest ,
2101+ ntfn .ConfID )
2102+
2103+ return nil
2104+ }
2105+
2106+ // Update the number of confirmations left to the notification.
2107+ ntfn .numConfsLeft = num
2108+
2109+ select {
2110+ case ntfn .Event .Updates <- num :
2111+ case <- n .quit :
2112+ return ErrTxNotifierExiting
2113+ }
2114+
2115+ return nil
2116+ }
0 commit comments