mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-22 14:22:37 +01:00
multi: move ChannelUpdate validate methods to netann
This commit is contained in:
parent
e07d23567c
commit
7bbf89625f
8 changed files with 82 additions and 82 deletions
|
@ -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)
|
||||
|
|
|
@ -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
2
go.mod
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue