Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
116a643
lnwallet: add new AuxFundingDesc struct
Roasbeef Apr 5, 2024
72beb79
lnwallet: use AuxFundingDesc to populate all custom chan info
Roasbeef Apr 5, 2024
84cc9a1
funding: create new AuxFundingController interface
Roasbeef Apr 5, 2024
65f54cb
config+serer: add AuxFundingController as top level cfg option
Roasbeef Apr 5, 2024
7144a1c
lnwallet: add TaprootInternalKey method to ShimIntent
Roasbeef Apr 16, 2024
bed4562
lnwallet: for PsbtIntent return the internal key in the POutput
Roasbeef Apr 16, 2024
7ec48a5
funding+lnwallet: only blind tapscript root early in funding flow
Roasbeef Apr 18, 2024
bcb6658
funding+lnwallet: finish hook up new aux funding flow
Roasbeef Apr 18, 2024
5c854a2
multi: add tapscript root to gossip message
guggero May 17, 2024
0b64b80
funding: inform aux controller about channel ready/finalize
guggero May 17, 2024
aa0c680
lnwallet: add new AuxSigner interface to mirror SigPool
Roasbeef Apr 9, 2024
953fb07
lnwallet: allow read-only access to HtlcView's HTLCs
guggero Sep 13, 2024
f52a163
lnwallet: clarify usage of cancel and response channels
guggero Sep 11, 2024
1e85c50
lnwallet: add WithAuxSigner option to channel
Roasbeef Apr 9, 2024
bd84fd2
lnwire: add custom records field to type `CommitSig`
guggero Sep 2, 2024
83fdbda
multi: obtain+verify aux sigs for all second level HTLCs
Roasbeef Apr 9, 2024
ea83300
lnwallet: sort sig jobs before submission
jharveyb Sep 8, 2024
5e1a98c
lnrpc+rpcserver: add and populate custom channel data
guggero May 17, 2024
d49da57
lnd: add aux data parser
guggero May 17, 2024
cdc3a4a
channeldb: add NextHeight, fix formatting
guggero May 27, 2024
52e50d8
htlcswitch: override amount check on custom records
guggero May 23, 2024
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
245 changes: 245 additions & 0 deletions lnwallet/aux_signer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
package lnwallet

import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tlv"
)

// AuxHtlcDescriptor is a struct that contains the information needed to sign or
// verify an HTLC for custom channels.
type AuxHtlcDescriptor struct {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, with this change then we aren't as blocked on some proposed refactors as we've separated concerns by using a new minimal struct.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The whole rebase on top of the first of these refactors just boiled down to making this struct. So not really that big of a deal, luckily.

// ChanID is the ChannelID of the LightningChannel that this
// paymentDescriptor belongs to. We track this here so we can
// reconstruct the Messages that this paymentDescriptor is built from.
ChanID lnwire.ChannelID

// RHash is the payment hash for this HTLC. The HTLC can be settled iff
// the preimage to this hash is presented.
RHash PaymentHash

// Timeout is the absolute timeout in blocks, after which this HTLC
// expires.
Timeout uint32

// Amount is the HTLC amount in milli-satoshis.
Amount lnwire.MilliSatoshi

// HtlcIndex is the index within the main update log for this HTLC.
// Entries within the log of type Add will have this field populated,
// as other entries will point to the entry via this counter.
//
// NOTE: This field will only be populated if EntryType is Add.
HtlcIndex uint64

// ParentIndex is the HTLC index of the entry that this update settles
// or times out.
//
// NOTE: This field will only be populated if EntryType is Fail or
// Settle.
ParentIndex uint64

// EntryType denotes the exact type of the paymentDescriptor. In the
// case of a Timeout, or Settle type, then the Parent field will point
// into the log to the HTLC being modified.
EntryType updateType

// CustomRecords also stores the set of optional custom records that
// may have been attached to a sent HTLC.
CustomRecords lnwire.CustomRecords

// addCommitHeight[Remote|Local] encodes the height of the commitment
// which included this HTLC on either the remote or local commitment
// chain. This value is used to determine when an HTLC is fully
// "locked-in".
addCommitHeightRemote uint64
addCommitHeightLocal uint64

// removeCommitHeight[Remote|Local] encodes the height of the
// commitment which removed the parent pointer of this
// paymentDescriptor either due to a timeout or a settle. Once both
// these heights are below the tail of both chains, the log entries can
// safely be removed.
removeCommitHeightRemote uint64
removeCommitHeightLocal uint64
}

// AddHeight returns the height at which the HTLC was added to the commitment
// chain. The height is returned based on the chain the HTLC is being added to
// (local or remote chain).
func (a *AuxHtlcDescriptor) AddHeight(
whoseCommitChain lntypes.ChannelParty) uint64 {

if whoseCommitChain.IsRemote() {
return a.addCommitHeightRemote
}

return a.addCommitHeightLocal
}

// RemoveHeight returns the height at which the HTLC was removed from the
// commitment chain. The height is returned based on the chain the HTLC is being
// removed from (local or remote chain).
func (a *AuxHtlcDescriptor) RemoveHeight(
whoseCommitChain lntypes.ChannelParty) uint64 {

if whoseCommitChain.IsRemote() {
return a.removeCommitHeightRemote
}

return a.removeCommitHeightLocal
}

// newAuxHtlcDescriptor creates a new AuxHtlcDescriptor from a payment
// descriptor.
func newAuxHtlcDescriptor(p *paymentDescriptor) AuxHtlcDescriptor {
return AuxHtlcDescriptor{
ChanID: p.ChanID,
RHash: p.RHash,
Timeout: p.Timeout,
Amount: p.Amount,
HtlcIndex: p.HtlcIndex,
ParentIndex: p.ParentIndex,
EntryType: p.EntryType,
CustomRecords: p.CustomRecords.Copy(),
addCommitHeightRemote: p.addCommitHeightRemote,
addCommitHeightLocal: p.addCommitHeightLocal,
removeCommitHeightRemote: p.removeCommitHeightRemote,
removeCommitHeightLocal: p.removeCommitHeightLocal,
}
}

// BaseAuxJob is a struct that contains the common fields that are shared among
// the aux sign/verify jobs.
type BaseAuxJob struct {
// OutputIndex is the output index of the HTLC on the commitment
// transaction being signed.
//
// NOTE: If the output is dust from the PoV of the commitment chain,
// then this value will be -1.
OutputIndex int32

// KeyRing is the commitment key ring that contains the keys needed to
// generate the second level HTLC signatures.
KeyRing CommitmentKeyRing

// HTLC is the HTLC that is being signed or verified.
HTLC AuxHtlcDescriptor

// Incoming is a boolean that indicates if the HTLC is incoming or
// outgoing.
Incoming bool

// CommitBlob is the commitment transaction blob that contains the aux
// information for this channel.
CommitBlob fn.Option[tlv.Blob]

// HtlcLeaf is the aux tap leaf that corresponds to the HTLC being
// signed/verified.
HtlcLeaf input.AuxTapLeaf
}

// AuxSigJob is a struct that contains all the information needed to sign an
// HTLC for custom channels.
type AuxSigJob struct {
// SignDesc is the sign desc for this HTLC.
SignDesc input.SignDescriptor

BaseAuxJob

// Resp is a channel that will be used to send the result of the sign
// job.
Resp chan AuxSigJobResp

// Cancel is a channel that should be closed if the caller wishes to
// abandon all pending sign jobs part of a single batch.
Cancel chan struct{}
}

// NewAuxSigJob creates a new AuxSigJob.
func NewAuxSigJob(sigJob SignJob, keyRing CommitmentKeyRing, incoming bool,
htlc AuxHtlcDescriptor, commitBlob fn.Option[tlv.Blob],
htlcLeaf input.AuxTapLeaf, cancelChan chan struct{}) AuxSigJob {

return AuxSigJob{
SignDesc: sigJob.SignDesc,
BaseAuxJob: BaseAuxJob{
OutputIndex: sigJob.OutputIndex,
KeyRing: keyRing,
HTLC: htlc,
Incoming: incoming,
CommitBlob: commitBlob,
HtlcLeaf: htlcLeaf,
},
Resp: make(chan AuxSigJobResp, 1),
Cancel: cancelChan,
}
}

// AuxSigJobResp is a struct that contains the result of a sign job.
type AuxSigJobResp struct {
// SigBlob is the signature blob that was generated for the HTLC. This
// is an opaque TLV field that may contain the signature and other data.
SigBlob fn.Option[tlv.Blob]

// HtlcIndex is the index of the HTLC that was signed.
HtlcIndex uint64

// Err is the error that occurred when executing the specified
// signature job. In the case that no error occurred, this value will
// be nil.
Err error
}

// AuxVerifyJob is a struct that contains all the information needed to verify
// an HTLC for custom channels.
type AuxVerifyJob struct {
// SigBlob is the signature blob that was generated for the HTLC. This
// is an opaque TLV field that may contain the signature and other data.
SigBlob fn.Option[tlv.Blob]

BaseAuxJob
}

// NewAuxVerifyJob creates a new AuxVerifyJob.
func NewAuxVerifyJob(sig fn.Option[tlv.Blob], keyRing CommitmentKeyRing,
incoming bool, htlc AuxHtlcDescriptor, commitBlob fn.Option[tlv.Blob],
htlcLeaf input.AuxTapLeaf) AuxVerifyJob {

return AuxVerifyJob{
SigBlob: sig,
BaseAuxJob: BaseAuxJob{
KeyRing: keyRing,
HTLC: htlc,
Incoming: incoming,
CommitBlob: commitBlob,
HtlcLeaf: htlcLeaf,
},
}
}

// AuxSigner is an interface that is used to sign and verify HTLCs for custom
// channels. It is similar to the existing SigPool, but uses opaque blobs to
// shuffle around signature information and other metadata.
type AuxSigner interface {
// SubmitSecondLevelSigBatch takes a batch of aux sign jobs and
// processes them asynchronously.
SubmitSecondLevelSigBatch(chanState AuxChanState, commitTx *wire.MsgTx,
sigJob []AuxSigJob) error

// PackSigs takes a series of aux signatures and packs them into a
// single blob that can be sent alongside the CommitSig messages.
PackSigs([]fn.Option[tlv.Blob]) fn.Result[fn.Option[tlv.Blob]]

// UnpackSigs takes a packed blob of signatures and returns the
// original signatures for each HTLC, keyed by HTLC index.
UnpackSigs(fn.Option[tlv.Blob]) fn.Result[[]fn.Option[tlv.Blob]]

// VerifySecondLevelSigs attempts to synchronously verify a batch of aux
// sig jobs.
VerifySecondLevelSigs(chanState AuxChanState, commitTx *wire.MsgTx,
verifyJob []AuxVerifyJob) error
}