Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion channeldb/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -2726,7 +2726,7 @@ func (l *LightningNode) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement,
return nodeAnn, nil
}

sig, err := lnwire.NewSigFromRawSignature(l.AuthSigBytes)
sig, err := lnwire.NewSigFromECDSARawSignature(l.AuthSigBytes)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions discovery/gossiper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2201,25 +2201,25 @@ func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo,
BitcoinKey2: info.BitcoinKey2Bytes,
ExtraOpaqueData: edge.ExtraOpaqueData,
}
chanAnn.NodeSig1, err = lnwire.NewSigFromRawSignature(
chanAnn.NodeSig1, err = lnwire.NewSigFromECDSARawSignature(
info.AuthProof.NodeSig1Bytes,
)
if err != nil {
return nil, nil, err
}
chanAnn.NodeSig2, err = lnwire.NewSigFromRawSignature(
chanAnn.NodeSig2, err = lnwire.NewSigFromECDSARawSignature(
info.AuthProof.NodeSig2Bytes,
)
if err != nil {
return nil, nil, err
}
chanAnn.BitcoinSig1, err = lnwire.NewSigFromRawSignature(
chanAnn.BitcoinSig1, err = lnwire.NewSigFromECDSARawSignature(
info.AuthProof.BitcoinSig1Bytes,
)
if err != nil {
return nil, nil, err
}
chanAnn.BitcoinSig2, err = lnwire.NewSigFromRawSignature(
chanAnn.BitcoinSig2, err = lnwire.NewSigFromECDSARawSignature(
info.AuthProof.BitcoinSig2Bytes,
)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions docs/release-notes/release-notes-0.17.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Release Notes

## BOLT Specs

* The `lnwire` library is now able to [parse messages for the new experimental
taproot channels spec proposal](https://github.com/lightningnetwork/lnd/pull/7331).

# Contributors (Alphabetical Order)

* Olaoluwa Osuntokun
10 changes: 8 additions & 2 deletions htlcswitch/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5374,9 +5374,15 @@ func TestChannelLinkFail(t *testing.T) {

// Flip a bit on the signature, rendering it
// invalid.
sig[19] ^= 1
sigCopy := sig.Copy()
copyBytes := sigCopy.RawBytes()
copyBytes[19] ^= 1
modifiedSig, err := lnwire.NewSigFromWireECDSA(
copyBytes,
)
require.NoError(t, err)
commitSig := &lnwire.CommitSig{
CommitSig: sig,
CommitSig: modifiedSig,
HtlcSigs: htlcSigs,
}

Expand Down
2 changes: 1 addition & 1 deletion lnrpc/routerrpc/router_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,7 @@ func marshallChannelUpdate(update *lnwire.ChannelUpdate) *lnrpc.ChannelUpdate {
}

return &lnrpc.ChannelUpdate{
Signature: update.Signature[:],
Signature: update.Signature.RawBytes(),
ChainHash: update.ChainHash[:],
ChanId: update.ShortChannelID.ToUint64(),
Timestamp: update.Timestamp,
Expand Down
2 changes: 1 addition & 1 deletion lnrpc/signrpc/signer_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ func (s *Server) VerifyMessage(_ context.Context,
}

// The signature must be fixed-size LN wire format encoded.
wireSig, err := lnwire.NewSigFromRawSignature(in.Signature)
wireSig, err := lnwire.NewSigFromECDSARawSignature(in.Signature)
if err != nil {
return nil, fmt.Errorf("failed to decode signature: %v", err)
}
Expand Down
10 changes: 6 additions & 4 deletions lnwallet/chancloser/chancloser.go
Original file line number Diff line number Diff line change
Expand Up @@ -785,16 +785,18 @@ func (c *ChanCloser) proposeCloseSigned(fee btcutil.Amount) (*lnwire.ClosingSign
return nil, err
}

// We'll note our last signature and proposed fee so when the remote party
// responds we'll be able to decide if we've agreed on fees or not.
// We'll note our last signature and proposed fee so when the remote
// party responds we'll be able to decide if we've agreed on fees or
// not.
c.lastFeeProposal = fee

parsedSig, err := lnwire.NewSigFromSignature(rawSig)
if err != nil {
return nil, err
}

chancloserLog.Infof("ChannelPoint(%v): proposing fee of %v sat to close "+
"chan", c.chanPoint, int64(fee))
chancloserLog.Infof("ChannelPoint(%v): proposing fee of %v sat to "+
"close chan", c.chanPoint, int64(fee))

// We'll assemble a ClosingSigned message using this information and return
// it to the caller so we can kick off the final stage of the channel
Expand Down
4 changes: 2 additions & 2 deletions lnwallet/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ type PaymentDescriptor struct {
// local node. This signature is generated by the remote node and
// stored by the local node in the case that local node needs to
// broadcast their commitment transaction.
sig *ecdsa.Signature
sig input.Signature

// addCommitHeight[Remote|Local] encodes the height of the commitment
// which included this HTLC on either the remote or local commitment
Expand Down Expand Up @@ -4333,7 +4333,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
var (
htlcIndex uint64
sigHash func() ([]byte, error)
sig *ecdsa.Signature
sig input.Signature
err error
)

Expand Down
6 changes: 5 additions & 1 deletion lnwallet/channel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5331,7 +5331,11 @@ func TestInvalidCommitSigError(t *testing.T) {

// Before the signature gets to Bob, we'll mutate it, such that the
// signature is now actually invalid.
aliceSig[0] ^= 88
aliceSigCopy := aliceSig.Copy()
aliceSigCopyBytes := aliceSigCopy.RawBytes()
aliceSigCopyBytes[0] ^= 88
aliceSig, err = lnwire.NewSigFromWireECDSA(aliceSigCopyBytes)
require.NoError(t, err)

// Bob should reject this new state, and return the proper error.
err = bobChannel.ReceiveNewCommitment(aliceSig, aliceHtlcSigs)
Expand Down
15 changes: 12 additions & 3 deletions lnwallet/rpcwallet/rpcwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,11 +453,20 @@ func (r *RPCKeyRing) SignMessage(keyLoc keychain.KeyLocator,
"signer instance: %v", err)
}

wireSig, err := lnwire.NewSigFromRawSignature(resp.Signature)
wireSig, err := lnwire.NewSigFromECDSARawSignature(resp.Signature)
if err != nil {
return nil, fmt.Errorf("error parsing raw signature: %v", err)
return nil, fmt.Errorf("unable to create sig: %w", err)
}
return wireSig.ToSignature()
sig, err := wireSig.ToSignature()
if err != nil {
return nil, fmt.Errorf("unable to parse sig: %w", err)
}
ecdsaSig, ok := sig.(*ecdsa.Signature)
if !ok {
return nil, fmt.Errorf("unexpected signature type: %T", sig)
}

return ecdsaSig, nil
}

// SignMessageCompact signs the given message, single or double SHA256 hashing
Expand Down
3 changes: 1 addition & 2 deletions lnwallet/sigpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"sync"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwire"
Expand Down Expand Up @@ -36,7 +35,7 @@ type VerifyJob struct {

// Sig is the raw signature generated using the above public key. This
// is the signature to be verified.
Sig *ecdsa.Signature
Sig input.Signature

// SigHash is a function closure generates the sighashes that the
// passed signature is known to have signed.
Expand Down
15 changes: 15 additions & 0 deletions lnwire/accept_channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ type AcceptChannel struct {
// type.
LeaseExpiry *LeaseExpiry

// LocalNonce is an optional field that transmits the
// local/verification nonce for a party. This nonce will be used to
// verify the very first commitment transaction signature.
// This will only be populated if the simple taproot channels type was
// negotiated.
LocalNonce *Musig2Nonce

// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
Expand Down Expand Up @@ -134,6 +141,9 @@ func (a *AcceptChannel) Encode(w *bytes.Buffer, pver uint32) error {
if a.LeaseExpiry != nil {
recordProducers = append(recordProducers, a.LeaseExpiry)
}
if a.LocalNonce != nil {
recordProducers = append(recordProducers, a.LocalNonce)
}
err := EncodeMessageExtraData(&a.ExtraData, recordProducers...)
if err != nil {
return err
Expand Down Expand Up @@ -238,9 +248,11 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error {
var (
chanType ChannelType
leaseExpiry LeaseExpiry
localNonce Musig2Nonce
)
typeMap, err := tlvRecords.ExtractRecords(
&a.UpfrontShutdownScript, &chanType, &leaseExpiry,
&localNonce,
)
if err != nil {
return err
Expand All @@ -253,6 +265,9 @@ func (a *AcceptChannel) Decode(r io.Reader, pver uint32) error {
if val, ok := typeMap[LeaseExpiryRecordType]; ok && val == nil {
a.LeaseExpiry = &leaseExpiry
}
if val, ok := typeMap[NonceRecordType]; ok && val == nil {
a.LocalNonce = &localNonce
}

a.ExtraData = tlvRecords

Expand Down
41 changes: 40 additions & 1 deletion lnwire/channel_reestablish.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/lightningnetwork/lnd/tlv"
)

// ChannelReestablish is a message sent between peers that have an existing
Expand Down Expand Up @@ -62,6 +63,13 @@ type ChannelReestablish struct {
// current un-revoked commitment transaction of the sending party.
LocalUnrevokedCommitPoint *btcec.PublicKey

// LocalNonce is an optional field that stores a local musig2 nonce.
// This will only be populated if the simple taproot channels type was
// negotiated.
//
// TODO(roasbeef): rename to verification nonce
LocalNonce *Musig2Nonce

// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
Expand Down Expand Up @@ -108,6 +116,16 @@ func (a *ChannelReestablish) Encode(w *bytes.Buffer, pver uint32) error {
if err := WritePublicKey(w, a.LocalUnrevokedCommitPoint); err != nil {
return err
}

recordProducers := make([]tlv.RecordProducer, 0, 1)
if a.LocalNonce != nil {
recordProducers = append(recordProducers, a.LocalNonce)
}
err := EncodeMessageExtraData(&a.ExtraData, recordProducers...)
if err != nil {
return err
}

return WriteBytes(w, a.ExtraData)
}

Expand Down Expand Up @@ -156,7 +174,28 @@ func (a *ChannelReestablish) Decode(r io.Reader, pver uint32) error {
return err
}

return a.ExtraData.Decode(r)
var tlvRecords ExtraOpaqueData
if err := ReadElements(r, &tlvRecords); err != nil {
return err
}

var localNonce Musig2Nonce
typeMap, err := tlvRecords.ExtractRecords(
&localNonce,
)
if err != nil {
return err
}

if val, ok := typeMap[NonceRecordType]; ok && val == nil {
a.LocalNonce = &localNonce
}

if len(tlvRecords) != 0 {
a.ExtraData = tlvRecords
}

return nil
}

// MsgType returns the integer uniquely identifying this message type on the
Expand Down
49 changes: 47 additions & 2 deletions lnwire/closing_signed.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"

"github.com/btcsuite/btcd/btcutil"
"github.com/lightningnetwork/lnd/tlv"
)

// ClosingSigned is sent by both parties to a channel once the channel is clear
Expand All @@ -29,6 +30,14 @@ type ClosingSigned struct {
// Signature is for the proposed channel close transaction.
Signature Sig

// PartialSig is used to transmit a musig2 extended partial signature
// that signs the latest fee offer. The nonce isn't sent along side, as
// that has already been sent in the initial shutdown message.
//
// NOTE: This field is only populated if a musig2 taproot channel is
// being signed for. In this case, the above Sig type MUST be blank.
PartialSig *PartialSig

// ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields.
Expand All @@ -55,16 +64,52 @@ var _ Message = (*ClosingSigned)(nil)
//
// This is part of the lnwire.Message interface.
func (c *ClosingSigned) Decode(r io.Reader, pver uint32) error {
return ReadElements(
r, &c.ChannelID, &c.FeeSatoshis, &c.Signature, &c.ExtraData,
err := ReadElements(
r, &c.ChannelID, &c.FeeSatoshis, &c.Signature,
)
if err != nil {
return err
}

var tlvRecords ExtraOpaqueData
if err := ReadElements(r, &tlvRecords); err != nil {
return err
}

var (
partialSig PartialSig
)
typeMap, err := tlvRecords.ExtractRecords(&partialSig)
if err != nil {
return err
}

// Set the corresponding TLV types if they were included in the stream.
if val, ok := typeMap[PartialSigRecordType]; ok && val == nil {
c.PartialSig = &partialSig
}

if len(tlvRecords) != 0 {
c.ExtraData = tlvRecords
}

return nil
}

// Encode serializes the target ClosingSigned into the passed io.Writer
// observing the protocol version specified.
//
// This is part of the lnwire.Message interface.
func (c *ClosingSigned) Encode(w *bytes.Buffer, pver uint32) error {
recordProducers := make([]tlv.RecordProducer, 0, 1)
if c.PartialSig != nil {
recordProducers = append(recordProducers, c.PartialSig)
}
err := EncodeMessageExtraData(&c.ExtraData, recordProducers...)
if err != nil {
return err
}

if err := WriteChannelID(w, c.ChannelID); err != nil {
return err
}
Expand Down
Loading