Merge pull request #2669 from cfromknecht/use-netann-in-discovery
netann+discovery+server: consolidate network announcements to netann pkg
This commit is contained in:
commit
4e793497c8
@ -6,6 +6,7 @@ import (
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
)
|
||||
|
||||
@ -119,7 +120,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
|
||||
continue
|
||||
}
|
||||
|
||||
chanAnn, edge1, edge2, err := CreateChanAnnouncement(
|
||||
chanAnn, edge1, edge2, err := netann.CreateChanAnnouncement(
|
||||
channel.Info.AuthProof, channel.Info, channel.Policy1,
|
||||
channel.Policy2,
|
||||
)
|
||||
@ -258,7 +259,7 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash,
|
||||
continue
|
||||
}
|
||||
|
||||
chanAnn, edge1, edge2, err := CreateChanAnnouncement(
|
||||
chanAnn, edge1, edge2, err := netann.CreateChanAnnouncement(
|
||||
channel.Info.AuthProof, channel.Info, channel.Policy1,
|
||||
channel.Policy2,
|
||||
)
|
||||
@ -323,20 +324,7 @@ func (c *ChanSeries) FetchChanUpdates(chain chainhash.Hash,
|
||||
|
||||
chanUpdates := make([]*lnwire.ChannelUpdate, 0, 2)
|
||||
if e1 != nil {
|
||||
chanUpdate := &lnwire.ChannelUpdate{
|
||||
ChainHash: chanInfo.ChainHash,
|
||||
ShortChannelID: shortChanID,
|
||||
Timestamp: uint32(e1.LastUpdate.Unix()),
|
||||
MessageFlags: e1.MessageFlags,
|
||||
ChannelFlags: e1.ChannelFlags,
|
||||
TimeLockDelta: e1.TimeLockDelta,
|
||||
HtlcMinimumMsat: e1.MinHTLC,
|
||||
HtlcMaximumMsat: e1.MaxHTLC,
|
||||
BaseFee: uint32(e1.FeeBaseMSat),
|
||||
FeeRate: uint32(e1.FeeProportionalMillionths),
|
||||
ExtraOpaqueData: e1.ExtraOpaqueData,
|
||||
}
|
||||
chanUpdate.Signature, err = lnwire.NewSigFromRawSignature(e1.SigBytes)
|
||||
chanUpdate, err := netann.ChannelUpdateFromEdge(chanInfo, e1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -344,20 +332,7 @@ func (c *ChanSeries) FetchChanUpdates(chain chainhash.Hash,
|
||||
chanUpdates = append(chanUpdates, chanUpdate)
|
||||
}
|
||||
if e2 != nil {
|
||||
chanUpdate := &lnwire.ChannelUpdate{
|
||||
ChainHash: chanInfo.ChainHash,
|
||||
ShortChannelID: shortChanID,
|
||||
Timestamp: uint32(e2.LastUpdate.Unix()),
|
||||
MessageFlags: e2.MessageFlags,
|
||||
ChannelFlags: e2.ChannelFlags,
|
||||
TimeLockDelta: e2.TimeLockDelta,
|
||||
HtlcMinimumMsat: e2.MinHTLC,
|
||||
HtlcMaximumMsat: e2.MaxHTLC,
|
||||
BaseFee: uint32(e2.FeeBaseMSat),
|
||||
FeeRate: uint32(e2.FeeProportionalMillionths),
|
||||
ExtraOpaqueData: e2.ExtraOpaqueData,
|
||||
}
|
||||
chanUpdate.Signature, err = lnwire.NewSigFromRawSignature(e2.SigBytes)
|
||||
chanUpdate, err := netann.ChannelUpdateFromEdge(chanInfo, e2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/multimutex"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
@ -350,15 +351,6 @@ func New(cfg Config, selfKey *btcec.PublicKey) *AuthenticatedGossiper {
|
||||
return gossiper
|
||||
}
|
||||
|
||||
// updatedChanPolicies is a set of channel policies that have been successfully
|
||||
// updated and written to disk, or an error if the policy update failed. This
|
||||
// struct's map field is intended to be used for updating channel policies on
|
||||
// the link layer.
|
||||
type updatedChanPolicies struct {
|
||||
chanPolicies map[wire.OutPoint]*channeldb.ChannelEdgePolicy
|
||||
err error
|
||||
}
|
||||
|
||||
// EdgeWithInfo contains the information that is required to update an edge.
|
||||
type EdgeWithInfo struct {
|
||||
// Info describes the channel.
|
||||
@ -1364,6 +1356,22 @@ func (d *AuthenticatedGossiper) processChanPolicyUpdate(
|
||||
return chanUpdates, nil
|
||||
}
|
||||
|
||||
// remotePubFromChanInfo returns the public key of the remote peer given a
|
||||
// ChannelEdgeInfo that describe a channel we have with them.
|
||||
func remotePubFromChanInfo(chanInfo *channeldb.ChannelEdgeInfo,
|
||||
chanFlags lnwire.ChanUpdateChanFlags) [33]byte {
|
||||
|
||||
var remotePubKey [33]byte
|
||||
switch {
|
||||
case chanFlags&lnwire.ChanUpdateDirection == 0:
|
||||
remotePubKey = chanInfo.NodeKey2Bytes
|
||||
case chanFlags&lnwire.ChanUpdateDirection == 1:
|
||||
remotePubKey = chanInfo.NodeKey1Bytes
|
||||
}
|
||||
|
||||
return remotePubKey
|
||||
}
|
||||
|
||||
// processRejectedEdge examines a rejected edge to see if we can extract any
|
||||
// new announcements from it. An edge will get rejected if we already added
|
||||
// the same edge without AuthProof to the graph. If the received announcement
|
||||
@ -1400,7 +1408,7 @@ func (d *AuthenticatedGossiper) processRejectedEdge(
|
||||
|
||||
// We'll then create then validate the new fully assembled
|
||||
// announcement.
|
||||
chanAnn, e1Ann, e2Ann, err := CreateChanAnnouncement(
|
||||
chanAnn, e1Ann, e2Ann, err := netann.CreateChanAnnouncement(
|
||||
proof, chanInfo, e1, e2,
|
||||
)
|
||||
if err != nil {
|
||||
@ -2157,7 +2165,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
||||
msg.ChannelID,
|
||||
peerID)
|
||||
|
||||
chanAnn, _, _, err := CreateChanAnnouncement(
|
||||
chanAnn, _, _, err := netann.CreateChanAnnouncement(
|
||||
chanInfo.AuthProof, chanInfo,
|
||||
e1, e2,
|
||||
)
|
||||
@ -2240,7 +2248,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement(
|
||||
dbProof.BitcoinSig1Bytes = oppositeProof.BitcoinSignature.ToSignatureBytes()
|
||||
dbProof.BitcoinSig2Bytes = msg.BitcoinSignature.ToSignatureBytes()
|
||||
}
|
||||
chanAnn, e1Ann, e2Ann, err := CreateChanAnnouncement(
|
||||
chanAnn, e1Ann, e2Ann, err := netann.CreateChanAnnouncement(
|
||||
&dbProof, chanInfo, e1, e2,
|
||||
)
|
||||
if err != nil {
|
||||
@ -2445,42 +2453,23 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
|
||||
edge *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement,
|
||||
*lnwire.ChannelUpdate, error) {
|
||||
|
||||
// Make sure timestamp is always increased, such that our update gets
|
||||
// propagated.
|
||||
timestamp := time.Now().Unix()
|
||||
if timestamp <= edge.LastUpdate.Unix() {
|
||||
timestamp = edge.LastUpdate.Unix() + 1
|
||||
}
|
||||
edge.LastUpdate = time.Unix(timestamp, 0)
|
||||
// Parse the unsigned edge into a channel update.
|
||||
chanUpdate := netann.UnsignedChannelUpdateFromEdge(info, edge)
|
||||
|
||||
chanUpdate := &lnwire.ChannelUpdate{
|
||||
ChainHash: info.ChainHash,
|
||||
ShortChannelID: lnwire.NewShortChanIDFromInt(edge.ChannelID),
|
||||
Timestamp: uint32(timestamp),
|
||||
MessageFlags: edge.MessageFlags,
|
||||
ChannelFlags: edge.ChannelFlags,
|
||||
TimeLockDelta: edge.TimeLockDelta,
|
||||
HtlcMinimumMsat: edge.MinHTLC,
|
||||
HtlcMaximumMsat: edge.MaxHTLC,
|
||||
BaseFee: uint32(edge.FeeBaseMSat),
|
||||
FeeRate: uint32(edge.FeeProportionalMillionths),
|
||||
ExtraOpaqueData: edge.ExtraOpaqueData,
|
||||
}
|
||||
|
||||
// With the update applied, we'll generate a new signature over a
|
||||
// digest of the channel announcement itself.
|
||||
sig, err := SignAnnouncement(d.cfg.AnnSigner, d.selfKey, chanUpdate)
|
||||
// We'll generate a new signature over a digest of the channel
|
||||
// announcement itself and update the timestamp to ensure it propagate.
|
||||
err := netann.SignChannelUpdate(
|
||||
d.cfg.AnnSigner, d.selfKey, chanUpdate,
|
||||
netann.ChanUpdSetTimestamp,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Next, we'll set the new signature in place, and update the reference
|
||||
// in the backing slice.
|
||||
edge.SetSigBytes(sig.Serialize())
|
||||
chanUpdate.Signature, err = lnwire.NewSigFromSignature(sig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
edge.LastUpdate = time.Unix(int64(chanUpdate.Timestamp), 0)
|
||||
edge.SigBytes = chanUpdate.Signature.ToSignatureBytes()
|
||||
|
||||
// To ensure that our signature is valid, we'll verify it ourself
|
||||
// before committing it to the slice returned.
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/netann"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
"github.com/lightningnetwork/lnd/ticker"
|
||||
@ -550,7 +551,7 @@ func createNodeAnnouncement(priv *btcec.PrivateKey,
|
||||
}
|
||||
|
||||
signer := mockSigner{priv}
|
||||
sig, err := SignAnnouncement(&signer, priv.PubKey(), a)
|
||||
sig, err := netann.SignAnnouncement(&signer, priv.PubKey(), a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -602,7 +603,7 @@ func createUpdateAnnouncement(blockHeight uint32,
|
||||
func signUpdate(nodeKey *btcec.PrivateKey, a *lnwire.ChannelUpdate) error {
|
||||
pub := nodeKey.PubKey()
|
||||
signer := mockSigner{nodeKey}
|
||||
sig, err := SignAnnouncement(&signer, pub, a)
|
||||
sig, err := netann.SignAnnouncement(&signer, pub, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -644,7 +645,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
|
||||
|
||||
pub := nodeKeyPriv1.PubKey()
|
||||
signer := mockSigner{nodeKeyPriv1}
|
||||
sig, err := SignAnnouncement(&signer, pub, a)
|
||||
sig, err := netann.SignAnnouncement(&signer, pub, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -655,7 +656,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
|
||||
|
||||
pub = nodeKeyPriv2.PubKey()
|
||||
signer = mockSigner{nodeKeyPriv2}
|
||||
sig, err = SignAnnouncement(&signer, pub, a)
|
||||
sig, err = netann.SignAnnouncement(&signer, pub, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -666,7 +667,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
|
||||
|
||||
pub = bitcoinKeyPriv1.PubKey()
|
||||
signer = mockSigner{bitcoinKeyPriv1}
|
||||
sig, err = SignAnnouncement(&signer, pub, a)
|
||||
sig, err = netann.SignAnnouncement(&signer, pub, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -677,7 +678,7 @@ func createRemoteChannelAnnouncement(blockHeight uint32,
|
||||
|
||||
pub = bitcoinKeyPriv2.PubKey()
|
||||
signer = mockSigner{bitcoinKeyPriv2}
|
||||
sig, err = SignAnnouncement(&signer, pub, a)
|
||||
sig, err = netann.SignAnnouncement(&signer, pub, a)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1,154 +0,0 @@
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// CreateChanAnnouncement is a helper function which creates all channel
|
||||
// announcements given the necessary channel related database items. This
|
||||
// function is used to transform out database structs into the corresponding wire
|
||||
// structs for announcing new channels to other peers, or simply syncing up a
|
||||
// peer's initial routing table upon connect.
|
||||
func CreateChanAnnouncement(chanProof *channeldb.ChannelAuthProof,
|
||||
chanInfo *channeldb.ChannelEdgeInfo,
|
||||
e1, e2 *channeldb.ChannelEdgePolicy) (*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.
|
||||
chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID)
|
||||
chanAnn := &lnwire.ChannelAnnouncement{
|
||||
ShortChannelID: chanID,
|
||||
NodeID1: chanInfo.NodeKey1Bytes,
|
||||
NodeID2: chanInfo.NodeKey2Bytes,
|
||||
ChainHash: chanInfo.ChainHash,
|
||||
BitcoinKey1: chanInfo.BitcoinKey1Bytes,
|
||||
BitcoinKey2: chanInfo.BitcoinKey2Bytes,
|
||||
Features: lnwire.NewRawFeatureVector(),
|
||||
ExtraOpaqueData: chanInfo.ExtraOpaqueData,
|
||||
}
|
||||
|
||||
var err error
|
||||
chanAnn.BitcoinSig1, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.BitcoinSig1Bytes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
chanAnn.BitcoinSig2, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.BitcoinSig2Bytes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
chanAnn.NodeSig1, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.NodeSig1Bytes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
chanAnn.NodeSig2, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.NodeSig2Bytes,
|
||||
)
|
||||
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 = &lnwire.ChannelUpdate{
|
||||
ChainHash: chanInfo.ChainHash,
|
||||
ShortChannelID: chanID,
|
||||
Timestamp: uint32(e1.LastUpdate.Unix()),
|
||||
MessageFlags: e1.MessageFlags,
|
||||
ChannelFlags: e1.ChannelFlags,
|
||||
TimeLockDelta: e1.TimeLockDelta,
|
||||
HtlcMinimumMsat: e1.MinHTLC,
|
||||
HtlcMaximumMsat: e1.MaxHTLC,
|
||||
BaseFee: uint32(e1.FeeBaseMSat),
|
||||
FeeRate: uint32(e1.FeeProportionalMillionths),
|
||||
ExtraOpaqueData: e1.ExtraOpaqueData,
|
||||
}
|
||||
edge1Ann.Signature, err = lnwire.NewSigFromRawSignature(e1.SigBytes)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
if e2 != nil {
|
||||
edge2Ann = &lnwire.ChannelUpdate{
|
||||
ChainHash: chanInfo.ChainHash,
|
||||
ShortChannelID: chanID,
|
||||
Timestamp: uint32(e2.LastUpdate.Unix()),
|
||||
MessageFlags: e2.MessageFlags,
|
||||
ChannelFlags: e2.ChannelFlags,
|
||||
TimeLockDelta: e2.TimeLockDelta,
|
||||
HtlcMinimumMsat: e2.MinHTLC,
|
||||
HtlcMaximumMsat: e2.MaxHTLC,
|
||||
BaseFee: uint32(e2.FeeBaseMSat),
|
||||
FeeRate: uint32(e2.FeeProportionalMillionths),
|
||||
ExtraOpaqueData: e2.ExtraOpaqueData,
|
||||
}
|
||||
edge2Ann.Signature, err = lnwire.NewSigFromRawSignature(e2.SigBytes)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return chanAnn, edge1Ann, edge2Ann, nil
|
||||
}
|
||||
|
||||
// SignAnnouncement is a helper function which is used to sign any outgoing
|
||||
// channel node node announcement messages.
|
||||
func SignAnnouncement(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
||||
msg lnwire.Message) (*btcec.Signature, error) {
|
||||
|
||||
var (
|
||||
data []byte
|
||||
err error
|
||||
)
|
||||
|
||||
switch m := msg.(type) {
|
||||
case *lnwire.ChannelAnnouncement:
|
||||
data, err = m.DataToSign()
|
||||
case *lnwire.ChannelUpdate:
|
||||
data, err = m.DataToSign()
|
||||
case *lnwire.NodeAnnouncement:
|
||||
data, err = m.DataToSign()
|
||||
default:
|
||||
return nil, errors.New("can't sign message " +
|
||||
"of this format")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("unable to get data to sign: %v", err)
|
||||
}
|
||||
|
||||
return signer.SignMessage(pubKey, data)
|
||||
}
|
||||
|
||||
// remotePubFromChanInfo returns the public key of the remote peer given a
|
||||
// ChannelEdgeInfo that describe a channel we have with them.
|
||||
func remotePubFromChanInfo(chanInfo *channeldb.ChannelEdgeInfo,
|
||||
chanFlags lnwire.ChanUpdateChanFlags) [33]byte {
|
||||
|
||||
var remotePubKey [33]byte
|
||||
switch {
|
||||
case chanFlags&lnwire.ChanUpdateDirection == 0:
|
||||
remotePubKey = chanInfo.NodeKey2Bytes
|
||||
case chanFlags&lnwire.ChanUpdateDirection == 1:
|
||||
remotePubKey = chanInfo.NodeKey1Bytes
|
||||
}
|
||||
|
||||
return remotePubKey
|
||||
}
|
@ -101,14 +101,6 @@ type NodeAnnouncement struct {
|
||||
ExtraOpaqueData []byte
|
||||
}
|
||||
|
||||
// UpdateNodeAnnAddrs is a functional option that allows updating the addresses
|
||||
// of the given node announcement.
|
||||
func UpdateNodeAnnAddrs(addrs []net.Addr) func(*NodeAnnouncement) {
|
||||
return func(nodeAnn *NodeAnnouncement) {
|
||||
nodeAnn.Addresses = addrs
|
||||
}
|
||||
}
|
||||
|
||||
// A compile time check to ensure NodeAnnouncement implements the
|
||||
// lnwire.Message interface.
|
||||
var _ Message = (*NodeAnnouncement)(nil)
|
||||
|
@ -527,7 +527,7 @@ func (m *ChanStatusManager) signAndSendNextUpdate(outpoint wire.OutPoint,
|
||||
|
||||
err = SignChannelUpdate(
|
||||
m.cfg.MessageSigner, m.cfg.OurPubKey, chanUpdate,
|
||||
ChannelUpdateSetDisable(disabled),
|
||||
ChanUpdSetDisable(disabled), ChanUpdSetTimestamp,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
81
netann/channel_announcement.go
Normal file
81
netann/channel_announcement.go
Normal file
@ -0,0 +1,81 @@
|
||||
package netann
|
||||
|
||||
import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// CreateChanAnnouncement is a helper function which creates all channel
|
||||
// announcements given the necessary channel related database items. This
|
||||
// function is used to transform out database structs into the corresponding wire
|
||||
// structs for announcing new channels to other peers, or simply syncing up a
|
||||
// peer's initial routing table upon connect.
|
||||
func CreateChanAnnouncement(chanProof *channeldb.ChannelAuthProof,
|
||||
chanInfo *channeldb.ChannelEdgeInfo,
|
||||
e1, e2 *channeldb.ChannelEdgePolicy) (*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.
|
||||
chanID := lnwire.NewShortChanIDFromInt(chanInfo.ChannelID)
|
||||
chanAnn := &lnwire.ChannelAnnouncement{
|
||||
ShortChannelID: chanID,
|
||||
NodeID1: chanInfo.NodeKey1Bytes,
|
||||
NodeID2: chanInfo.NodeKey2Bytes,
|
||||
ChainHash: chanInfo.ChainHash,
|
||||
BitcoinKey1: chanInfo.BitcoinKey1Bytes,
|
||||
BitcoinKey2: chanInfo.BitcoinKey2Bytes,
|
||||
Features: lnwire.NewRawFeatureVector(),
|
||||
ExtraOpaqueData: chanInfo.ExtraOpaqueData,
|
||||
}
|
||||
|
||||
var err error
|
||||
chanAnn.BitcoinSig1, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.BitcoinSig1Bytes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
chanAnn.BitcoinSig2, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.BitcoinSig2Bytes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
chanAnn.NodeSig1, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.NodeSig1Bytes,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
chanAnn.NodeSig2, err = lnwire.NewSigFromRawSignature(
|
||||
chanProof.NodeSig2Bytes,
|
||||
)
|
||||
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 {
|
||||
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
|
||||
}
|
@ -15,9 +15,9 @@ import (
|
||||
// lnwire.ChannelUpdate.
|
||||
type ChannelUpdateModifier func(*lnwire.ChannelUpdate)
|
||||
|
||||
// ChannelUpdateSetDisable sets the disabled channel flag if disabled is true,
|
||||
// and clears the bit otherwise.
|
||||
func ChannelUpdateSetDisable(disabled bool) ChannelUpdateModifier {
|
||||
// ChanUpdSetDisable is a functional option that sets the disabled channel flag
|
||||
// if disabled is true, and clears the bit otherwise.
|
||||
func ChanUpdSetDisable(disabled bool) ChannelUpdateModifier {
|
||||
return func(update *lnwire.ChannelUpdate) {
|
||||
if disabled {
|
||||
// Set the bit responsible for marking a channel as
|
||||
@ -31,6 +31,20 @@ func ChannelUpdateSetDisable(disabled bool) ChannelUpdateModifier {
|
||||
}
|
||||
}
|
||||
|
||||
// ChanUpdSetTimestamp is a functional option that sets the timestamp of the
|
||||
// update to the current time, or increments it if the timestamp is already in
|
||||
// the future.
|
||||
func ChanUpdSetTimestamp(update *lnwire.ChannelUpdate) {
|
||||
newTimestamp := uint32(time.Now().Unix())
|
||||
if newTimestamp <= update.Timestamp {
|
||||
// Increment the prior value to ensure the timestamp
|
||||
// monotonically increases, otherwise the update won't
|
||||
// propagate.
|
||||
newTimestamp = update.Timestamp + 1
|
||||
}
|
||||
update.Timestamp = newTimestamp
|
||||
}
|
||||
|
||||
// SignChannelUpdate applies the given modifiers to the passed
|
||||
// lnwire.ChannelUpdate, then signs the resulting update. The provided update
|
||||
// should be the most recent, valid update, otherwise the timestamp may not
|
||||
@ -45,23 +59,8 @@ func SignChannelUpdate(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
||||
modifier(update)
|
||||
}
|
||||
|
||||
// Update the message's timestamp to the current time. If the update's
|
||||
// current time is already in the future, we increment the prior value
|
||||
// to ensure the timestamps monotonically increase, otherwise the
|
||||
// update won't propagate.
|
||||
newTimestamp := uint32(time.Now().Unix())
|
||||
if newTimestamp <= update.Timestamp {
|
||||
newTimestamp = update.Timestamp + 1
|
||||
}
|
||||
update.Timestamp = newTimestamp
|
||||
|
||||
chanUpdateMsg, err := update.DataToSign()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the DER-encoded ECDSA signature over the message digest.
|
||||
sig, err := signer.SignMessage(pubKey, chanUpdateMsg)
|
||||
sig, err := SignAnnouncement(signer, pubKey, update)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -112,12 +111,12 @@ func ExtractChannelUpdate(ownerPubKey []byte,
|
||||
info.ChannelPoint)
|
||||
}
|
||||
|
||||
// ChannelUpdateFromEdge reconstructs a signed ChannelUpdate from the given edge
|
||||
// info and policy.
|
||||
func ChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo,
|
||||
policy *channeldb.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) {
|
||||
// UnsignedChannelUpdateFromEdge reconstructs an unsigned ChannelUpdate from the
|
||||
// given edge info and policy.
|
||||
func UnsignedChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo,
|
||||
policy *channeldb.ChannelEdgePolicy) *lnwire.ChannelUpdate {
|
||||
|
||||
update := &lnwire.ChannelUpdate{
|
||||
return &lnwire.ChannelUpdate{
|
||||
ChainHash: info.ChainHash,
|
||||
ShortChannelID: lnwire.NewShortChanIDFromInt(policy.ChannelID),
|
||||
Timestamp: uint32(policy.LastUpdate.Unix()),
|
||||
@ -130,6 +129,14 @@ func ChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo,
|
||||
FeeRate: uint32(policy.FeeProportionalMillionths),
|
||||
ExtraOpaqueData: policy.ExtraOpaqueData,
|
||||
}
|
||||
}
|
||||
|
||||
// ChannelUpdateFromEdge reconstructs a signed ChannelUpdate from the given edge
|
||||
// info and policy.
|
||||
func ChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo,
|
||||
policy *channeldb.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) {
|
||||
|
||||
update := UnsignedChannelUpdateFromEdge(info, policy)
|
||||
|
||||
var err error
|
||||
update.Signature, err = lnwire.NewSigFromRawSignature(policy.SigBytes)
|
||||
|
@ -103,6 +103,7 @@ func TestUpdateDisableFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, tc := range updateDisableTests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// Create the initial update, the only fields we are
|
||||
// concerned with in this test are the timestamp and the
|
||||
@ -127,7 +128,8 @@ func TestUpdateDisableFlag(t *testing.T) {
|
||||
// disabled or enabled as prescribed in the test case.
|
||||
err := netann.SignChannelUpdate(
|
||||
tc.signer, pubKey, newUpdate,
|
||||
netann.ChannelUpdateSetDisable(tc.disable),
|
||||
netann.ChanUpdSetDisable(tc.disable),
|
||||
netann.ChanUpdSetTimestamp,
|
||||
)
|
||||
|
||||
var fail bool
|
||||
|
60
netann/node_announcement.go
Normal file
60
netann/node_announcement.go
Normal file
@ -0,0 +1,60 @@
|
||||
package netann
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// NodeAnnModifier is a closure that makes in-place modifications to an
|
||||
// lnwire.NodeAnnouncement.
|
||||
type NodeAnnModifier func(*lnwire.NodeAnnouncement)
|
||||
|
||||
// NodeAnnSetAddrs is a functional option that allows updating the addresses of
|
||||
// the given node announcement.
|
||||
func NodeAnnSetAddrs(addrs []net.Addr) func(*lnwire.NodeAnnouncement) {
|
||||
return func(nodeAnn *lnwire.NodeAnnouncement) {
|
||||
nodeAnn.Addresses = addrs
|
||||
}
|
||||
}
|
||||
|
||||
// NodeAnnSetTimestamp is a functional option that sets the timestamp of the
|
||||
// announcement to the current time, or increments it if the timestamp is
|
||||
// already in the future.
|
||||
func NodeAnnSetTimestamp(nodeAnn *lnwire.NodeAnnouncement) {
|
||||
newTimestamp := uint32(time.Now().Unix())
|
||||
if newTimestamp <= nodeAnn.Timestamp {
|
||||
// Increment the prior value to ensure the timestamp
|
||||
// monotonically increases, otherwise the announcement won't
|
||||
// propagate.
|
||||
newTimestamp = nodeAnn.Timestamp + 1
|
||||
}
|
||||
nodeAnn.Timestamp = newTimestamp
|
||||
}
|
||||
|
||||
// SignNodeAnnouncement applies the given modifies to the passed
|
||||
// lnwire.NodeAnnouncement, then signs the resulting announcement. The provided
|
||||
// update should be the most recent, valid update, otherwise the timestamp may
|
||||
// not monotonically increase from the prior.
|
||||
func SignNodeAnnouncement(signer lnwallet.MessageSigner,
|
||||
pubKey *btcec.PublicKey, nodeAnn *lnwire.NodeAnnouncement,
|
||||
mods ...NodeAnnModifier) error {
|
||||
|
||||
// Apply the requested changes to the node announcement.
|
||||
for _, modifier := range mods {
|
||||
modifier(nodeAnn)
|
||||
}
|
||||
|
||||
// Create the DER-encoded ECDSA signature over the message digest.
|
||||
sig, err := SignAnnouncement(signer, pubKey, nodeAnn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Parse the DER-encoded signature into a fixed-size 64-byte array.
|
||||
nodeAnn.Signature, err = lnwire.NewSigFromSignature(sig)
|
||||
return err
|
||||
}
|
36
netann/sign.go
Normal file
36
netann/sign.go
Normal file
@ -0,0 +1,36 @@
|
||||
package netann
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
// SignAnnouncement signs any type of gossip message that is announced on the
|
||||
// network.
|
||||
func SignAnnouncement(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
|
||||
msg lnwire.Message) (*btcec.Signature, error) {
|
||||
|
||||
var (
|
||||
data []byte
|
||||
err error
|
||||
)
|
||||
|
||||
switch m := msg.(type) {
|
||||
case *lnwire.ChannelAnnouncement:
|
||||
data, err = m.DataToSign()
|
||||
case *lnwire.ChannelUpdate:
|
||||
data, err = m.DataToSign()
|
||||
case *lnwire.NodeAnnouncement:
|
||||
data, err = m.DataToSign()
|
||||
default:
|
||||
return nil, fmt.Errorf("can't sign %T message", m)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get data to sign: %v", err)
|
||||
}
|
||||
|
||||
return signer.SignMessage(pubKey, data)
|
||||
}
|
35
server.go
35
server.go
@ -651,7 +651,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
|
||||
|
||||
// With the announcement generated, we'll sign it to properly
|
||||
// authenticate the message on the network.
|
||||
authSig, err := discovery.SignAnnouncement(
|
||||
authSig, err := netann.SignAnnouncement(
|
||||
s.nodeSigner, s.identityPriv.PubKey(), nodeAnn,
|
||||
)
|
||||
if err != nil {
|
||||
@ -1657,7 +1657,7 @@ out:
|
||||
// announcement with the updated addresses and broadcast
|
||||
// it to our peers.
|
||||
newNodeAnn, err := s.genNodeAnnouncement(
|
||||
true, lnwire.UpdateNodeAnnAddrs(newAddrs),
|
||||
true, netann.NodeAnnSetAddrs(newAddrs),
|
||||
)
|
||||
if err != nil {
|
||||
srvrLog.Debugf("Unable to generate new node "+
|
||||
@ -2039,7 +2039,7 @@ func (s *server) initTorController() error {
|
||||
// announcement. If refresh is true, then the time stamp of the announcement
|
||||
// will be updated in order to ensure it propagates through the network.
|
||||
func (s *server) genNodeAnnouncement(refresh bool,
|
||||
updates ...func(*lnwire.NodeAnnouncement)) (lnwire.NodeAnnouncement, error) {
|
||||
modifiers ...netann.NodeAnnModifier) (lnwire.NodeAnnouncement, error) {
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
@ -2050,34 +2050,19 @@ func (s *server) genNodeAnnouncement(refresh bool,
|
||||
return *s.currentNodeAnn, nil
|
||||
}
|
||||
|
||||
// Now that we know we need to update our copy, we'll apply all the
|
||||
// function updates that'll mutate the current version of our node
|
||||
// announcement.
|
||||
for _, update := range updates {
|
||||
update(s.currentNodeAnn)
|
||||
}
|
||||
// Always update the timestamp when refreshing to ensure the update
|
||||
// propagates.
|
||||
modifiers = append(modifiers, netann.NodeAnnSetTimestamp)
|
||||
|
||||
// We'll now update the timestamp, ensuring that with each update, the
|
||||
// timestamp monotonically increases.
|
||||
newStamp := uint32(time.Now().Unix())
|
||||
if newStamp <= s.currentNodeAnn.Timestamp {
|
||||
newStamp = s.currentNodeAnn.Timestamp + 1
|
||||
}
|
||||
s.currentNodeAnn.Timestamp = newStamp
|
||||
|
||||
// Now that the announcement is fully updated, we'll generate a new
|
||||
// signature over the announcement to ensure nodes on the network
|
||||
// accepted the new authenticated announcement.
|
||||
sig, err := discovery.SignAnnouncement(
|
||||
// Otherwise, we'll sign a new update after applying all of the passed
|
||||
// modifiers.
|
||||
err := netann.SignNodeAnnouncement(
|
||||
s.nodeSigner, s.identityPriv.PubKey(), s.currentNodeAnn,
|
||||
modifiers...,
|
||||
)
|
||||
if err != nil {
|
||||
return lnwire.NodeAnnouncement{}, err
|
||||
}
|
||||
s.currentNodeAnn.Signature, err = lnwire.NewSigFromSignature(sig)
|
||||
if err != nil {
|
||||
return lnwire.NodeAnnouncement{}, err
|
||||
}
|
||||
|
||||
return *s.currentNodeAnn, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user