[NOD-175] When resolving orphans - don't send inv (#300)

* [NOD-175] Added BlockAddedNotificationData and sent it instead of just a block on BlockAdded.

* [NOD-175] Added BFWasUnorphaned and raised it when an unorphaned block was to be accepted.

* [NOD-175] Fixed a typo.

* [NOD-175] Made it so that only the mempool gets updated if we're not current or the block was just now unorphaned.
This commit is contained in:
stasatdaglabs 2019-05-16 13:05:30 +03:00 committed by Ori Newman
parent ac1fd11a42
commit 2481871c10
5 changed files with 37 additions and 19 deletions

View File

@ -80,7 +80,10 @@ func (dag *BlockDAG) maybeAcceptBlock(block *util.Block, flags BehaviorFlags) er
// DAG. The caller would typically want to react by relaying the
// inventory to other peers.
dag.dagLock.Unlock()
dag.sendNotification(NTBlockAdded, block)
dag.sendNotification(NTBlockAdded, &BlockAddedNotificationData{
Block: block,
WasUnorphaned: flags&BFWasUnorphaned != 0,
})
dag.dagLock.Lock()
return nil

View File

@ -6,6 +6,7 @@ package blockdag
import (
"fmt"
"github.com/daglabs/btcd/util"
)
// NotificationType represents the type of a notification message.
@ -66,3 +67,10 @@ func (dag *BlockDAG) sendNotification(typ NotificationType, data interface{}) {
}
dag.notificationsLock.RUnlock()
}
// BlockAddedNotificationData defines data to be sent along with a BlockAdded
// notification
type BlockAddedNotificationData struct {
Block *util.Block
WasUnorphaned bool
}

View File

@ -14,7 +14,7 @@ import (
)
// BehaviorFlags is a bitmask defining tweaks to the normal behavior when
// performing chain processing and consensus rules checks.
// performing DAG processing and consensus rules checks.
type BehaviorFlags uint32
const (
@ -29,6 +29,10 @@ const (
// not be performed.
BFNoPoWCheck
// BFWasUnorphaned may be set to indicate that a block was just now
// unorphaned
BFWasUnorphaned
// BFNone is a convenience value to specifically indicate no flags.
BFNone BehaviorFlags = 0
)
@ -107,7 +111,7 @@ func (dag *BlockDAG) processOrphans(hash *daghash.Hash, flags BehaviorFlags) err
i--
// Potentially accept the block into the block DAG.
err = dag.maybeAcceptBlock(orphan.block, flags)
err = dag.maybeAcceptBlock(orphan.block, flags|BFWasUnorphaned)
if err != nil {
return err
}

View File

@ -1213,21 +1213,12 @@ func (sm *SyncManager) handleBlockDAGNotification(notification *blockdag.Notific
switch notification.Type {
// A block has been accepted into the blockDAG. Relay it to other peers.
case blockdag.NTBlockAdded:
// Don't relay if we are not current. Other peers that are
// current should already know about it.
if !sm.current() {
return
}
block, ok := notification.Data.(*util.Block)
data, ok := notification.Data.(*blockdag.BlockAddedNotificationData)
if !ok {
log.Warnf("Block Added notification data is not a block.")
log.Warnf("Block Added notification data is of wrong type.")
break
}
// Generate the inventory vector and relay it.
iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash())
sm.peerNotifier.RelayInventory(iv, block.MsgBlock().Header)
block := data.Block
// Update mempool
ch := make(chan mempool.NewBlockMsg)
@ -1238,6 +1229,17 @@ func (sm *SyncManager) handleBlockDAGNotification(notification *blockdag.Notific
panic(fmt.Sprintf("HandleNewBlock failed to handle block %s", block.Hash()))
}
})
// Don't relay if we are not current or the block was just now unorphaned.
// Other peers that are current should already know about it
if !sm.current() || data.WasUnorphaned {
return
}
// Generate the inventory vector and relay it.
iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash())
sm.peerNotifier.RelayInventory(iv, block.MsgBlock().Header)
for msg := range ch {
sm.peerNotifier.TransactionConfirmed(msg.Tx)
sm.peerNotifier.AnnounceNewTransactions(msg.AcceptedTxs)

View File

@ -4312,21 +4312,22 @@ func NewRPCServer(
rpc.limitauthsha = sha256.Sum256([]byte(auth))
}
rpc.ntfnMgr = newWsNotificationManager(&rpc)
rpc.cfg.DAG.Subscribe(rpc.handleBlockchainNotification)
rpc.cfg.DAG.Subscribe(rpc.handleBlockDAGNotification)
return &rpc, nil
}
// Callback for notifications from blockdag. It notifies clients that are
// long polling for changes or subscribed to websockets notifications.
func (s *Server) handleBlockchainNotification(notification *blockdag.Notification) {
func (s *Server) handleBlockDAGNotification(notification *blockdag.Notification) {
switch notification.Type {
case blockdag.NTBlockAdded:
block, ok := notification.Data.(*util.Block)
data, ok := notification.Data.(*blockdag.BlockAddedNotificationData)
if !ok {
log.Warnf("Block added notification data is not a block.")
log.Warnf("Block added notification data is of wrong type.")
break
}
block := data.Block
tipHashes := s.cfg.DAG.TipHashes()