diff --git a/discovery/chan_series.go b/discovery/chan_series.go index 362a22921..d91396a54 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -3,6 +3,7 @@ package discovery import ( "time" + "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwire" @@ -132,11 +133,16 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash, return nil, err } + var capacity btcutil.Amount + if ann, ok := chanAnn.(*lnwire.ChannelAnnouncement2); ok { + capacity = btcutil.Amount(ann.Capacity.Val) + } + updates = append(updates, chanAnn) if edge1 != nil { // We don't want to send channel updates that don't // conform to the spec (anymore). - err := edge1.Validate(0) + err := edge1.Validate(capacity) if err != nil { log.Errorf("not sending invalid channel "+ "update %v: %v", edge1, err) @@ -145,7 +151,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash, } } if edge2 != nil { - err := edge2.Validate(0) + err := edge2.Validate(capacity) if err != nil { log.Errorf("not sending invalid channel "+ "update %v: %v", edge2, err) diff --git a/netann/channel_announcement.go b/netann/channel_announcement.go index 71d7bf36c..e8088a26c 100644 --- a/netann/channel_announcement.go +++ b/netann/channel_announcement.go @@ -14,9 +14,9 @@ import ( // structs for announcing new channels to other peers, or simply syncing up a // peer's initial routing table upon connect. func CreateChanAnnouncement(chanProof models.ChannelAuthProof, - chanInfo models.ChannelEdgeInfo, edge1, - edge2 models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement1, - *lnwire.ChannelUpdate1, *lnwire.ChannelUpdate1, error) { + chanInfo models.ChannelEdgeInfo, + edge1, edge2 models.ChannelEdgePolicy) (lnwire.ChannelAnnouncement, + lnwire.ChannelUpdate, lnwire.ChannelUpdate, error) { switch proof := chanProof.(type) { case *models.ChannelAuthProof1: @@ -50,6 +50,37 @@ func CreateChanAnnouncement(chanProof models.ChannelAuthProof, return createChanAnnouncement1(proof, info, e1, e2) + case *models.ChannelAuthProof2: + info, ok := chanInfo.(*models.ChannelEdgeInfo2) + if !ok { + return nil, nil, nil, fmt.Errorf("expected type "+ + "ChannelEdgeInfo2 to be paired with "+ + "ChannelAuthProof2, got: %T", chanInfo) + } + + var e1, e2 *models.ChannelEdgePolicy2 + if edge1 != nil { + e1, ok = edge1.(*models.ChannelEdgePolicy2) + if !ok { + return nil, nil, nil, fmt.Errorf("expected "+ + "type ChannelEdgePolicy2 to be "+ + "paired with ChannelEdgeInfo2, "+ + "got: %T", edge1) + } + } + + if edge2 != nil { + e2, ok = edge2.(*models.ChannelEdgePolicy2) + if !ok { + return nil, nil, nil, fmt.Errorf("expected "+ + "type ChannelEdgePolicy2 to be "+ + "paired with ChannelEdgeInfo2, "+ + "got: %T", edge2) + } + } + + return createChanAnnouncement2(proof, info, e1, e2) + default: return nil, nil, nil, fmt.Errorf("unhandled "+ "models.ChannelAuthProof type: %T", chanProof) @@ -59,7 +90,7 @@ func CreateChanAnnouncement(chanProof models.ChannelAuthProof, func createChanAnnouncement1(chanProof *models.ChannelAuthProof1, chanInfo *models.ChannelEdgeInfo1, e1, e2 *models.ChannelEdgePolicy1) (*lnwire.ChannelAnnouncement1, - *lnwire.ChannelUpdate1, *lnwire.ChannelUpdate1, error) { + lnwire.ChannelUpdate, lnwire.ChannelUpdate, error) { // First, using the parameters of the channel, along with the channel // authentication chanProof, we'll create re-create the original @@ -112,7 +143,59 @@ func createChanAnnouncement1(chanProof *models.ChannelAuthProof1, // Since it's up to a node's policy as to whether they advertise the // edge in a direction, we don't create an advertisement if the edge is // nil. - var edge1Ann, edge2Ann *lnwire.ChannelUpdate1 + var edge1Ann, edge2Ann lnwire.ChannelUpdate + if e1 != nil { + edge1Ann, err = ChannelUpdateFromEdge(chanInfo, e1) + if err != nil { + return nil, nil, nil, err + } + } + if e2 != nil { + edge2Ann, err = ChannelUpdateFromEdge(chanInfo, e2) + if err != nil { + return nil, nil, nil, err + } + } + + return chanAnn, edge1Ann, edge2Ann, nil +} + +func createChanAnnouncement2(chanProof *models.ChannelAuthProof2, + chanInfo *models.ChannelEdgeInfo2, + e1, e2 *models.ChannelEdgePolicy2) (lnwire.ChannelAnnouncement, + lnwire.ChannelUpdate, lnwire.ChannelUpdate, error) { + + // First, using the parameters of the channel, along with the channel + // authentication chanProof, we'll create re-create the original + // authenticated channel announcement. + chanAnn := &lnwire.ChannelAnnouncement2{ + ShortChannelID: chanInfo.ShortChannelID, + NodeID1: chanInfo.NodeID1, + NodeID2: chanInfo.NodeID2, + ChainHash: chanInfo.ChainHash, + BitcoinKey1: chanInfo.BitcoinKey1, + BitcoinKey2: chanInfo.BitcoinKey2, + Features: chanInfo.Features, + Capacity: chanInfo.Capacity, + ExtraOpaqueData: chanInfo.ExtraOpaqueData, + } + + var err error + chanAnn.Signature, err = lnwire.NewSigFromSchnorrRawSignature( + chanProof.SchnorrSigBytes, + ) + if err != nil { + return nil, nil, nil, err + } + + // We'll unconditionally queue the channel's existence chanProof as it + // will need to be processed before either of the channel update + // networkMsgs. + + // Since it's up to a node's policy as to whether they advertise the + // edge in a direction, we don't create an advertisement if the edge is + // nil. + var edge1Ann, edge2Ann lnwire.ChannelUpdate if e1 != nil { edge1Ann, err = ChannelUpdateFromEdge(chanInfo, e1) if err != nil { diff --git a/netann/channel_update.go b/netann/channel_update.go index db0e97273..413314ba7 100644 --- a/netann/channel_update.go +++ b/netann/channel_update.go @@ -152,20 +152,27 @@ func unsignedChanPolicy1ToUpdate(chainHash chainhash.Hash, // ChannelUpdateFromEdge reconstructs a signed ChannelUpdate from the given // edge info and policy. func ChannelUpdateFromEdge(info models.ChannelEdgeInfo, - policy *models.ChannelEdgePolicy1) (*lnwire.ChannelUpdate1, error) { + policy models.ChannelEdgePolicy) (*lnwire.ChannelUpdate1, error) { - sig, err := policy.Signature() - if err != nil { - return nil, err + switch p := policy.(type) { + case *models.ChannelEdgePolicy1: + sig, err := p.Signature() + if err != nil { + return nil, err + } + + s, err := lnwire.NewSigFromSignature(sig) + if err != nil { + return nil, err + } + + update := unsignedChanPolicy1ToUpdate(info.GetChainHash(), p) + update.Signature = s + + return update, nil + + default: + return nil, fmt.Errorf("unhandled implementation of the "+ + "models.ChanelEdgePolicy interface: %T", policy) } - - s, err := lnwire.NewSigFromSignature(sig) - if err != nil { - return nil, err - } - - update := unsignedChanPolicy1ToUpdate(info.GetChainHash(), policy) - update.Signature = s - - return update, nil }