lnwire+netann: update ChannelAnnouncement2 structure
What changed, and why it matters
This commit refactors how a new Lightning network message type (ChannelAnnouncement2) is encoded and decoded. Previously the message had a fixed signature field followed by a block of TLV data. Now the signature itself is placed inside the TLV stream, and the code distinguishes between fields that are covered by the signature and those that are not. The change is a protocol-structure update rather than a clear-cut bug fix, but it touches signature coverage and message parsing, which are security-sensitive areas.
Treat this as a protocol-compatibility and signature-correctness change. Review the corresponding BOLT/spec update to confirm the signed TLV ranges and default chain-hash behavior match the intended design. Run the new round-trip and signature-validation tests, and verify that any node receiving the old wire format handles it gracefully (or that the protocol version gates the change).
Security signals we found
Signature coverage boundary changed: signature now a TLV record in the signed range
Unknown TLV records in the signed range are retained for signature validation
New EncodeAllNonSigFields / DecodeNonSigTLVRecords helpers affect what bytes are hashed for signing
ChainHash defaulting to Bitcoin mainnet genesis hash when omitted could alter signed payload if logic is inconsistent
No explicit security bug or CVE mentioned in commit message
Evidence from the diff
The patch converts ChannelAnnouncement2 from a hybrid layout (raw signature + ExtraOpaqueData) into a ‘pure TLV’ layout where every field, including the Schnorr signature, is a TLV record. It introduces signed/unsigned TLV ranges, adds AllRecords/allNonSignatureRecordProducers, EncodeAllNonSigFields, and DecodeNonSigTLVRecords, and replaces DataToSign with lnwire.SerialiseFieldsToSign. Tests are updated to exercise unknown records inside the signed range and to ensure round-trip encoding preserves bytes. The commit does not state it fixes a vulnerability; it is framed as a structural update to align with the protocol spec.
Changed components
lnwire/channel_announcement_2.golnwire/channel_announcement_2_test.golnwire/test_message.golnwire/test_utils.gonetann/channel_announcement.gonetann/channel_announcement_test.goInspect captured patch +279 / −96
diff --git a/lnwire/channel_announcement_2.go b/lnwire/channel_announcement_2.go
index 95af69e..94474d9 100644
--- a/lnwire/channel_announcement_2.go
+++ b/lnwire/channel_announcement_2.go
@@ -12,9 +12,6 @@ import (
// ChannelAnnouncement2 message is used to announce the existence of a taproot
// channel between two peers in the network.
type ChannelAnnouncement2 struct {
- // Signature is a Schnorr signature over the TLV stream of the message.
- Signature Sig
-
// ChainHash denotes the target chain that this channel was opened
// within. This value should be the genesis hash of the target chain.
ChainHash tlv.RecordT[tlv.TlvType0, chainhash.Hash]
@@ -59,47 +56,107 @@ type ChannelAnnouncement2 struct {
// the funding output is a pure 2-of-2 MuSig aggregate public key.
MerkleRootHash tlv.OptionalRecordT[tlv.TlvType16, [32]byte]
- // ExtraOpaqueData is the set of data that was appended to this
- // message, some of which we may not actually know how to iterate or
- // parse. By holding onto this data, we ensure that we're able to
- // properly validate the set of signatures that cover these new fields,
- // and ensure we're able to make upgrades to the network in a forwards
- // compatible manner.
- ExtraOpaqueData ExtraOpaqueData
+ // Signature is a Schnorr signature over serialised signed-range TLV
+ // stream of the message.
+ Signature tlv.RecordT[tlv.TlvType160, Sig]
+
+ // Any extra fields in the signed range that we do not yet know about,
+ // but we need to keep them for signature validation and to produce a
+ // valid message.
+ ExtraSignedFields
}
-// Decode deserializes a serialized AnnounceSignatures1 stored in the passed
-// io.Reader observing the specified protocol version.
+// Encode serializes the target AnnounceSignatures1 into the passed io.Writer
+// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
-func (c *ChannelAnnouncement2) Decode(r io.Reader, _ uint32) error {
- err := ReadElement(r, &c.Signature)
- if err != nil {
- return err
- }
- c.Signature.ForceSchnorr()
+func (c *ChannelAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
+ return EncodePureTLVMessage(c, w)
+}
+
+// AllRecords returns all the TLV records for the message. This will include all
+// the records we know about along with any that we don't know about but that
+// fall in the signed TLV range.
+//
+// NOTE: this is part of the PureTLVMessage interface.
+func (c *ChannelAnnouncement2) AllRecords() []tlv.Record {
+ recordProducers := append(
+ c.allNonSignatureRecordProducers(), &c.Signature,
+ )
- return c.DecodeTLVRecords(r)
+ return ProduceRecordsSorted(recordProducers...)
}
-// DecodeTLVRecords decodes only the TLV section of the message.
-func (c *ChannelAnnouncement2) DecodeTLVRecords(r io.Reader) error {
- // First extract into extra opaque data.
- var tlvRecords ExtraOpaqueData
- if err := ReadElements(r, &tlvRecords); err != nil {
- return err
+// allNonSignatureRecordProducers returns all the TLV record producers for the
+// message except the signature record producer.
+//
+//nolint:ll
+func (c *ChannelAnnouncement2) allNonSignatureRecordProducers() []tlv.RecordProducer {
+ // The chain-hash record is only included if it is _not_ equal to the
+ // bitcoin mainnet genisis block hash.
+ var recordProducers []tlv.RecordProducer
+ if !c.ChainHash.Val.IsEqual(chaincfg.MainNetParams.GenesisHash) {
+ hash := tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
+ hash.Val = c.ChainHash.Val
+
+ recordProducers = append(recordProducers, &hash)
}
+ recordProducers = append(recordProducers,
+ &c.Features, &c.ShortChannelID, &c.Capacity, &c.NodeID1,
+ &c.NodeID2,
+ )
+
+ c.BitcoinKey1.WhenSome(func(key tlv.RecordT[tlv.TlvType12, [33]byte]) {
+ recordProducers = append(recordProducers, &key)
+ })
+
+ c.BitcoinKey2.WhenSome(func(key tlv.RecordT[tlv.TlvType14, [33]byte]) {
+ recordProducers = append(recordProducers, &key)
+ })
+
+ c.MerkleRootHash.WhenSome(
+ func(hash tlv.RecordT[tlv.TlvType16, [32]byte]) {
+ recordProducers = append(recordProducers, &hash)
+ },
+ )
+
+ recordProducers = append(recordProducers, RecordsAsProducers(
+ tlv.MapToRecords(c.ExtraSignedFields),
+ )...)
+
+ return recordProducers
+}
+
+// Decode deserializes a serialized AnnounceSignatures1 stored in the passed
+// io.Reader observing the specified protocol version.
+//
+// This is part of the lnwire.Message interface.
+func (c *ChannelAnnouncement2) Decode(r io.Reader, _ uint32) error {
var (
chainHash = tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
btcKey1 = tlv.ZeroRecordT[tlv.TlvType12, [33]byte]()
btcKey2 = tlv.ZeroRecordT[tlv.TlvType14, [33]byte]()
merkleRootHash = tlv.ZeroRecordT[tlv.TlvType16, [32]byte]()
)
- typeMap, err := tlvRecords.ExtractRecords(
- &chainHash, &c.Features, &c.ShortChannelID, &c.Capacity,
- &c.NodeID1, &c.NodeID2, &btcKey1, &btcKey2, &merkleRootHash,
- )
+ stream, err := tlv.NewStream(ProduceRecordsSorted(
+ &chainHash,
+ &c.Features,
+ &c.ShortChannelID,
+ &c.Capacity,
+ &c.NodeID1,
+ &c.NodeID2,
+ &btcKey1,
+ &btcKey2,
+ &merkleRootHash,
+ &c.Signature,
+ )...)
+ if err != nil {
+ return err
+ }
+ c.Signature.Val.ForceSchnorr()
+
+ typeMap, err := stream.DecodeWithParsedTypesP2P(r)
if err != nil {
return err
}
@@ -122,68 +179,68 @@ func (c *ChannelAnnouncement2) DecodeTLVRecords(r io.Reader) error {
c.MerkleRootHash = tlv.SomeRecordT(merkleRootHash)
}
- if len(tlvRecords) != 0 {
- c.ExtraOpaqueData = tlvRecords
- }
+ c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
- return c.ExtraOpaqueData.ValidateTLV()
+ return nil
}
-// Encode serializes the target AnnounceSignatures1 into the passed io.Writer
-// observing the protocol version specified.
-//
-// This is part of the lnwire.Message interface.
-func (c *ChannelAnnouncement2) Encode(w *bytes.Buffer, _ uint32) error {
- _, err := w.Write(c.Signature.RawBytes())
+// DecodeNonSigTLVRecords decodes only the TLV section of the message.
+func (c *ChannelAnnouncement2) DecodeNonSigTLVRecords(r io.Reader) error {
+ var (
+ chainHash = tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
+ btcKey1 = tlv.ZeroRecordT[tlv.TlvType12, [33]byte]()
+ btcKey2 = tlv.ZeroRecordT[tlv.TlvType14, [33]byte]()
+ merkleRootHash = tlv.ZeroRecordT[tlv.TlvType16, [32]byte]()
+ )
+ stream, err := tlv.NewStream(ProduceRecordsSorted(
+ &chainHash,
+ &c.Features,
+ &c.ShortChannelID,
+ &c.Capacity,
+ &c.NodeID1,
+ &c.NodeID2,
+ &btcKey1,
+ &btcKey2,
+ &merkleRootHash,
+ )...)
if err != nil {
return err
}
- _, err = c.DataToSign()
+
+ typeMap, err := stream.DecodeWithParsedTypesP2P(r)
if err != nil {
return err
}
- return WriteBytes(w, c.ExtraOpaqueData)
-}
+ // By default, the chain-hash is the bitcoin mainnet genesis block hash.
+ c.ChainHash.Val = *chaincfg.MainNetParams.GenesisHash
+ if _, ok := typeMap[c.ChainHash.TlvType()]; ok {
+ c.ChainHash.Val = chainHash.Val
+ }
-// DataToSign encodes the data to be signed into the ExtraOpaqueData member and
-// returns it.
-func (c *ChannelAnnouncement2) DataToSign() ([]byte, error) {
- // The chain-hash record is only included if it is _not_ equal to the
- // bitcoin mainnet genisis block hash.
- var recordProducers []tlv.RecordProducer
- if !c.ChainHash.Val.IsEqual(chaincfg.MainNetParams.GenesisHash) {
- hash := tlv.ZeroRecordT[tlv.TlvType0, [32]byte]()
- hash.Val = c.ChainHash.Val
+ if _, ok := typeMap[c.BitcoinKey1.TlvType()]; ok {
+ c.BitcoinKey1 = tlv.SomeRecordT(btcKey1)
+ }
- recordProducers = append(recordProducers, &hash)
+ if _, ok := typeMap[c.BitcoinKey2.TlvType()]; ok {
+ c.BitcoinKey2 = tlv.SomeRecordT(btcKey2)
}
- recordProducers = append(recordProducers,
- &c.Features, &c.ShortChannelID, &c.Capacity, &c.NodeID1,
- &c.NodeID2,
- )
+ if _, ok := typeMap[c.MerkleRootHash.TlvType()]; ok {
+ c.MerkleRootHash = tlv.SomeRecordT(merkleRootHash)
+ }
- c.BitcoinKey1.WhenSome(func(key tlv.RecordT[tlv.TlvType12, [33]byte]) {
- recordProducers = append(recordProducers, &key)
- })
+ c.ExtraSignedFields = ExtraSignedFieldsFromTypeMap(typeMap)
- c.BitcoinKey2.WhenSome(func(key tlv.RecordT[tlv.TlvType14, [33]byte]) {
- recordProducers = append(recordProducers, &key)
- })
+ return nil
+}
- c.MerkleRootHash.WhenSome(
- func(hash tlv.RecordT[tlv.TlvType16, [32]byte]) {
- recordProducers = append(recordProducers, &hash)
- },
+// EncodeAllNonSigFields encodes the entire message to the given writer but
+// excludes the signature field.
+func (c *ChannelAnnouncement2) EncodeAllNonSigFields(w io.Writer) error {
+ return EncodeRecordsTo(
+ w, ProduceRecordsSorted(c.allNonSignatureRecordProducers()...),
)
-
- err := EncodeMessageExtraData(&c.ExtraOpaqueData, recordProducers...)
- if err != nil {
- return nil, err
- }
-
- return c.ExtraOpaqueData, nil
}
// MsgType returns the integer uniquely identifying this message type on the
@@ -209,6 +266,10 @@ var _ Message = (*ChannelAnnouncement2)(nil)
// lnwire.SizeableMessage interface.
var _ SizeableMessage = (*ChannelAnnouncement2)(nil)
+// A compile time check to ensure ChannelAnnouncement2 implements the
+// lnwire.PureTLVMessage interface.
+var _ PureTLVMessage = (*ChannelAnnouncement2)(nil)
+
// Node1KeyBytes returns the bytes representing the public key of node 1 in the
// channel.
//
diff --git a/lnwire/channel_announcement_2_test.go b/lnwire/channel_announcement_2_test.go
new file mode 100644
index 0000000..40d255b
--- /dev/null
+++ b/lnwire/channel_announcement_2_test.go
@@ -0,0 +1,103 @@
+package lnwire
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/lightningnetwork/lnd/tlv"
+ "github.com/stretchr/testify/require"
+)
+
+// TestChanAnn2EncodeDecode tests the encoding and decoding of the
+// ChannelAnnouncement2 message using hardcoded byte slices.
+func TestChanAnn2EncodeDecode(t *testing.T) {
+ t.Parallel()
+
+ // We'll create a raw byte stream that represents a valid
+ // ChannelAnnouncement2 message with various known and unknown fields in
+ // the signed TLV ranges along with the signature in the unsigned range.
+ rawBytes := []byte{
+ // ChainHash record (optional, not mainnet).
+ 0x00, // type.
+ 0x20, // length.
+ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+ 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+
+ // Features record.
+ 0x02, // type.
+ 0x02, // length.
+ 0x1, 0x2, // value.
+
+ // ShortChannelID record.
+ 0x04, // type.
+ 0x08, // length.
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x2, 0x0, 0x3, // value.
+
+ // Unknown TLV record.
+ 0x05, // type.
+ 0x02, // length.
+ 0xab, 0xcd, // value.
+
+ // Capacity record.
+ 0x06, // type.
+ 0x08, // length.
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x86, 0xa0, // value: 100000.
+
+ // NodeID1 record.
+ 0x08, // type.
+ 0x21, // length.
+ 0x2, 0x28, 0xf2, 0xaf, 0xa, 0xbe, 0x32, 0x24, 0x3, 0x48, 0xf,
+ 0xb3, 0xee, 0x17, 0x2f, 0x7f, 0x16, 0x1, 0xe6, 0x7d, 0x1d, 0xa6,
+ 0xca, 0xd4, 0xb, 0x54, 0xc4, 0x46, 0x8d, 0x48, 0x23, 0x6c, 0x39,
+
+ // NodeID2 record.
+ 0x0a, // type.
+ 0x21, // length.
+ 0x3, 0x28, 0xf2, 0xaf, 0xa, 0xbe, 0x32, 0x24, 0x3, 0x48, 0xf,
+ 0xb3, 0xee, 0x17, 0x2f, 0x7f, 0x16, 0x1, 0xe6, 0x7d, 0x1d, 0xa6,
+ 0xca, 0xd4, 0xb, 0x54, 0xc4, 0x46, 0x8d, 0x48, 0x23, 0x6c, 0x39,
+
+ // Unknown TLV record.
+ 0x6f, // type.
+ 0x2, // length.
+ 0x79, 0x79, // value.
+
+ // Signature.
+ 0xa0, // type.
+ 0x40, // length.
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
+ 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
+ 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+ 0x3f, // value.
+ }
+ secondSignedRangeType := new(bytes.Buffer)
+ var buf [8]byte
+ err := tlv.WriteVarInt(
+ secondSignedRangeType, pureTLVSignedSecondRangeStart+1, &buf,
+ )
+ require.NoError(t, err)
+ rawBytes = append(rawBytes, secondSignedRangeType.Bytes()...) // type.
+ rawBytes = append(rawBytes, []byte{
+ 0x02, // length.
+ 0x79, 0x79, // value.
+ }...)
+
+ // Now, create a new empty message and decode the raw bytes into it.
+ msg := &ChannelAnnouncement2{}
+ r := bytes.NewReader(rawBytes)
+ err = msg.Decode(r, 0)
+ require.NoError(t, err)
+
+ // Next, encode the message back into a new byte buffer.
+ var b bytes.Buffer
+ err = msg.Encode(&b, 0)
+ require.NoError(t, err)
+
+ // The re-encoded bytes should be exactly the same as the original raw
+ // bytes.
+ require.Equal(t, rawBytes, b.Bytes())
+}
diff --git a/lnwire/test_message.go b/lnwire/test_message.go
index 7eb712b..8e2e46b 100644
--- a/lnwire/test_message.go
+++ b/lnwire/test_message.go
@@ -213,7 +213,6 @@ func (c *ChannelAnnouncement2) RandTestMessage(t *rapid.T) Message {
copy(chainHashObj[:], chainHash[:])
msg := &ChannelAnnouncement2{
- Signature: RandSignature(t),
ChainHash: tlv.NewPrimitiveRecord[tlv.TlvType0, chainhash.Hash](
chainHashObj,
),
@@ -232,10 +231,16 @@ func (c *ChannelAnnouncement2) RandTestMessage(t *rapid.T) Message {
NodeID2: tlv.NewPrimitiveRecord[tlv.TlvType10, [33]byte](
nodeID2,
),
- ExtraOpaqueData: RandExtraOpaqueData(t, nil),
+ ExtraSignedFields: make(map[uint64][]byte),
}
- msg.Signature.ForceSchnorr()
+ msg.Signature.Val = RandSignature(t)
+ msg.Signature.Val.ForceSchnorr()
+
+ randRecs, _ := RandSignedRangeRecords(t)
+ if len(randRecs) > 0 {
+ msg.ExtraSignedFields = ExtraSignedFields(randRecs)
+ }
// Randomly include optional fields
if rapid.Bool().Draw(t, "includeBitcoinKey1") {
@@ -411,7 +416,7 @@ func (a *ChannelUpdate1) RandTestMessage(t *rapid.T) Message {
// include an inbound fee, then we will also set the record in the
// extra opaque data.
var (
- customRecords, _ = RandCustomRecords(t, nil, false)
+ customRecords, _ = RandCustomRecords(t, nil)
inboundFee tlv.OptionalRecordT[tlv.TlvType55555, Fee]
)
includeInboundFee := rapid.Bool().Draw(t, "includeInboundFee")
@@ -728,7 +733,7 @@ var _ TestMessage = (*CommitSig)(nil)
//
// This is part of the TestMessage interface.
func (c *CommitSig) RandTestMessage(t *rapid.T) Message {
- cr, _ := RandCustomRecords(t, nil, true)
+ cr, _ := RandCustomRecords(t, nil)
sig := &CommitSig{
ChanID: RandChannelID(t),
CommitSig: RandSignature(t),
@@ -1606,7 +1611,7 @@ func (s *Shutdown) RandTestMessage(t *rapid.T) Message {
shutdownNonce = SomeShutdownNonce(RandMusig2Nonce(t))
}
- cr, _ := RandCustomRecords(t, nil, true)
+ cr, _ := RandCustomRecords(t, nil)
return &Shutdown{
ChannelID: RandChannelID(t),
@@ -1663,7 +1668,7 @@ func (c *UpdateAddHTLC) RandTestMessage(t *rapid.T) Message {
numRecords := rapid.IntRange(0, 5).Draw(t, "numRecords")
if numRecords > 0 {
- msg.CustomRecords, _ = RandCustomRecords(t, nil, true)
+ msg.CustomRecords, _ = RandCustomRecords(t, nil)
}
// 50/50 chance to add a blinding point
@@ -1744,7 +1749,7 @@ func (c *UpdateFulfillHTLC) RandTestMessage(t *rapid.T) Message {
PaymentPreimage: RandPaymentPreimage(t),
}
- cr, ignoreRecords := RandCustomRecords(t, nil, true)
+ cr, ignoreRecords := RandCustomRecords(t, nil)
msg.CustomRecords = cr
randData := RandExtraOpaqueData(t, ignoreRecords)
diff --git a/lnwire/test_utils.go b/lnwire/test_utils.go
index 07c9d79..4c88687 100644
--- a/lnwire/test_utils.go
+++ b/lnwire/test_utils.go
@@ -198,23 +198,37 @@ func RandNetAddrs(t *rapid.T) []net.Addr {
}
// RandCustomRecords generates random custom TLV records.
-func RandCustomRecords(t *rapid.T,
- ignoreRecords fn.Set[uint64],
- custom bool) (CustomRecords, fn.Set[uint64]) {
+func RandCustomRecords(t *rapid.T, ignoreRecords fn.Set[uint64]) (CustomRecords,
+ fn.Set[uint64]) {
- numRecords := rapid.IntRange(0, 5).Draw(t, "numCustomRecords")
+ customRecords, set := RandTLVRecords(
+ t, ignoreRecords, MinCustomRecordsTlvType,
+ )
+
+ // Validate the custom records as a sanity check.
+ require.NoError(t, customRecords.Validate())
+
+ return customRecords, set
+}
+
+// RandSignedRangeRecords generates a random set of signed records in the
+// second "signed" tlv range for pure TLV messages.
+func RandSignedRangeRecords(t *rapid.T) (CustomRecords, fn.Set[uint64]) {
+ return RandTLVRecords(t, nil, pureTLVSignedSecondRangeStart)
+}
+
+// RandTLVRecords generates custom TLV records.
+func RandTLVRecords(t *rapid.T, ignoreRecords fn.Set[uint64],
+ rangeStart int) (CustomRecords, fn.Set[uint64]) {
+
+ numRecords := rapid.IntRange(0, 5).Draw(t, "numRecords")
customRecords := make(CustomRecords)
if numRecords == 0 {
return nil, nil
}
- rangeStart := 0
- rangeStop := int(CustomTypeStart)
- if custom {
- rangeStart = 70_000
- rangeStop = 100_000
- }
+ rangeStop := rangeStart + 30_000
ignoreSet := fn.NewSet[uint64]()
for i := 0; i < numRecords; i++ {
@@ -258,7 +272,7 @@ func RandExtraOpaqueData(t *rapid.T,
ignoreRecords fn.Set[uint64]) ExtraOpaqueData {
// Make some random records.
- cRecords, _ := RandCustomRecords(t, ignoreRecords, false)
+ cRecords, _ := RandTLVRecords(t, ignoreRecords, 0)
if cRecords == nil {
return ExtraOpaqueData{}
}
diff --git a/netann/channel_announcement.go b/netann/channel_announcement.go
index 83ee55d..3f3e94a 100644
--- a/netann/channel_announcement.go
+++ b/netann/channel_announcement.go
@@ -203,7 +203,7 @@ func validateChannelAnn2(a *lnwire.ChannelAnnouncement2,
return err
}
- sig, err := a.Signature.ToSignature()
+ sig, err := a.Signature.Val.ToSignature()
if err != nil {
return err
}
@@ -278,7 +278,7 @@ func validateChannelAnn2(a *lnwire.ChannelAnnouncement2,
func ChanAnn2DigestToSign(a *lnwire.ChannelAnnouncement2) (*chainhash.Hash,
error) {
- data, err := a.DataToSign()
+ data, err := lnwire.SerialiseFieldsToSign(a)
if err != nil {
return nil, err
}
diff --git a/netann/channel_announcement_test.go b/netann/channel_announcement_test.go
index fbd2b2d..a4c1f53 100644
--- a/netann/channel_announcement_test.go
+++ b/netann/channel_announcement_test.go
@@ -159,7 +159,7 @@ func test4of4MuSig2ChanAnnouncement(t *testing.T) {
sig, err := lnwire.NewSigFromSignature(s)
require.NoError(t, err)
- ann.Signature = sig
+ ann.Signature.Val = sig
// Validate the announcement.
require.NoError(t, ValidateChannelAnn(ann, nil))
@@ -259,7 +259,7 @@ func test3of3MuSig2ChanAnnouncement(t *testing.T) {
sig, err := lnwire.NewSigFromSignature(s)
require.NoError(t, err)
- ann.Signature = sig
+ ann.Signature.Val = sig
// Validate the announcement.
require.NoError(t, ValidateChannelAnn(ann, fetchTx))
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.