multi: move ChannelUpdate validate methods to netann

This commit is contained in:
Elle Mouton 2024-09-11 12:27:14 +02:00
parent e07d23567c
commit 7bbf89625f
No known key found for this signature in database
GPG key ID: D7D916376026F177
8 changed files with 82 additions and 82 deletions

View file

@ -5,7 +5,6 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/graph"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/routing/route"
@ -137,7 +136,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
if edge1 != nil {
// We don't want to send channel updates that don't
// conform to the spec (anymore).
err := graph.ValidateChannelUpdateFields(0, edge1)
err := netann.ValidateChannelUpdateFields(0, edge1)
if err != nil {
log.Errorf("not sending invalid channel "+
"update %v: %v", edge1, err)
@ -146,7 +145,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash,
}
}
if edge2 != nil {
err := graph.ValidateChannelUpdateFields(0, edge2)
err := netann.ValidateChannelUpdateFields(0, edge2)
if err != nil {
log.Errorf("not sending invalid channel "+
"update %v: %v", edge2, err)

View file

@ -2100,7 +2100,7 @@ func (d *AuthenticatedGossiper) processZombieUpdate(
"with chan_id=%v", msg.ShortChannelID)
}
err := graph.VerifyChannelUpdateSignature(msg, pubKey)
err := netann.VerifyChannelUpdateSignature(msg, pubKey)
if err != nil {
return fmt.Errorf("unable to verify channel "+
"update signature: %v", err)
@ -2237,7 +2237,7 @@ func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo,
// To ensure that our signature is valid, we'll verify it ourself
// before committing it to the slice returned.
err = graph.ValidateChannelUpdateAnn(
err = netann.ValidateChannelUpdateAnn(
d.selfKey, info.Capacity, chanUpdate,
)
if err != nil {
@ -3028,7 +3028,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg,
// Validate the channel announcement with the expected public key and
// channel capacity. In the case of an invalid channel update, we'll
// return an error to the caller and exit early.
err = graph.ValidateChannelUpdateAnn(pubKey, chanInfo.Capacity, upd)
err = netann.ValidateChannelUpdateAnn(pubKey, chanInfo.Capacity, upd)
if err != nil {
rErr := fmt.Errorf("unable to validate channel update "+
"announcement for short_chan_id=%v: %v",

2
go.mod
View file

@ -45,6 +45,7 @@ require (
github.com/lightningnetwork/lnd/tor v1.1.2
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796
github.com/miekg/dns v1.1.43
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.1
github.com/stretchr/testify v1.9.0
github.com/tv42/zbase32 v0.0.0-20160707012821-501572607d02
@ -135,7 +136,6 @@ require (
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/runc v1.1.12 // indirect
github.com/ory/dockertest/v3 v3.10.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect

View file

@ -2,12 +2,9 @@ package graph
import (
"bytes"
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/davecgh/go-spew/spew"
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/lnwire"
)
@ -48,70 +45,3 @@ func ValidateNodeAnn(a *lnwire.NodeAnnouncement) error {
return nil
}
// ValidateChannelUpdateAnn validates the channel update announcement by
// checking (1) that the included signature covers the announcement and has been
// signed by the node's private key, and (2) that the announcement's message
// flags and optional fields are sane.
func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, capacity btcutil.Amount,
a *lnwire.ChannelUpdate1) error {
if err := ValidateChannelUpdateFields(capacity, a); err != nil {
return err
}
return VerifyChannelUpdateSignature(a, pubKey)
}
// VerifyChannelUpdateSignature verifies that the channel update message was
// signed by the party with the given node public key.
func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate1,
pubKey *btcec.PublicKey) error {
data, err := msg.DataToSign()
if err != nil {
return fmt.Errorf("unable to reconstruct message data: %w", err)
}
dataHash := chainhash.DoubleHashB(data)
nodeSig, err := msg.Signature.ToSignature()
if err != nil {
return err
}
if !nodeSig.Verify(dataHash, pubKey) {
return fmt.Errorf("invalid signature for channel update %v",
spew.Sdump(msg))
}
return nil
}
// ValidateChannelUpdateFields validates a channel update's message flags and
// corresponding update fields.
func ValidateChannelUpdateFields(capacity btcutil.Amount,
msg *lnwire.ChannelUpdate1) error {
// The maxHTLC flag is mandatory.
if !msg.MessageFlags.HasMaxHtlc() {
return errors.Errorf("max htlc flag not set for channel "+
"update %v", spew.Sdump(msg))
}
maxHtlc := msg.HtlcMaximumMsat
if maxHtlc == 0 || maxHtlc < msg.HtlcMinimumMsat {
return errors.Errorf("invalid max htlc for channel "+
"update %v", spew.Sdump(msg))
}
// For light clients, the capacity will not be set so we'll skip
// checking whether the MaxHTLC value respects the channel's
// capacity.
capacityMsat := lnwire.NewMSatFromSatoshis(capacity)
if capacityMsat != 0 && maxHtlc > capacityMsat {
return errors.Errorf("max_htlc (%v) for channel update "+
"greater than capacity (%v)", maxHtlc, capacityMsat)
}
return nil
}

View file

@ -27,6 +27,7 @@ import (
"github.com/lightningnetwork/lnd/lnwallet/chanvalidate"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/multimutex"
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/routing/chainview"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/ticker"
@ -1484,7 +1485,7 @@ func (b *Builder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool {
return false
}
err = ValidateChannelUpdateAnn(pubKey, ch.Capacity, msg)
err = netann.ValidateChannelUpdateAnn(pubKey, ch.Capacity, msg)
if err != nil {
log.Errorf("Unable to validate channel update: %v", err)
return false

View file

@ -6,10 +6,14 @@ import (
"time"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/channeldb/models"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/pkg/errors"
)
// ErrUnableToExtractChanUpdate is returned when a channel update cannot be
@ -152,3 +156,70 @@ func ChannelUpdateFromEdge(info *models.ChannelEdgeInfo,
return update, nil
}
// ValidateChannelUpdateAnn validates the channel update announcement by
// checking (1) that the included signature covers the announcement and has been
// signed by the node's private key, and (2) that the announcement's message
// flags and optional fields are sane.
func ValidateChannelUpdateAnn(pubKey *btcec.PublicKey, capacity btcutil.Amount,
a *lnwire.ChannelUpdate1) error {
if err := ValidateChannelUpdateFields(capacity, a); err != nil {
return err
}
return VerifyChannelUpdateSignature(a, pubKey)
}
// VerifyChannelUpdateSignature verifies that the channel update message was
// signed by the party with the given node public key.
func VerifyChannelUpdateSignature(msg *lnwire.ChannelUpdate1,
pubKey *btcec.PublicKey) error {
data, err := msg.DataToSign()
if err != nil {
return fmt.Errorf("unable to reconstruct message data: %w", err)
}
dataHash := chainhash.DoubleHashB(data)
nodeSig, err := msg.Signature.ToSignature()
if err != nil {
return err
}
if !nodeSig.Verify(dataHash, pubKey) {
return fmt.Errorf("invalid signature for channel update %v",
spew.Sdump(msg))
}
return nil
}
// ValidateChannelUpdateFields validates a channel update's message flags and
// corresponding update fields.
func ValidateChannelUpdateFields(capacity btcutil.Amount,
msg *lnwire.ChannelUpdate1) error {
// The maxHTLC flag is mandatory.
if !msg.MessageFlags.HasMaxHtlc() {
return errors.Errorf("max htlc flag not set for channel "+
"update %v", spew.Sdump(msg))
}
maxHtlc := msg.HtlcMaximumMsat
if maxHtlc == 0 || maxHtlc < msg.HtlcMinimumMsat {
return errors.Errorf("invalid max htlc for channel "+
"update %v", spew.Sdump(msg))
}
// For light clients, the capacity will not be set so we'll skip
// checking whether the MaxHTLC value respects the channel's
// capacity.
capacityMsat := lnwire.NewMSatFromSatoshis(capacity)
if capacityMsat != 0 && maxHtlc > capacityMsat {
return errors.Errorf("max_htlc (%v) for channel update "+
"greater than capacity (%v)", maxHtlc, capacityMsat)
}
return nil
}

View file

@ -7,7 +7,6 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/lightningnetwork/lnd/graph"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
@ -182,7 +181,7 @@ func TestUpdateDisableFlag(t *testing.T) {
// Finally, validate the signature using the router's
// verification logic.
err = graph.VerifyChannelUpdateSignature(
err = netann.VerifyChannelUpdateSignature(
newUpdate, pubKey,
)
if err != nil {

View file

@ -8,9 +8,9 @@ import (
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/channeldb/models"
"github.com/lightningnetwork/lnd/graph"
"github.com/lightningnetwork/lnd/lnutils"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/routing/route"
)
@ -440,7 +440,7 @@ func (p *paymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate1,
pubKey *btcec.PublicKey, policy *models.CachedEdgePolicy) bool {
// Validate the message signature.
if err := graph.VerifyChannelUpdateSignature(msg, pubKey); err != nil {
if err := netann.VerifyChannelUpdateSignature(msg, pubKey); err != nil {
log.Errorf(
"Unable to validate channel update signature: %v", err,
)