discovery: prevent rebroadcast of previously premature announcements
This commit is contained in:
parent
a4f33ae63c
commit
871a6f1690
@ -265,16 +265,6 @@ type AuthenticatedGossiper struct {
|
|||||||
// every new block height.
|
// every new block height.
|
||||||
blockEpochs *chainntnfs.BlockEpochEvent
|
blockEpochs *chainntnfs.BlockEpochEvent
|
||||||
|
|
||||||
// prematureAnnouncements maps a block height to a set of network
|
|
||||||
// messages which are "premature" from our PoV. A message is premature
|
|
||||||
// if it claims to be anchored in a block which is beyond the current
|
|
||||||
// main chain tip as we know it. Premature network messages will be
|
|
||||||
// processed once the chain tip as we know it extends to/past the
|
|
||||||
// premature height.
|
|
||||||
//
|
|
||||||
// TODO(roasbeef): limit premature networkMsgs to N
|
|
||||||
prematureAnnouncements map[uint32][]*networkMsg
|
|
||||||
|
|
||||||
// prematureChannelUpdates is a map of ChannelUpdates we have received
|
// prematureChannelUpdates is a map of ChannelUpdates we have received
|
||||||
// that wasn't associated with any channel we know about. We store
|
// that wasn't associated with any channel we know about. We store
|
||||||
// them temporarily, such that we can reprocess them when a
|
// them temporarily, such that we can reprocess them when a
|
||||||
@ -338,7 +328,6 @@ func New(cfg Config, selfKey *btcec.PublicKey) *AuthenticatedGossiper {
|
|||||||
networkMsgs: make(chan *networkMsg),
|
networkMsgs: make(chan *networkMsg),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
chanPolicyUpdates: make(chan *chanPolicyUpdateRequest),
|
chanPolicyUpdates: make(chan *chanPolicyUpdateRequest),
|
||||||
prematureAnnouncements: make(map[uint32][]*networkMsg),
|
|
||||||
prematureChannelUpdates: make(map[uint64][]*networkMsg),
|
prematureChannelUpdates: make(map[uint64][]*networkMsg),
|
||||||
channelMtx: multimutex.NewMutex(),
|
channelMtx: multimutex.NewMutex(),
|
||||||
recentRejects: make(map[uint64]struct{}),
|
recentRejects: make(map[uint64]struct{}),
|
||||||
@ -1047,33 +1036,11 @@ func (d *AuthenticatedGossiper) networkHandler() {
|
|||||||
d.Lock()
|
d.Lock()
|
||||||
blockHeight := uint32(newBlock.Height)
|
blockHeight := uint32(newBlock.Height)
|
||||||
d.bestHeight = blockHeight
|
d.bestHeight = blockHeight
|
||||||
|
d.Unlock()
|
||||||
|
|
||||||
log.Debugf("New block: height=%d, hash=%s", blockHeight,
|
log.Debugf("New block: height=%d, hash=%s", blockHeight,
|
||||||
newBlock.Hash)
|
newBlock.Hash)
|
||||||
|
|
||||||
// Next we check if we have any premature announcements
|
|
||||||
// for this height, if so, then we process them once
|
|
||||||
// more as normal announcements.
|
|
||||||
premature := d.prematureAnnouncements[blockHeight]
|
|
||||||
if len(premature) == 0 {
|
|
||||||
d.Unlock()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
delete(d.prematureAnnouncements, blockHeight)
|
|
||||||
d.Unlock()
|
|
||||||
|
|
||||||
log.Infof("Re-processing %v premature announcements "+
|
|
||||||
"for height %v", len(premature), blockHeight)
|
|
||||||
|
|
||||||
for _, ann := range premature {
|
|
||||||
emittedAnnouncements := d.processNetworkAnnouncement(ann)
|
|
||||||
if emittedAnnouncements != nil {
|
|
||||||
announcements.AddMsgs(
|
|
||||||
emittedAnnouncements...,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The trickle timer has ticked, which indicates we should
|
// The trickle timer has ticked, which indicates we should
|
||||||
// flush to the network the pending batch of new announcements
|
// flush to the network the pending batch of new announcements
|
||||||
// we've received since the last trickle tick.
|
// we've received since the last trickle tick.
|
||||||
@ -1503,7 +1470,6 @@ func (d *AuthenticatedGossiper) addNode(msg *lnwire.NodeAnnouncement) error {
|
|||||||
func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
||||||
nMsg *networkMsg) []networkMsg {
|
nMsg *networkMsg) []networkMsg {
|
||||||
|
|
||||||
// isPremature *MUST* be called with the gossiper's lock held.
|
|
||||||
isPremature := func(chanID lnwire.ShortChannelID, delta uint32) bool {
|
isPremature := func(chanID lnwire.ShortChannelID, delta uint32) bool {
|
||||||
// TODO(roasbeef) make height delta 6
|
// TODO(roasbeef) make height delta 6
|
||||||
// * or configurable
|
// * or configurable
|
||||||
@ -1595,18 +1561,12 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
|||||||
// to be fully verified once we advance forward in the chain.
|
// to be fully verified once we advance forward in the chain.
|
||||||
d.Lock()
|
d.Lock()
|
||||||
if nMsg.isRemote && isPremature(msg.ShortChannelID, 0) {
|
if nMsg.isRemote && isPremature(msg.ShortChannelID, 0) {
|
||||||
blockHeight := msg.ShortChannelID.BlockHeight
|
|
||||||
log.Infof("Announcement for chan_id=(%v), is "+
|
log.Infof("Announcement for chan_id=(%v), is "+
|
||||||
"premature: advertises height %v, only "+
|
"premature: advertises height %v, only "+
|
||||||
"height %v is known",
|
"height %v is known",
|
||||||
msg.ShortChannelID.ToUint64(),
|
msg.ShortChannelID.ToUint64(),
|
||||||
msg.ShortChannelID.BlockHeight,
|
msg.ShortChannelID.BlockHeight,
|
||||||
d.bestHeight)
|
d.bestHeight)
|
||||||
|
|
||||||
d.prematureAnnouncements[blockHeight] = append(
|
|
||||||
d.prematureAnnouncements[blockHeight],
|
|
||||||
nMsg,
|
|
||||||
)
|
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1826,11 +1786,6 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
|||||||
"height %v, only height %v is known",
|
"height %v, only height %v is known",
|
||||||
shortChanID, blockHeight,
|
shortChanID, blockHeight,
|
||||||
d.bestHeight)
|
d.bestHeight)
|
||||||
|
|
||||||
d.prematureAnnouncements[blockHeight] = append(
|
|
||||||
d.prematureAnnouncements[blockHeight],
|
|
||||||
nMsg,
|
|
||||||
)
|
|
||||||
d.Unlock()
|
d.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -2126,10 +2081,6 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
|||||||
// to other clients if this constraint was changed.
|
// to other clients if this constraint was changed.
|
||||||
d.Lock()
|
d.Lock()
|
||||||
if isPremature(msg.ShortChannelID, d.cfg.ProofMatureDelta) {
|
if isPremature(msg.ShortChannelID, d.cfg.ProofMatureDelta) {
|
||||||
d.prematureAnnouncements[needBlockHeight] = append(
|
|
||||||
d.prematureAnnouncements[needBlockHeight],
|
|
||||||
nMsg,
|
|
||||||
)
|
|
||||||
log.Infof("Premature proof announcement, "+
|
log.Infof("Premature proof announcement, "+
|
||||||
"current block height lower than needed: %v <"+
|
"current block height lower than needed: %v <"+
|
||||||
" %v, add announcement to reprocessing batch",
|
" %v, add announcement to reprocessing batch",
|
||||||
|
@ -918,8 +918,7 @@ func TestPrematureAnnouncement(t *testing.T) {
|
|||||||
|
|
||||||
// Pretending that we receive the valid channel update announcement from
|
// Pretending that we receive the valid channel update announcement from
|
||||||
// remote side, but block height of this announcement is greater than
|
// remote side, but block height of this announcement is greater than
|
||||||
// highest know to us, for that reason it should be added to the
|
// highest known to us, so it should be rejected.
|
||||||
// repeat/premature batch.
|
|
||||||
ua, err := createUpdateAnnouncement(1, 0, nodeKeyPriv1, timestamp)
|
ua, err := createUpdateAnnouncement(1, 0, nodeKeyPriv1, timestamp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't create update announcement: %v", err)
|
t.Fatalf("can't create update announcement: %v", err)
|
||||||
@ -934,31 +933,6 @@ func TestPrematureAnnouncement(t *testing.T) {
|
|||||||
if len(ctx.router.edges) != 0 {
|
if len(ctx.router.edges) != 0 {
|
||||||
t.Fatal("edge update was added to router")
|
t.Fatal("edge update was added to router")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate new block and waiting the previously added announcements
|
|
||||||
// to be proceeded.
|
|
||||||
newBlock := &wire.MsgBlock{}
|
|
||||||
ctx.notifier.notifyBlock(newBlock.Header.BlockHash(), 1)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-ctx.broadcastedMessage:
|
|
||||||
case <-time.After(2 * trickleDelay):
|
|
||||||
t.Fatal("announcement wasn't broadcasted")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ctx.router.infos) != 1 {
|
|
||||||
t.Fatalf("edge wasn't added to router: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-ctx.broadcastedMessage:
|
|
||||||
case <-time.After(2 * trickleDelay):
|
|
||||||
t.Fatal("announcement wasn't broadcasted")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ctx.router.edges) != 1 {
|
|
||||||
t.Fatalf("edge update wasn't added to router: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestSignatureAnnouncementLocalFirst ensures that the AuthenticatedGossiper
|
// TestSignatureAnnouncementLocalFirst ensures that the AuthenticatedGossiper
|
||||||
|
Loading…
Reference in New Issue
Block a user