Skip to content

Commit 1763bfd

Browse files
Roasbeefguggero
authored andcommitted
lnwallet: add new AuxSigner interface to mirror SigPool
In this commit, we add a new aux signer interface that's meant to mirror the SigPool. If present, this'll be used to (maybe) obtain signatures for second level HTLCs for certain classes of custom channels.
1 parent d43b5f8 commit 1763bfd

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

lnwallet/aux_signer.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package lnwallet
2+
3+
import (
4+
"github.com/btcsuite/btcd/wire"
5+
"github.com/lightningnetwork/lnd/channeldb"
6+
"github.com/lightningnetwork/lnd/fn"
7+
"github.com/lightningnetwork/lnd/input"
8+
"github.com/lightningnetwork/lnd/tlv"
9+
)
10+
11+
// BaseAuxJob is a struct that contains the common fields that are shared among
12+
// the aux sign/verify jobs.
13+
type BaseAuxJob struct {
14+
// OutputIndex is the output index of the HTLC on the commitment
15+
// transaction being signed.
16+
OutputIndex int32
17+
18+
// KeyRing is the commitment key ring that contains the keys needed to
19+
// generate the second level HTLC signatures.
20+
KeyRing CommitmentKeyRing
21+
22+
// HTLC is the HTLC that is being signed or verified.
23+
HTLC PaymentDescriptor
24+
25+
// Incoming is a boolean that indicates if the HTLC is incoming or
26+
// outgoing.
27+
Incoming bool
28+
29+
// CommitBlob is the commitment transaction blob that contains the aux
30+
// information for this channel.
31+
CommitBlob fn.Option[tlv.Blob]
32+
33+
// HtlcLeaf is the aux tap leaf that corresponds to the HTLC being
34+
// signed/verified.
35+
HtlcLeaf input.AuxTapLeaf
36+
}
37+
38+
// AuxSigJob is a struct that contains all the information needed to sign an
39+
// HTLC for custom channels.
40+
type AuxSigJob struct {
41+
// SignDesc is the sign desc for this HTLC.
42+
SignDesc input.SignDescriptor
43+
44+
BaseAuxJob
45+
46+
// Resp is a channel that will be used to send the result of the sign
47+
// job.
48+
Resp chan AuxSigJobResp
49+
50+
// Cancel is a channel that should be closed if the caller wishes to
51+
// abandon all pending sign jobs part of a single batch.
52+
Cancel chan struct{}
53+
}
54+
55+
// NewAuxSigJob creates a new AuxSigJob.
56+
func NewAuxSigJob(sigJob SignJob, keyRing CommitmentKeyRing, incoming bool,
57+
htlc PaymentDescriptor, commitBlob fn.Option[tlv.Blob],
58+
htlcLeaf input.AuxTapLeaf, cancelChan chan struct{}) AuxSigJob {
59+
60+
return AuxSigJob{
61+
SignDesc: sigJob.SignDesc,
62+
BaseAuxJob: BaseAuxJob{
63+
OutputIndex: sigJob.OutputIndex,
64+
KeyRing: keyRing,
65+
HTLC: htlc,
66+
Incoming: incoming,
67+
CommitBlob: commitBlob,
68+
HtlcLeaf: htlcLeaf,
69+
},
70+
Resp: make(chan AuxSigJobResp, 1),
71+
Cancel: cancelChan,
72+
}
73+
}
74+
75+
// AuxSigJobResp is a struct that contains the result of a sign job.
76+
type AuxSigJobResp struct {
77+
// SigBlob is the signature blob that was generated for the HTLC. This
78+
// is an opaque TLV field that may contain the signature and other data.
79+
SigBlob fn.Option[tlv.Blob]
80+
81+
// HtlcIndex is the index of the HTLC that was signed.
82+
HtlcIndex uint64
83+
84+
// Err is the error that occurred when executing the specified
85+
// signature job. In the case that no error occurred, this value will
86+
// be nil.
87+
Err error
88+
}
89+
90+
// AuxVerifyJob is a struct that contains all the information needed to verify
91+
// an HTLC for custom channels.
92+
type AuxVerifyJob struct {
93+
// SigBlob is the signature blob that was generated for the HTLC. This
94+
// is an opaque TLV field that may contain the signature and other data.
95+
SigBlob fn.Option[tlv.Blob]
96+
97+
BaseAuxJob
98+
99+
// Cancel is a channel that should be closed if the caller wishes to
100+
// abandon the job.
101+
Cancel chan struct{}
102+
103+
// ErrResp is a channel that will be used to send the result of the
104+
// verify job.
105+
ErrResp chan error
106+
}
107+
108+
// NewAuxVerifyJob creates a new AuxVerifyJob.
109+
func NewAuxVerifyJob(sig fn.Option[tlv.Blob], keyRing CommitmentKeyRing,
110+
incoming bool, htlc PaymentDescriptor, commitBlob fn.Option[tlv.Blob],
111+
htlcLeaf input.AuxTapLeaf) AuxVerifyJob {
112+
113+
return AuxVerifyJob{
114+
SigBlob: sig,
115+
BaseAuxJob: BaseAuxJob{
116+
KeyRing: keyRing,
117+
HTLC: htlc,
118+
Incoming: incoming,
119+
CommitBlob: commitBlob,
120+
HtlcLeaf: htlcLeaf,
121+
},
122+
}
123+
}
124+
125+
// AuxSigner is an interface that is used to sign and verify HTLCs for custom
126+
// channels. It is similar to the existing SigPool, but uses opaque blobs to
127+
// shuffle around signature information and other metadata.
128+
type AuxSigner interface {
129+
// SubmitSecondLevelSigBatch takes a batch of aux sign jobs and
130+
// processes them asynchronously.
131+
SubmitSecondLevelSigBatch(chanState *channeldb.OpenChannel,
132+
commitTx *wire.MsgTx, sigJob []AuxSigJob) error
133+
134+
// PackSigs takes a series of aux signatures and packs them into a
135+
// single blob that can be sent alongside the CommitSig messages.
136+
PackSigs([]fn.Option[tlv.Blob]) (fn.Option[tlv.Blob], error)
137+
138+
// UnpackSigs takes a packed blob of signatures and returns the
139+
// original signatures for each HTLC, keyed by HTLC index.
140+
UnpackSigs(fn.Option[tlv.Blob]) ([]fn.Option[tlv.Blob], error)
141+
142+
// VerifySecondLevelSigs attempts to synchronously verify a batch of aux
143+
// sig jobs.
144+
VerifySecondLevelSigs(chanState *channeldb.OpenChannel,
145+
commitTx *wire.MsgTx, verifyJob []AuxVerifyJob) error
146+
}

lnwallet/commitment.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,36 @@ func updateAuxBlob(chanState *channeldb.OpenChannel,
833833
)
834834
}
835835

836+
// packSigs is a helper function that attempts to pack a series of aux
837+
// signatures and packs them into a single blob that can be sent alongside the
838+
// CommitSig messages.
839+
func packSigs(auxSigs []fn.Option[tlv.Blob],
840+
signer fn.Option[AuxSigner]) (tlv.Blob, error) {
841+
842+
if signer.IsNone() {
843+
return nil, nil
844+
}
845+
846+
blobOption, err := signer.UnsafeFromSome().PackSigs(auxSigs)
847+
if err != nil {
848+
return nil, fmt.Errorf("error packing aux sigs: %w", err)
849+
}
850+
851+
return blobOption.UnwrapOr(nil), nil
852+
}
853+
854+
// unpackSigs is a helper function that takes a packed blob of signatures and
855+
// returns the original signatures for each HTLC, keyed by HTLC index.
856+
func unpackSigs(blob fn.Option[tlv.Blob],
857+
signer fn.Option[AuxSigner]) ([]fn.Option[tlv.Blob], error) {
858+
859+
if signer.IsNone() {
860+
return nil, nil
861+
}
862+
863+
return signer.UnsafeFromSome().UnpackSigs(blob)
864+
}
865+
836866
// createUnsignedCommitmentTx generates the unsigned commitment transaction for
837867
// a commitment view and returns it as part of the unsignedCommitmentTx. The
838868
// passed in balances should be balances *before* subtracting any commitment

0 commit comments

Comments
 (0)