Skip to content

Commit a6b56da

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 17e9758 commit a6b56da

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed

lnwallet/aux_signer.go

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

lnwallet/commitment.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,37 @@ 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 map[input.HtlcIndex]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]) (map[input.HtlcIndex]fn.Option[tlv.Blob],
858+
error) {
859+
860+
if signer.IsNone() {
861+
return nil, nil
862+
}
863+
864+
return signer.UnsafeFromSome().UnpackSigs(blob)
865+
}
866+
836867
// createUnsignedCommitmentTx generates the unsigned commitment transaction for
837868
// a commitment view and returns it as part of the unsignedCommitmentTx. The
838869
// passed in balances should be balances *before* subtracting any commitment

0 commit comments

Comments
 (0)