mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-18 21:35:24 +01:00
discovery: move ann sig handling to handleAnnSig
This commit is contained in:
parent
1e9220dab6
commit
932c5f1a7b
@ -1758,10 +1758,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
||||
schedulerOp = append(schedulerOp, batch.LazyAdd())
|
||||
}
|
||||
|
||||
var announcements []networkMsg
|
||||
|
||||
switch msg := nMsg.msg.(type) {
|
||||
|
||||
// A new node announcement has arrived which either presents new
|
||||
// information about a node in one of the channels we know about, or a
|
||||
// updating previously advertised information.
|
||||
@ -1785,324 +1782,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
||||
// willingness of nodes involved in the funding of a channel to
|
||||
// announce this new channel to the rest of the world.
|
||||
case *lnwire.AnnounceSignatures:
|
||||
needBlockHeight := msg.ShortChannelID.BlockHeight +
|
||||
d.cfg.ProofMatureDelta
|
||||
shortChanID := msg.ShortChannelID.ToUint64()
|
||||
|
||||
prefix := "local"
|
||||
if nMsg.isRemote {
|
||||
prefix = "remote"
|
||||
}
|
||||
|
||||
log.Infof("Received new %v channel announcement for %v", prefix,
|
||||
msg.ShortChannelID)
|
||||
|
||||
// By the specification, channel announcement proofs should be
|
||||
// sent after some number of confirmations after channel was
|
||||
// registered in bitcoin blockchain. Therefore, we check if the
|
||||
// proof is premature.
|
||||
d.Lock()
|
||||
premature := d.isPremature(
|
||||
msg.ShortChannelID, d.cfg.ProofMatureDelta, nMsg,
|
||||
)
|
||||
if premature {
|
||||
log.Warnf("Premature proof announcement, current "+
|
||||
"block height lower than needed: %v < %v",
|
||||
d.bestHeight, needBlockHeight)
|
||||
d.Unlock()
|
||||
nMsg.err <- nil
|
||||
return nil, false
|
||||
}
|
||||
d.Unlock()
|
||||
|
||||
// Ensure that we know of a channel with the target channel ID
|
||||
// before proceeding further.
|
||||
//
|
||||
// We must acquire the mutex for this channel ID before getting
|
||||
// the channel from the database, to ensure what we read does
|
||||
// not change before we call AddProof() later.
|
||||
d.channelMtx.Lock(msg.ShortChannelID.ToUint64())
|
||||
defer d.channelMtx.Unlock(msg.ShortChannelID.ToUint64())
|
||||
|
||||
chanInfo, e1, e2, err := d.cfg.Router.GetChannelByID(
|
||||
msg.ShortChannelID)
|
||||
if err != nil {
|
||||
// TODO(andrew.shvv) this is dangerous because remote
|
||||
// node might rewrite the waiting proof.
|
||||
proof := channeldb.NewWaitingProof(nMsg.isRemote, msg)
|
||||
err := d.cfg.WaitingProofStore.Add(proof)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to store "+
|
||||
"the proof for short_chan_id=%v: %v",
|
||||
shortChanID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
log.Infof("Orphan %v proof announcement with "+
|
||||
"short_chan_id=%v, adding "+
|
||||
"to waiting batch", prefix, shortChanID)
|
||||
nMsg.err <- nil
|
||||
return nil, false
|
||||
}
|
||||
|
||||
nodeID := nMsg.source.SerializeCompressed()
|
||||
isFirstNode := bytes.Equal(nodeID, chanInfo.NodeKey1Bytes[:])
|
||||
isSecondNode := bytes.Equal(nodeID, chanInfo.NodeKey2Bytes[:])
|
||||
|
||||
// Ensure that channel that was retrieved belongs to the peer
|
||||
// which sent the proof announcement.
|
||||
if !(isFirstNode || isSecondNode) {
|
||||
err := fmt.Errorf("channel that was received not "+
|
||||
"belongs to the peer which sent the proof, "+
|
||||
"short_chan_id=%v", shortChanID)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// If proof was sent by a local sub-system, then we'll
|
||||
// send the announcement signature to the remote node
|
||||
// so they can also reconstruct the full channel
|
||||
// announcement.
|
||||
if !nMsg.isRemote {
|
||||
var remotePubKey [33]byte
|
||||
if isFirstNode {
|
||||
remotePubKey = chanInfo.NodeKey2Bytes
|
||||
} else {
|
||||
remotePubKey = chanInfo.NodeKey1Bytes
|
||||
}
|
||||
// Since the remote peer might not be online
|
||||
// we'll call a method that will attempt to
|
||||
// deliver the proof when it comes online.
|
||||
err := d.reliableSender.sendMessage(msg, remotePubKey)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to reliably send %v "+
|
||||
"for channel=%v to peer=%x: %v",
|
||||
msg.MsgType(), msg.ShortChannelID,
|
||||
remotePubKey, err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we already have the full proof for this channel.
|
||||
if chanInfo.AuthProof != nil {
|
||||
// If we already have the fully assembled proof, then
|
||||
// the peer sending us their proof has probably not
|
||||
// received our local proof yet. So be kind and send
|
||||
// them the full proof.
|
||||
if nMsg.isRemote {
|
||||
peerID := nMsg.source.SerializeCompressed()
|
||||
log.Debugf("Got AnnounceSignatures for " +
|
||||
"channel with full proof.")
|
||||
|
||||
d.wg.Add(1)
|
||||
go func() {
|
||||
defer d.wg.Done()
|
||||
log.Debugf("Received half proof for "+
|
||||
"channel %v with existing "+
|
||||
"full proof. Sending full "+
|
||||
"proof to peer=%x",
|
||||
msg.ChannelID,
|
||||
peerID)
|
||||
|
||||
chanAnn, _, _, err := netann.CreateChanAnnouncement(
|
||||
chanInfo.AuthProof, chanInfo,
|
||||
e1, e2,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("unable to gen "+
|
||||
"ann: %v", err)
|
||||
return
|
||||
}
|
||||
err = nMsg.peer.SendMessage(
|
||||
false, chanAnn,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Failed sending "+
|
||||
"full proof to "+
|
||||
"peer=%x: %v",
|
||||
peerID, err)
|
||||
return
|
||||
}
|
||||
log.Debugf("Full proof sent to peer=%x"+
|
||||
" for chanID=%v", peerID,
|
||||
msg.ChannelID)
|
||||
}()
|
||||
}
|
||||
|
||||
log.Debugf("Already have proof for channel "+
|
||||
"with chanID=%v", msg.ChannelID)
|
||||
nMsg.err <- nil
|
||||
return nil, true
|
||||
}
|
||||
|
||||
// Check that we received the opposite proof. If so, then we're
|
||||
// now able to construct the full proof, and create the channel
|
||||
// announcement. If we didn't receive the opposite half of the
|
||||
// proof than we should store it this one, and wait for
|
||||
// opposite to be received.
|
||||
proof := channeldb.NewWaitingProof(nMsg.isRemote, msg)
|
||||
oppositeProof, err := d.cfg.WaitingProofStore.Get(
|
||||
proof.OppositeKey(),
|
||||
)
|
||||
if err != nil && err != channeldb.ErrWaitingProofNotFound {
|
||||
err := fmt.Errorf("unable to get "+
|
||||
"the opposite proof for short_chan_id=%v: %v",
|
||||
shortChanID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if err == channeldb.ErrWaitingProofNotFound {
|
||||
err := d.cfg.WaitingProofStore.Add(proof)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to store "+
|
||||
"the proof for short_chan_id=%v: %v",
|
||||
shortChanID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
log.Infof("1/2 of channel ann proof received for "+
|
||||
"short_chan_id=%v, waiting for other half",
|
||||
shortChanID)
|
||||
|
||||
nMsg.err <- nil
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// We now have both halves of the channel announcement proof,
|
||||
// then we'll reconstruct the initial announcement so we can
|
||||
// validate it shortly below.
|
||||
var dbProof channeldb.ChannelAuthProof
|
||||
if isFirstNode {
|
||||
dbProof.NodeSig1Bytes = msg.NodeSignature.ToSignatureBytes()
|
||||
dbProof.NodeSig2Bytes = oppositeProof.NodeSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig1Bytes = msg.BitcoinSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig2Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes()
|
||||
} else {
|
||||
dbProof.NodeSig1Bytes = oppositeProof.NodeSignature.ToSignatureBytes()
|
||||
dbProof.NodeSig2Bytes = msg.NodeSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig1Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig2Bytes = msg.BitcoinSignature.ToSignatureBytes()
|
||||
}
|
||||
chanAnn, e1Ann, e2Ann, err := netann.CreateChanAnnouncement(
|
||||
&dbProof, chanInfo, e1, e2,
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// With all the necessary components assembled validate the
|
||||
// full channel announcement proof.
|
||||
if err := routing.ValidateChannelAnn(chanAnn); err != nil {
|
||||
err := fmt.Errorf("channel announcement proof "+
|
||||
"for short_chan_id=%v isn't valid: %v",
|
||||
shortChanID, err)
|
||||
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// If the channel was returned by the router it means that
|
||||
// existence of funding point and inclusion of nodes bitcoin
|
||||
// keys in it already checked by the router. In this stage we
|
||||
// should check that node keys are attest to the bitcoin keys
|
||||
// by validating the signatures of announcement. If proof is
|
||||
// valid then we'll populate the channel edge with it, so we
|
||||
// can announce it on peer connect.
|
||||
err = d.cfg.Router.AddProof(msg.ShortChannelID, &dbProof)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable add proof to the "+
|
||||
"channel chanID=%v: %v", msg.ChannelID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
err = d.cfg.WaitingProofStore.Remove(proof.OppositeKey())
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable remove opposite proof "+
|
||||
"for the channel with chanID=%v: %v",
|
||||
msg.ChannelID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Proof was successfully created and now can announce the
|
||||
// channel to the remain network.
|
||||
log.Infof("Fully valid channel proof for short_chan_id=%v "+
|
||||
"constructed, adding to next ann batch",
|
||||
shortChanID)
|
||||
|
||||
// Assemble the necessary announcements to add to the next
|
||||
// broadcasting batch.
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: nMsg.source,
|
||||
msg: chanAnn,
|
||||
})
|
||||
if src, err := chanInfo.NodeKey1(); err == nil && e1Ann != nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: src,
|
||||
msg: e1Ann,
|
||||
})
|
||||
}
|
||||
if src, err := chanInfo.NodeKey2(); err == nil && e2Ann != nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: src,
|
||||
msg: e2Ann,
|
||||
})
|
||||
}
|
||||
|
||||
// We'll also send along the node announcements for each channel
|
||||
// participant if we know of them. To ensure our node
|
||||
// announcement propagates to our channel counterparty, we'll
|
||||
// set the source for each announcement to the node it belongs
|
||||
// to, otherwise we won't send it since the source gets skipped.
|
||||
// This isn't necessary for channel updates and announcement
|
||||
// signatures since we send those directly to our channel
|
||||
// counterparty through the gossiper's reliable sender.
|
||||
node1Ann, err := d.fetchNodeAnn(chanInfo.NodeKey1Bytes)
|
||||
if err != nil {
|
||||
log.Debugf("Unable to fetch node announcement for "+
|
||||
"%x: %v", chanInfo.NodeKey1Bytes, err)
|
||||
} else {
|
||||
if nodeKey1, err := chanInfo.NodeKey1(); err == nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: nodeKey1,
|
||||
msg: node1Ann,
|
||||
})
|
||||
}
|
||||
}
|
||||
node2Ann, err := d.fetchNodeAnn(chanInfo.NodeKey2Bytes)
|
||||
if err != nil {
|
||||
log.Debugf("Unable to fetch node announcement for "+
|
||||
"%x: %v", chanInfo.NodeKey2Bytes, err)
|
||||
} else {
|
||||
if nodeKey2, err := chanInfo.NodeKey2(); err == nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: nodeKey2,
|
||||
msg: node2Ann,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
nMsg.err <- nil
|
||||
return announcements, true
|
||||
return d.handleAnnSig(nMsg, msg)
|
||||
|
||||
default:
|
||||
err := errors.New("wrong type of the announcement")
|
||||
@ -2978,3 +2658,309 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
|
||||
nMsg.err <- nil
|
||||
return announcements, true
|
||||
}
|
||||
|
||||
// handleAnnSig processes a new announcement signatures message.
|
||||
func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg,
|
||||
ann *lnwire.AnnounceSignatures) ([]networkMsg, bool) {
|
||||
|
||||
needBlockHeight := ann.ShortChannelID.BlockHeight +
|
||||
d.cfg.ProofMatureDelta
|
||||
shortChanID := ann.ShortChannelID.ToUint64()
|
||||
|
||||
prefix := "local"
|
||||
if nMsg.isRemote {
|
||||
prefix = "remote"
|
||||
}
|
||||
|
||||
log.Infof("Received new %v channel announcement for %v", prefix,
|
||||
ann.ShortChannelID)
|
||||
|
||||
// By the specification, channel announcement proofs should be sent
|
||||
// after some number of confirmations after channel was registered in
|
||||
// bitcoin blockchain. Therefore, we check if the proof is mature.
|
||||
d.Lock()
|
||||
premature := d.isPremature(
|
||||
ann.ShortChannelID, d.cfg.ProofMatureDelta, nMsg,
|
||||
)
|
||||
if premature {
|
||||
log.Warnf("Premature proof announcement, current block height"+
|
||||
"lower than needed: %v < %v", d.bestHeight,
|
||||
needBlockHeight)
|
||||
d.Unlock()
|
||||
nMsg.err <- nil
|
||||
return nil, false
|
||||
}
|
||||
d.Unlock()
|
||||
|
||||
// Ensure that we know of a channel with the target channel ID before
|
||||
// proceeding further.
|
||||
//
|
||||
// We must acquire the mutex for this channel ID before getting the
|
||||
// channel from the database, to ensure what we read does not change
|
||||
// before we call AddProof() later.
|
||||
d.channelMtx.Lock(ann.ShortChannelID.ToUint64())
|
||||
defer d.channelMtx.Unlock(ann.ShortChannelID.ToUint64())
|
||||
|
||||
chanInfo, e1, e2, err := d.cfg.Router.GetChannelByID(
|
||||
ann.ShortChannelID,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
proof := channeldb.NewWaitingProof(nMsg.isRemote, ann)
|
||||
err := d.cfg.WaitingProofStore.Add(proof)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to store the proof for "+
|
||||
"short_chan_id=%v: %v", shortChanID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
log.Infof("Orphan %v proof announcement with short_chan_id=%v"+
|
||||
", adding to waiting batch", prefix, shortChanID)
|
||||
nMsg.err <- nil
|
||||
return nil, false
|
||||
}
|
||||
|
||||
nodeID := nMsg.source.SerializeCompressed()
|
||||
isFirstNode := bytes.Equal(nodeID, chanInfo.NodeKey1Bytes[:])
|
||||
isSecondNode := bytes.Equal(nodeID, chanInfo.NodeKey2Bytes[:])
|
||||
|
||||
// Ensure that channel that was retrieved belongs to the peer which
|
||||
// sent the proof announcement.
|
||||
if !(isFirstNode || isSecondNode) {
|
||||
err := fmt.Errorf("channel that was received doesn't belong "+
|
||||
"to the peer which sent the proof, short_chan_id=%v",
|
||||
shortChanID)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// If proof was sent by a local sub-system, then we'll send the
|
||||
// announcement signature to the remote node so they can also
|
||||
// reconstruct the full channel announcement.
|
||||
if !nMsg.isRemote {
|
||||
var remotePubKey [33]byte
|
||||
if isFirstNode {
|
||||
remotePubKey = chanInfo.NodeKey2Bytes
|
||||
} else {
|
||||
remotePubKey = chanInfo.NodeKey1Bytes
|
||||
}
|
||||
// Since the remote peer might not be online we'll call a
|
||||
// method that will attempt to deliver the proof when it comes
|
||||
// online.
|
||||
err := d.reliableSender.sendMessage(ann, remotePubKey)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to reliably send %v for "+
|
||||
"channel=%v to peer=%x: %v", ann.MsgType(),
|
||||
ann.ShortChannelID, remotePubKey, err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we already have the full proof for this channel.
|
||||
if chanInfo.AuthProof != nil {
|
||||
// If we already have the fully assembled proof, then the peer
|
||||
// sending us their proof has probably not received our local
|
||||
// proof yet. So be kind and send them the full proof.
|
||||
if nMsg.isRemote {
|
||||
peerID := nMsg.source.SerializeCompressed()
|
||||
log.Debugf("Got AnnounceSignatures for channel with " +
|
||||
"full proof.")
|
||||
|
||||
d.wg.Add(1)
|
||||
go func() {
|
||||
defer d.wg.Done()
|
||||
log.Debugf("Received half proof for channel "+
|
||||
"%v with existing full proof. Sending"+
|
||||
" full proof to peer=%x",
|
||||
ann.ChannelID, peerID)
|
||||
|
||||
ca, _, _, err := netann.CreateChanAnnouncement(
|
||||
chanInfo.AuthProof, chanInfo, e1, e2,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("unable to gen ann: %v",
|
||||
err)
|
||||
return
|
||||
}
|
||||
|
||||
err = nMsg.peer.SendMessage(false, ca)
|
||||
if err != nil {
|
||||
log.Errorf("Failed sending full proof"+
|
||||
" to peer=%x: %v", peerID, err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("Full proof sent to peer=%x for "+
|
||||
"chanID=%v", peerID, ann.ChannelID)
|
||||
}()
|
||||
}
|
||||
|
||||
log.Debugf("Already have proof for channel with chanID=%v",
|
||||
ann.ChannelID)
|
||||
nMsg.err <- nil
|
||||
return nil, true
|
||||
}
|
||||
|
||||
// Check that we received the opposite proof. If so, then we're now
|
||||
// able to construct the full proof, and create the channel
|
||||
// announcement. If we didn't receive the opposite half of the proof
|
||||
// then we should store this one, and wait for the opposite to be
|
||||
// received.
|
||||
proof := channeldb.NewWaitingProof(nMsg.isRemote, ann)
|
||||
oppProof, err := d.cfg.WaitingProofStore.Get(proof.OppositeKey())
|
||||
if err != nil && err != channeldb.ErrWaitingProofNotFound {
|
||||
err := fmt.Errorf("unable to get the opposite proof for "+
|
||||
"short_chan_id=%v: %v", shortChanID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if err == channeldb.ErrWaitingProofNotFound {
|
||||
err := d.cfg.WaitingProofStore.Add(proof)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to store the proof for "+
|
||||
"short_chan_id=%v: %v", shortChanID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
log.Infof("1/2 of channel ann proof received for "+
|
||||
"short_chan_id=%v, waiting for other half",
|
||||
shortChanID)
|
||||
|
||||
nMsg.err <- nil
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// We now have both halves of the channel announcement proof, then
|
||||
// we'll reconstruct the initial announcement so we can validate it
|
||||
// shortly below.
|
||||
var dbProof channeldb.ChannelAuthProof
|
||||
if isFirstNode {
|
||||
dbProof.NodeSig1Bytes = ann.NodeSignature.ToSignatureBytes()
|
||||
dbProof.NodeSig2Bytes = oppProof.NodeSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig1Bytes = ann.BitcoinSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig2Bytes = oppProof.BitcoinSignature.ToSignatureBytes()
|
||||
} else {
|
||||
dbProof.NodeSig1Bytes = oppProof.NodeSignature.ToSignatureBytes()
|
||||
dbProof.NodeSig2Bytes = ann.NodeSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig1Bytes = oppProof.BitcoinSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig2Bytes = ann.BitcoinSignature.ToSignatureBytes()
|
||||
}
|
||||
|
||||
chanAnn, e1Ann, e2Ann, err := netann.CreateChanAnnouncement(
|
||||
&dbProof, chanInfo, e1, e2,
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// With all the necessary components assembled validate the full
|
||||
// channel announcement proof.
|
||||
if err := routing.ValidateChannelAnn(chanAnn); err != nil {
|
||||
err := fmt.Errorf("channel announcement proof for "+
|
||||
"short_chan_id=%v isn't valid: %v", shortChanID, err)
|
||||
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// If the channel was returned by the router it means that existence of
|
||||
// funding point and inclusion of nodes bitcoin keys in it already
|
||||
// checked by the router. In this stage we should check that node keys
|
||||
// attest to the bitcoin keys by validating the signatures of
|
||||
// announcement. If proof is valid then we'll populate the channel edge
|
||||
// with it, so we can announce it on peer connect.
|
||||
err = d.cfg.Router.AddProof(ann.ShortChannelID, &dbProof)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable add proof to the channel chanID=%v:"+
|
||||
" %v", ann.ChannelID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
err = d.cfg.WaitingProofStore.Remove(proof.OppositeKey())
|
||||
if err != nil {
|
||||
err := fmt.Errorf("unable to remove opposite proof for the "+
|
||||
"channel with chanID=%v: %v", ann.ChannelID, err)
|
||||
log.Error(err)
|
||||
nMsg.err <- err
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Proof was successfully created and now can announce the channel to
|
||||
// the remain network.
|
||||
log.Infof("Fully valid channel proof for short_chan_id=%v constructed"+
|
||||
", adding to next ann batch", shortChanID)
|
||||
|
||||
// Assemble the necessary announcements to add to the next broadcasting
|
||||
// batch.
|
||||
var announcements []networkMsg
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: nMsg.source,
|
||||
msg: chanAnn,
|
||||
})
|
||||
if src, err := chanInfo.NodeKey1(); err == nil && e1Ann != nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: src,
|
||||
msg: e1Ann,
|
||||
})
|
||||
}
|
||||
if src, err := chanInfo.NodeKey2(); err == nil && e2Ann != nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: src,
|
||||
msg: e2Ann,
|
||||
})
|
||||
}
|
||||
|
||||
// We'll also send along the node announcements for each channel
|
||||
// participant if we know of them. To ensure our node announcement
|
||||
// propagates to our channel counterparty, we'll set the source for
|
||||
// each announcement to the node it belongs to, otherwise we won't send
|
||||
// it since the source gets skipped. This isn't necessary for channel
|
||||
// updates and announcement signatures since we send those directly to
|
||||
// our channel counterparty through the gossiper's reliable sender.
|
||||
node1Ann, err := d.fetchNodeAnn(chanInfo.NodeKey1Bytes)
|
||||
if err != nil {
|
||||
log.Debugf("Unable to fetch node announcement for %x: %v",
|
||||
chanInfo.NodeKey1Bytes, err)
|
||||
} else {
|
||||
if nodeKey1, err := chanInfo.NodeKey1(); err == nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: nodeKey1,
|
||||
msg: node1Ann,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
node2Ann, err := d.fetchNodeAnn(chanInfo.NodeKey2Bytes)
|
||||
if err != nil {
|
||||
log.Debugf("Unable to fetch node announcement for %x: %v",
|
||||
chanInfo.NodeKey2Bytes, err)
|
||||
} else {
|
||||
if nodeKey2, err := chanInfo.NodeKey2(); err == nil {
|
||||
announcements = append(announcements, networkMsg{
|
||||
peer: nMsg.peer,
|
||||
source: nodeKey2,
|
||||
msg: node2Ann,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
nMsg.err <- nil
|
||||
return announcements, true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user