mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-29 03:01:52 +01:00
lnwallet: obtain+verify aux sigs for all second level HTLCs
In this commit, we start to use the new AuxSigner to obtain+verify aux sigs for all second level HTLCs. This is similar to the existing SigPool, but we'll only attempt to do this if the AuxSigner is present (won't be for most channels).
This commit is contained in:
parent
e9e10cc32f
commit
c0c511c686
@ -68,6 +68,10 @@ type Config struct {
|
|||||||
// leaves for certain custom channel types.
|
// leaves for certain custom channel types.
|
||||||
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
||||||
|
|
||||||
|
// AuxSigner is an optional signer that can be used to sign auxiliary
|
||||||
|
// leaves for certain custom channel types.
|
||||||
|
AuxSigner fn.Option[lnwallet.AuxSigner]
|
||||||
|
|
||||||
// BlockCache is the main cache for storing block information.
|
// BlockCache is the main cache for storing block information.
|
||||||
BlockCache *blockcache.BlockCache
|
BlockCache *blockcache.BlockCache
|
||||||
|
|
||||||
|
@ -165,10 +165,14 @@ type AuxComponents struct {
|
|||||||
MsgRouter fn.Option[protofsm.MsgRouter]
|
MsgRouter fn.Option[protofsm.MsgRouter]
|
||||||
|
|
||||||
// AuxFundingController is an optional controller that can be used to
|
// AuxFundingController is an optional controller that can be used to
|
||||||
// modify the way we handle certain custom chanenl types. It's also
|
// modify the way we handle certain custom channel types. It's also
|
||||||
// able to automatically handle new custom protocol messages related to
|
// able to automatically handle new custom protocol messages related to
|
||||||
// the funding process.
|
// the funding process.
|
||||||
AuxFundingController fn.Option[funding.AuxFundingController]
|
AuxFundingController fn.Option[funding.AuxFundingController]
|
||||||
|
|
||||||
|
// AuxSigner is an optional signer that can be used to sign auxiliary
|
||||||
|
// leaves for certain custom channel types.
|
||||||
|
AuxSigner fn.Option[lnwallet.AuxSigner]
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultWalletImpl is the default implementation of our normal, btcwallet
|
// DefaultWalletImpl is the default implementation of our normal, btcwallet
|
||||||
@ -575,6 +579,7 @@ func (d *DefaultWalletImpl) BuildWalletConfig(ctx context.Context,
|
|||||||
ChanStateDB: dbs.ChanStateDB.ChannelStateDB(),
|
ChanStateDB: dbs.ChanStateDB.ChannelStateDB(),
|
||||||
NeutrinoCS: neutrinoCS,
|
NeutrinoCS: neutrinoCS,
|
||||||
AuxLeafStore: aux.AuxLeafStore,
|
AuxLeafStore: aux.AuxLeafStore,
|
||||||
|
AuxSigner: aux.AuxSigner,
|
||||||
ActiveNetParams: d.cfg.ActiveNetParams,
|
ActiveNetParams: d.cfg.ActiveNetParams,
|
||||||
FeeURL: d.cfg.FeeURL,
|
FeeURL: d.cfg.FeeURL,
|
||||||
Dialer: func(addr string) (net.Conn, error) {
|
Dialer: func(addr string) (net.Conn, error) {
|
||||||
@ -727,6 +732,7 @@ func (d *DefaultWalletImpl) BuildChainControl(
|
|||||||
NetParams: *walletConfig.NetParams,
|
NetParams: *walletConfig.NetParams,
|
||||||
CoinSelectionStrategy: walletConfig.CoinSelectionStrategy,
|
CoinSelectionStrategy: walletConfig.CoinSelectionStrategy,
|
||||||
AuxLeafStore: partialChainControl.Cfg.AuxLeafStore,
|
AuxLeafStore: partialChainControl.Cfg.AuxLeafStore,
|
||||||
|
AuxSigner: partialChainControl.Cfg.AuxSigner,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The broadcast is already always active for neutrino nodes, so we
|
// The broadcast is already always active for neutrino nodes, so we
|
||||||
@ -906,10 +912,6 @@ type DatabaseInstances struct {
|
|||||||
// for native SQL queries for tables that already support it. This may
|
// for native SQL queries for tables that already support it. This may
|
||||||
// be nil if the use-native-sql flag was not set.
|
// be nil if the use-native-sql flag was not set.
|
||||||
NativeSQLStore *sqldb.BaseDB
|
NativeSQLStore *sqldb.BaseDB
|
||||||
|
|
||||||
// AuxLeafStore is an optional data source that can be used by custom
|
|
||||||
// channels to fetch+store various data.
|
|
||||||
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultDatabaseBuilder is a type that builds the default database backends
|
// DefaultDatabaseBuilder is a type that builds the default database backends
|
||||||
|
@ -221,6 +221,10 @@ type ChainArbitratorConfig struct {
|
|||||||
// AuxLeafStore is an optional store that can be used to store auxiliary
|
// AuxLeafStore is an optional store that can be used to store auxiliary
|
||||||
// leaves for certain custom channel types.
|
// leaves for certain custom channel types.
|
||||||
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
||||||
|
|
||||||
|
// AuxSigner is an optional signer that can be used to sign auxiliary
|
||||||
|
// leaves for certain custom channel types.
|
||||||
|
AuxSigner fn.Option[lnwallet.AuxSigner]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainArbitrator is a sub-system that oversees the on-chain resolution of all
|
// ChainArbitrator is a sub-system that oversees the on-chain resolution of all
|
||||||
@ -307,6 +311,9 @@ func (a *arbChannel) NewAnchorResolutions() (*lnwallet.AnchorResolutions,
|
|||||||
a.c.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
a.c.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
||||||
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
||||||
})
|
})
|
||||||
|
a.c.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
|
||||||
|
chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
|
||||||
|
})
|
||||||
|
|
||||||
chanMachine, err := lnwallet.NewLightningChannel(
|
chanMachine, err := lnwallet.NewLightningChannel(
|
||||||
a.c.cfg.Signer, channel, nil, chanOpts...,
|
a.c.cfg.Signer, channel, nil, chanOpts...,
|
||||||
@ -357,6 +364,9 @@ func (a *arbChannel) ForceCloseChan() (*lnwallet.LocalForceCloseSummary, error)
|
|||||||
a.c.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
a.c.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
||||||
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
||||||
})
|
})
|
||||||
|
a.c.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
|
||||||
|
chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
|
||||||
|
})
|
||||||
|
|
||||||
// Finally, we'll force close the channel completing
|
// Finally, we'll force close the channel completing
|
||||||
// the force close workflow.
|
// the force close workflow.
|
||||||
|
@ -548,6 +548,10 @@ type Config struct {
|
|||||||
// able to automatically handle new custom protocol messages related to
|
// able to automatically handle new custom protocol messages related to
|
||||||
// the funding process.
|
// the funding process.
|
||||||
AuxFundingController fn.Option[AuxFundingController]
|
AuxFundingController fn.Option[AuxFundingController]
|
||||||
|
|
||||||
|
// AuxSigner is an optional signer that can be used to sign auxiliary
|
||||||
|
// leaves for certain custom channel types.
|
||||||
|
AuxSigner fn.Option[lnwallet.AuxSigner]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manager acts as an orchestrator/bridge between the wallet's
|
// Manager acts as an orchestrator/bridge between the wallet's
|
||||||
@ -1077,6 +1081,9 @@ func (f *Manager) advanceFundingState(channel *channeldb.OpenChannel,
|
|||||||
f.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
f.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
||||||
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
||||||
})
|
})
|
||||||
|
f.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
|
||||||
|
chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
|
||||||
|
})
|
||||||
|
|
||||||
// We create the state-machine object which wraps the database state.
|
// We create the state-machine object which wraps the database state.
|
||||||
lnChannel, err := lnwallet.NewLightningChannel(
|
lnChannel, err := lnwallet.NewLightningChannel(
|
||||||
|
@ -2554,6 +2554,7 @@ func (l *channelLink) updateCommitTx() error {
|
|||||||
CommitSig: newCommit.CommitSig,
|
CommitSig: newCommit.CommitSig,
|
||||||
HtlcSigs: newCommit.HtlcSigs,
|
HtlcSigs: newCommit.HtlcSigs,
|
||||||
PartialSig: newCommit.PartialSig,
|
PartialSig: newCommit.PartialSig,
|
||||||
|
ExtraData: newCommit.AuxSigBlob,
|
||||||
}
|
}
|
||||||
l.cfg.Peer.SendMessage(false, commitSig)
|
l.cfg.Peer.SendMessage(false, commitSig)
|
||||||
|
|
||||||
|
@ -77,6 +77,9 @@ type AuxSigJobResp struct {
|
|||||||
// blob
|
// blob
|
||||||
SigBlob fn.Option[tlv.Blob]
|
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
|
// Err is the error that occurred when executing the specified
|
||||||
// signature job. In the case that no error occurred, this value will
|
// signature job. In the case that no error occurred, this value will
|
||||||
// be nil.
|
// be nil.
|
||||||
|
@ -3580,7 +3580,7 @@ func processFeeUpdate(feeUpdate *PaymentDescriptor, nextHeight uint64,
|
|||||||
func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
||||||
chanState *channeldb.OpenChannel, leaseExpiry uint32,
|
chanState *channeldb.OpenChannel, leaseExpiry uint32,
|
||||||
remoteCommitView *commitment,
|
remoteCommitView *commitment,
|
||||||
leafStore fn.Option[AuxLeafStore]) ([]SignJob, chan struct{}, error) {
|
leafStore fn.Option[AuxLeafStore]) ([]SignJob, []AuxSigJob, chan struct{}, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
isRemoteInitiator = !chanState.IsInitiator
|
isRemoteInitiator = !chanState.IsInitiator
|
||||||
@ -3597,9 +3597,10 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
// With the keys generated, we'll make a slice with enough capacity to
|
// With the keys generated, we'll make a slice with enough capacity to
|
||||||
// hold potentially all the HTLCs. The actual slice may be a bit
|
// hold potentially all the HTLCs. The actual slice may be a bit
|
||||||
// smaller (than its total capacity) and some HTLCs may be dust.
|
// smaller (than its total capacity) and some HTLCs may be dust.
|
||||||
numSigs := (len(remoteCommitView.incomingHTLCs) +
|
numSigs := len(remoteCommitView.incomingHTLCs) +
|
||||||
len(remoteCommitView.outgoingHTLCs))
|
len(remoteCommitView.outgoingHTLCs)
|
||||||
sigBatch := make([]SignJob, 0, numSigs)
|
sigBatch := make([]SignJob, 0, numSigs)
|
||||||
|
auxSigBatch := make([]AuxSigJob, 0, numSigs)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
cancelChan := make(chan struct{})
|
cancelChan := make(chan struct{})
|
||||||
@ -3609,7 +3610,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
*keyRing,
|
*keyRing,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to fetch aux leaves: "+
|
return nil, nil, nil, fmt.Errorf("unable to fetch aux leaves: "+
|
||||||
"%w", err)
|
"%w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3660,11 +3661,9 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
fn.FlattenOption(auxLeaf),
|
fn.FlattenOption(auxLeaf),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): hook up signer interface here
|
|
||||||
|
|
||||||
// Construct a full hash cache as we may be signing a segwit v1
|
// Construct a full hash cache as we may be signing a segwit v1
|
||||||
// sighash.
|
// sighash.
|
||||||
txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex]
|
txOut := remoteCommitView.txn.TxOut[htlc.remoteOutputIndex]
|
||||||
@ -3696,6 +3695,12 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sigBatch = append(sigBatch, sigJob)
|
sigBatch = append(sigBatch, sigJob)
|
||||||
|
|
||||||
|
auxSigJob := NewAuxSigJob(
|
||||||
|
sigJob, *keyRing, htlc, remoteCommitView.customBlob,
|
||||||
|
fn.FlattenOption(auxLeaf), cancelChan,
|
||||||
|
)
|
||||||
|
auxSigBatch = append(auxSigBatch, auxSigJob)
|
||||||
}
|
}
|
||||||
for _, htlc := range remoteCommitView.outgoingHTLCs {
|
for _, htlc := range remoteCommitView.outgoingHTLCs {
|
||||||
if HtlcIsDust(
|
if HtlcIsDust(
|
||||||
@ -3740,7 +3745,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
fn.FlattenOption(auxLeaf),
|
fn.FlattenOption(auxLeaf),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a full hash cache as we may be signing a segwit v1
|
// Construct a full hash cache as we may be signing a segwit v1
|
||||||
@ -3773,9 +3778,15 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sigBatch = append(sigBatch, sigJob)
|
sigBatch = append(sigBatch, sigJob)
|
||||||
|
|
||||||
|
auxSigJob := NewAuxSigJob(
|
||||||
|
sigJob, *keyRing, htlc, remoteCommitView.customBlob,
|
||||||
|
fn.FlattenOption(auxLeaf), cancelChan,
|
||||||
|
)
|
||||||
|
auxSigBatch = append(auxSigBatch, auxSigJob)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sigBatch, cancelChan, nil
|
return sigBatch, auxSigBatch, cancelChan, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// createCommitDiff will create a commit diff given a new pending commitment
|
// createCommitDiff will create a commit diff given a new pending commitment
|
||||||
@ -3784,7 +3795,8 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
|
|||||||
// new commitment to the remote party. The commit diff returned contains all
|
// new commitment to the remote party. The commit diff returned contains all
|
||||||
// information necessary for retransmission.
|
// information necessary for retransmission.
|
||||||
func (lc *LightningChannel) createCommitDiff(newCommit *commitment,
|
func (lc *LightningChannel) createCommitDiff(newCommit *commitment,
|
||||||
commitSig lnwire.Sig, htlcSigs []lnwire.Sig) (*channeldb.CommitDiff,
|
commitSig lnwire.Sig, htlcSigs []lnwire.Sig,
|
||||||
|
auxSigs map[input.HtlcIndex]fn.Option[tlv.Blob]) (*channeldb.CommitDiff,
|
||||||
error) {
|
error) {
|
||||||
|
|
||||||
// First, we need to convert the funding outpoint into the ID that's
|
// First, we need to convert the funding outpoint into the ID that's
|
||||||
@ -3908,6 +3920,11 @@ func (lc *LightningChannel) createCommitDiff(newCommit *commitment,
|
|||||||
// disk.
|
// disk.
|
||||||
diskCommit := newCommit.toDiskCommit(false)
|
diskCommit := newCommit.toDiskCommit(false)
|
||||||
|
|
||||||
|
auxSigBlob, err := packSigs(auxSigs, lc.auxSigner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error packing aux sigs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return &channeldb.CommitDiff{
|
return &channeldb.CommitDiff{
|
||||||
Commitment: *diskCommit,
|
Commitment: *diskCommit,
|
||||||
CommitSig: &lnwire.CommitSig{
|
CommitSig: &lnwire.CommitSig{
|
||||||
@ -3916,6 +3933,7 @@ func (lc *LightningChannel) createCommitDiff(newCommit *commitment,
|
|||||||
),
|
),
|
||||||
CommitSig: commitSig,
|
CommitSig: commitSig,
|
||||||
HtlcSigs: htlcSigs,
|
HtlcSigs: htlcSigs,
|
||||||
|
ExtraData: auxSigBlob,
|
||||||
},
|
},
|
||||||
LogUpdates: logUpdates,
|
LogUpdates: logUpdates,
|
||||||
OpenedCircuitKeys: openCircuitKeys,
|
OpenedCircuitKeys: openCircuitKeys,
|
||||||
@ -4365,6 +4383,10 @@ type CommitSigs struct {
|
|||||||
// PartialSig is the musig2 partial signature for taproot commitment
|
// PartialSig is the musig2 partial signature for taproot commitment
|
||||||
// transactions.
|
// transactions.
|
||||||
PartialSig lnwire.OptPartialSigWithNonceTLV
|
PartialSig lnwire.OptPartialSigWithNonceTLV
|
||||||
|
|
||||||
|
// AuxSigBlob is the blob containing all the auxiliary signatures for
|
||||||
|
// this new commitment state.
|
||||||
|
AuxSigBlob tlv.Blob
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommitState wraps the various signatures needed to properly
|
// NewCommitState wraps the various signatures needed to properly
|
||||||
@ -4483,7 +4505,7 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
|
|||||||
if lc.channelState.ChanType.HasLeaseExpiration() {
|
if lc.channelState.ChanType.HasLeaseExpiration() {
|
||||||
leaseExpiry = lc.channelState.ThawHeight
|
leaseExpiry = lc.channelState.ThawHeight
|
||||||
}
|
}
|
||||||
sigBatch, cancelChan, err := genRemoteHtlcSigJobs(
|
sigBatch, auxSigBatch, cancelChan, err := genRemoteHtlcSigJobs(
|
||||||
keyRing, lc.channelState, leaseExpiry, newCommitView,
|
keyRing, lc.channelState, leaseExpiry, newCommitView,
|
||||||
lc.leafStore,
|
lc.leafStore,
|
||||||
)
|
)
|
||||||
@ -4492,6 +4514,16 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
|
|||||||
}
|
}
|
||||||
lc.sigPool.SubmitSignBatch(sigBatch)
|
lc.sigPool.SubmitSignBatch(sigBatch)
|
||||||
|
|
||||||
|
err = fn.MapOptionZ(lc.auxSigner, func(a AuxSigner) error {
|
||||||
|
return a.SubmitSecondLevelSigBatch(
|
||||||
|
lc.channelState, newCommitView.txn, auxSigBatch,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error submitting second level sig "+
|
||||||
|
"batch: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// While the jobs are being carried out, we'll Sign their version of
|
// While the jobs are being carried out, we'll Sign their version of
|
||||||
// the new commitment transaction while we're waiting for the rest of
|
// the new commitment transaction while we're waiting for the rest of
|
||||||
// the HTLC signatures to be processed.
|
// the HTLC signatures to be processed.
|
||||||
@ -4535,11 +4567,18 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
|
|||||||
sort.Slice(sigBatch, func(i, j int) bool {
|
sort.Slice(sigBatch, func(i, j int) bool {
|
||||||
return sigBatch[i].OutputIndex < sigBatch[j].OutputIndex
|
return sigBatch[i].OutputIndex < sigBatch[j].OutputIndex
|
||||||
})
|
})
|
||||||
|
sort.Slice(auxSigBatch, func(i, j int) bool {
|
||||||
|
return auxSigBatch[i].OutputIndex < auxSigBatch[j].OutputIndex
|
||||||
|
})
|
||||||
|
|
||||||
// With the jobs sorted, we'll now iterate through all the responses to
|
// With the jobs sorted, we'll now iterate through all the responses to
|
||||||
// gather each of the signatures in order.
|
// gather each of the signatures in order.
|
||||||
htlcSigs = make([]lnwire.Sig, 0, len(sigBatch))
|
htlcSigs = make([]lnwire.Sig, 0, len(sigBatch))
|
||||||
for _, htlcSigJob := range sigBatch {
|
auxSigs := make(
|
||||||
|
map[input.HtlcIndex]fn.Option[tlv.Blob], len(auxSigBatch),
|
||||||
|
)
|
||||||
|
for i := range sigBatch {
|
||||||
|
htlcSigJob := sigBatch[i]
|
||||||
jobResp := <-htlcSigJob.Resp
|
jobResp := <-htlcSigJob.Resp
|
||||||
|
|
||||||
// If an error occurred, then we'll cancel any other active
|
// If an error occurred, then we'll cancel any other active
|
||||||
@ -4550,12 +4589,30 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
htlcSigs = append(htlcSigs, jobResp.Sig)
|
htlcSigs = append(htlcSigs, jobResp.Sig)
|
||||||
|
|
||||||
|
if lc.auxSigner.IsNone() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
auxHtlcSigJob := auxSigBatch[i]
|
||||||
|
auxJobResp := <-auxHtlcSigJob.Resp
|
||||||
|
|
||||||
|
// If an error occurred, then we'll cancel any other active
|
||||||
|
// jobs.
|
||||||
|
if auxJobResp.Err != nil {
|
||||||
|
close(cancelChan)
|
||||||
|
return nil, auxJobResp.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
auxSigs[auxJobResp.HtlcIndex] = auxJobResp.SigBlob
|
||||||
}
|
}
|
||||||
|
|
||||||
// As we're about to proposer a new commitment state for the remote
|
// As we're about to proposer a new commitment state for the remote
|
||||||
// party, we'll write this pending state to disk before we exit, so we
|
// party, we'll write this pending state to disk before we exit, so we
|
||||||
// can retransmit it if necessary.
|
// can retransmit it if necessary.
|
||||||
commitDiff, err := lc.createCommitDiff(newCommitView, sig, htlcSigs)
|
commitDiff, err := lc.createCommitDiff(
|
||||||
|
newCommitView, sig, htlcSigs, auxSigs,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -4577,6 +4634,7 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
|
|||||||
CommitSig: sig,
|
CommitSig: sig,
|
||||||
HtlcSigs: htlcSigs,
|
HtlcSigs: htlcSigs,
|
||||||
PartialSig: lnwire.MaybePartialSigWithNonce(partialSig),
|
PartialSig: lnwire.MaybePartialSigWithNonce(partialSig),
|
||||||
|
AuxSigBlob: commitDiff.CommitSig.ExtraData,
|
||||||
},
|
},
|
||||||
PendingHTLCs: commitDiff.Commitment.Htlcs,
|
PendingHTLCs: commitDiff.Commitment.Htlcs,
|
||||||
}, nil
|
}, nil
|
||||||
@ -5054,7 +5112,8 @@ func (lc *LightningChannel) computeView(view *HtlcView, remoteChain bool,
|
|||||||
func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
||||||
localCommitmentView *commitment, keyRing *CommitmentKeyRing,
|
localCommitmentView *commitment, keyRing *CommitmentKeyRing,
|
||||||
htlcSigs []lnwire.Sig, leaseExpiry uint32,
|
htlcSigs []lnwire.Sig, leaseExpiry uint32,
|
||||||
leafStore fn.Option[AuxLeafStore]) ([]VerifyJob, error) {
|
leafStore fn.Option[AuxLeafStore], auxSigner fn.Option[AuxSigner],
|
||||||
|
sigBlob fn.Option[tlv.Blob]) ([]VerifyJob, []AuxVerifyJob, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
isLocalInitiator = chanState.IsInitiator
|
isLocalInitiator = chanState.IsInitiator
|
||||||
@ -5073,13 +5132,22 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
numHtlcs := (len(localCommitmentView.incomingHTLCs) +
|
numHtlcs := (len(localCommitmentView.incomingHTLCs) +
|
||||||
len(localCommitmentView.outgoingHTLCs))
|
len(localCommitmentView.outgoingHTLCs))
|
||||||
verifyJobs := make([]VerifyJob, 0, numHtlcs)
|
verifyJobs := make([]VerifyJob, 0, numHtlcs)
|
||||||
|
auxVerifyJobs := make([]AuxVerifyJob, 0, numHtlcs)
|
||||||
|
|
||||||
auxLeaves, err := AuxLeavesFromCommit(
|
auxLeaves, err := AuxLeavesFromCommit(
|
||||||
chanState, *localCommitmentView.toDiskCommit(true), leafStore,
|
chanState, *localCommitmentView.toDiskCommit(true), leafStore,
|
||||||
*keyRing,
|
*keyRing,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to fetch aux leaves: %w",
|
return nil, nil, fmt.Errorf("unable to fetch aux leaves: %w",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have a sig blob, then we'll attempt to map that to individual
|
||||||
|
// blobs for each HTLC we might need a signature for.
|
||||||
|
auxHtlcSigs, err := unpackSigs(sigBlob, auxSigner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("error unpacking aux sigs: %w",
|
||||||
err)
|
err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5093,6 +5161,8 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
htlcIndex uint64
|
htlcIndex uint64
|
||||||
sigHash func() ([]byte, error)
|
sigHash func() ([]byte, error)
|
||||||
sig input.Signature
|
sig input.Signature
|
||||||
|
htlc *PaymentDescriptor
|
||||||
|
auxLeaf input.AuxTapLeaf
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -5103,7 +5173,7 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
// index, then this means that we need to generate an HTLC
|
// index, then this means that we need to generate an HTLC
|
||||||
// success transaction in order to validate the signature.
|
// success transaction in order to validate the signature.
|
||||||
case localCommitmentView.incomingHTLCIndex[outputIndex] != nil:
|
case localCommitmentView.incomingHTLCIndex[outputIndex] != nil:
|
||||||
htlc := localCommitmentView.incomingHTLCIndex[outputIndex]
|
htlc = localCommitmentView.incomingHTLCIndex[outputIndex]
|
||||||
|
|
||||||
htlcIndex = htlc.HtlcIndex
|
htlcIndex = htlc.HtlcIndex
|
||||||
|
|
||||||
@ -5116,20 +5186,20 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
htlcFee := HtlcSuccessFee(chanType, feePerKw)
|
htlcFee := HtlcSuccessFee(chanType, feePerKw)
|
||||||
outputAmt := htlc.Amount.ToSatoshis() - htlcFee
|
outputAmt := htlc.Amount.ToSatoshis() - htlcFee
|
||||||
|
|
||||||
auxLeaf := fn.MapOption(func(
|
leaf := fn.MapOption(func(
|
||||||
l CommitAuxLeaves) input.AuxTapLeaf {
|
l CommitAuxLeaves) input.AuxTapLeaf {
|
||||||
|
|
||||||
leaves := l.IncomingHtlcLeaves
|
leaves := l.IncomingHtlcLeaves
|
||||||
idx := htlc.HtlcIndex
|
idx := htlc.HtlcIndex
|
||||||
return leaves[idx].SecondLevelLeaf
|
return leaves[idx].SecondLevelLeaf
|
||||||
})(auxLeaves)
|
})(auxLeaves)
|
||||||
|
auxLeaf = fn.FlattenOption(leaf)
|
||||||
|
|
||||||
successTx, err := CreateHtlcSuccessTx(
|
successTx, err := CreateHtlcSuccessTx(
|
||||||
chanType, isLocalInitiator, op,
|
chanType, isLocalInitiator, op,
|
||||||
outputAmt, uint32(localChanCfg.CsvDelay),
|
outputAmt, uint32(localChanCfg.CsvDelay),
|
||||||
leaseExpiry, keyRing.RevocationKey,
|
leaseExpiry, keyRing.RevocationKey,
|
||||||
keyRing.ToLocalKey,
|
keyRing.ToLocalKey, auxLeaf,
|
||||||
fn.FlattenOption(auxLeaf),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -5172,7 +5242,7 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
|
|
||||||
// Make sure there are more signatures left.
|
// Make sure there are more signatures left.
|
||||||
if i >= len(htlcSigs) {
|
if i >= len(htlcSigs) {
|
||||||
return nil, fmt.Errorf("not enough HTLC " +
|
return nil, nil, fmt.Errorf("not enough HTLC " +
|
||||||
"signatures")
|
"signatures")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5188,7 +5258,7 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
// is valid.
|
// is valid.
|
||||||
sig, err = htlcSigs[i].ToSignature()
|
sig, err = htlcSigs[i].ToSignature()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
htlc.sig = sig
|
htlc.sig = sig
|
||||||
|
|
||||||
@ -5196,7 +5266,7 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
// generate a timeout transaction so we can verify the
|
// generate a timeout transaction so we can verify the
|
||||||
// signature presented.
|
// signature presented.
|
||||||
case localCommitmentView.outgoingHTLCIndex[outputIndex] != nil:
|
case localCommitmentView.outgoingHTLCIndex[outputIndex] != nil:
|
||||||
htlc := localCommitmentView.outgoingHTLCIndex[outputIndex]
|
htlc = localCommitmentView.outgoingHTLCIndex[outputIndex]
|
||||||
|
|
||||||
htlcIndex = htlc.HtlcIndex
|
htlcIndex = htlc.HtlcIndex
|
||||||
|
|
||||||
@ -5209,21 +5279,21 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
htlcFee := HtlcTimeoutFee(chanType, feePerKw)
|
htlcFee := HtlcTimeoutFee(chanType, feePerKw)
|
||||||
outputAmt := htlc.Amount.ToSatoshis() - htlcFee
|
outputAmt := htlc.Amount.ToSatoshis() - htlcFee
|
||||||
|
|
||||||
auxLeaf := fn.MapOption(func(
|
leaf := fn.MapOption(func(
|
||||||
l CommitAuxLeaves) input.AuxTapLeaf {
|
l CommitAuxLeaves) input.AuxTapLeaf {
|
||||||
|
|
||||||
leaves := l.OutgoingHtlcLeaves
|
leaves := l.OutgoingHtlcLeaves
|
||||||
idx := htlc.HtlcIndex
|
idx := htlc.HtlcIndex
|
||||||
return leaves[idx].SecondLevelLeaf
|
return leaves[idx].SecondLevelLeaf
|
||||||
})(auxLeaves)
|
})(auxLeaves)
|
||||||
|
auxLeaf = fn.FlattenOption(leaf)
|
||||||
|
|
||||||
timeoutTx, err := CreateHtlcTimeoutTx(
|
timeoutTx, err := CreateHtlcTimeoutTx(
|
||||||
chanType, isLocalInitiator, op,
|
chanType, isLocalInitiator, op,
|
||||||
outputAmt, htlc.Timeout,
|
outputAmt, htlc.Timeout,
|
||||||
uint32(localChanCfg.CsvDelay),
|
uint32(localChanCfg.CsvDelay),
|
||||||
leaseExpiry, keyRing.RevocationKey,
|
leaseExpiry, keyRing.RevocationKey,
|
||||||
keyRing.ToLocalKey,
|
keyRing.ToLocalKey, auxLeaf,
|
||||||
fn.FlattenOption(auxLeaf),
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -5268,7 +5338,7 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
|
|
||||||
// Make sure there are more signatures left.
|
// Make sure there are more signatures left.
|
||||||
if i >= len(htlcSigs) {
|
if i >= len(htlcSigs) {
|
||||||
return nil, fmt.Errorf("not enough HTLC " +
|
return nil, nil, fmt.Errorf("not enough HTLC " +
|
||||||
"signatures")
|
"signatures")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5284,7 +5354,7 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
// is valid.
|
// is valid.
|
||||||
sig, err = htlcSigs[i].ToSignature()
|
sig, err = htlcSigs[i].ToSignature()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
htlc.sig = sig
|
htlc.sig = sig
|
||||||
@ -5301,16 +5371,26 @@ func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
|
|||||||
})
|
})
|
||||||
|
|
||||||
i++
|
i++
|
||||||
|
|
||||||
|
// TODO(roasbeef): meld aux six into tlv blob for htlc on disk?
|
||||||
|
|
||||||
|
auxSig := auxHtlcSigs[htlcIndex]
|
||||||
|
auxVerifyJob := NewAuxVerifyJob(
|
||||||
|
auxSig, *keyRing, *htlc,
|
||||||
|
localCommitmentView.customBlob, auxLeaf,
|
||||||
|
)
|
||||||
|
|
||||||
|
auxVerifyJobs = append(auxVerifyJobs, auxVerifyJob)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we received a number of HTLC signatures that doesn't match our
|
// If we received a number of HTLC signatures that doesn't match our
|
||||||
// commitment, we'll return an error now.
|
// commitment, we'll return an error now.
|
||||||
if len(htlcSigs) != i {
|
if len(htlcSigs) != i {
|
||||||
return nil, fmt.Errorf("number of htlc sig mismatch. "+
|
return nil, nil, fmt.Errorf("number of htlc sig mismatch. "+
|
||||||
"Expected %v sigs, got %v", i, len(htlcSigs))
|
"Expected %v sigs, got %v", i, len(htlcSigs))
|
||||||
}
|
}
|
||||||
|
|
||||||
return verifyJobs, nil
|
return verifyJobs, auxVerifyJobs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidCommitSigError is a struct that implements the error interface to
|
// InvalidCommitSigError is a struct that implements the error interface to
|
||||||
@ -5472,6 +5552,11 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSigs *CommitSigs) error {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var auxSigBlob fn.Option[tlv.Blob]
|
||||||
|
if commitSigs.AuxSigBlob != nil {
|
||||||
|
auxSigBlob = fn.Some(commitSigs.AuxSigBlob)
|
||||||
|
}
|
||||||
|
|
||||||
// As an optimization, we'll generate a series of jobs for the worker
|
// As an optimization, we'll generate a series of jobs for the worker
|
||||||
// pool to verify each of the HTLC signatures presented. Once
|
// pool to verify each of the HTLC signatures presented. Once
|
||||||
// generated, we'll submit these jobs to the worker pool.
|
// generated, we'll submit these jobs to the worker pool.
|
||||||
@ -5479,9 +5564,10 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSigs *CommitSigs) error {
|
|||||||
if lc.channelState.ChanType.HasLeaseExpiration() {
|
if lc.channelState.ChanType.HasLeaseExpiration() {
|
||||||
leaseExpiry = lc.channelState.ThawHeight
|
leaseExpiry = lc.channelState.ThawHeight
|
||||||
}
|
}
|
||||||
verifyJobs, err := genHtlcSigValidationJobs(
|
verifyJobs, auxVerifyJobs, err := genHtlcSigValidationJobs(
|
||||||
lc.channelState, localCommitmentView, keyRing,
|
lc.channelState, localCommitmentView, keyRing,
|
||||||
commitSigs.HtlcSigs, leaseExpiry, lc.leafStore,
|
commitSigs.HtlcSigs, leaseExpiry, lc.leafStore, lc.auxSigner,
|
||||||
|
auxSigBlob,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -5630,6 +5716,17 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSigs *CommitSigs) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that we know all the normal sigs are valid, we'll also verify
|
||||||
|
// the aux jobs, if any exist.
|
||||||
|
err = fn.MapOptionZ(lc.auxSigner, func(a AuxSigner) error {
|
||||||
|
return a.VerifySecondLevelSigs(
|
||||||
|
lc.channelState, localCommitTx, auxVerifyJobs,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to validate aux sigs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// The signature checks out, so we can now add the new commitment to
|
// The signature checks out, so we can now add the new commitment to
|
||||||
// our local commitment chain. For regular channels, we can just
|
// our local commitment chain. For regular channels, we can just
|
||||||
// serialize the ECDSA sig. For taproot channels, we'll serialize the
|
// serialize the ECDSA sig. For taproot channels, we'll serialize the
|
||||||
|
@ -67,4 +67,8 @@ type Config struct {
|
|||||||
// AuxLeafStore is an optional store that can be used to store auxiliary
|
// AuxLeafStore is an optional store that can be used to store auxiliary
|
||||||
// leaves for certain custom channel types.
|
// leaves for certain custom channel types.
|
||||||
AuxLeafStore fn.Option[AuxLeafStore]
|
AuxLeafStore fn.Option[AuxLeafStore]
|
||||||
|
|
||||||
|
// AuxSigner is an optional signer that can be used to sign auxiliary
|
||||||
|
// leaves for certain custom channel types.
|
||||||
|
AuxSigner fn.Option[AuxSigner]
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,8 @@ type VerifyJob struct {
|
|||||||
|
|
||||||
// HtlcIndex is the index of the HTLC from the PoV of the remote
|
// HtlcIndex is the index of the HTLC from the PoV of the remote
|
||||||
// party's update log.
|
// party's update log.
|
||||||
|
//
|
||||||
|
// TODO(roasbeef): remove -- never actually used?
|
||||||
HtlcIndex uint64
|
HtlcIndex uint64
|
||||||
|
|
||||||
// Cancel is a channel that should be closed if the caller wishes to
|
// Cancel is a channel that should be closed if the caller wishes to
|
||||||
|
@ -2602,6 +2602,9 @@ func (l *LightningWallet) ValidateChannel(channelState *channeldb.OpenChannel,
|
|||||||
l.Cfg.AuxLeafStore.WhenSome(func(s AuxLeafStore) {
|
l.Cfg.AuxLeafStore.WhenSome(func(s AuxLeafStore) {
|
||||||
chanOpts = append(chanOpts, WithLeafStore(s))
|
chanOpts = append(chanOpts, WithLeafStore(s))
|
||||||
})
|
})
|
||||||
|
l.Cfg.AuxSigner.WhenSome(func(s AuxSigner) {
|
||||||
|
chanOpts = append(chanOpts, WithAuxSigner(s))
|
||||||
|
})
|
||||||
|
|
||||||
// First, we'll obtain a fully signed commitment transaction so we can
|
// First, we'll obtain a fully signed commitment transaction so we can
|
||||||
// pass into it on the chanvalidate package for verification.
|
// pass into it on the chanvalidate package for verification.
|
||||||
|
@ -364,6 +364,10 @@ type Config struct {
|
|||||||
// leaves for certain custom channel types.
|
// leaves for certain custom channel types.
|
||||||
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
AuxLeafStore fn.Option[lnwallet.AuxLeafStore]
|
||||||
|
|
||||||
|
// AuxSigner is an optional signer that can be used to sign auxiliary
|
||||||
|
// leaves for certain custom channel types.
|
||||||
|
AuxSigner fn.Option[lnwallet.AuxSigner]
|
||||||
|
|
||||||
// PongBuf is a slice we'll reuse instead of allocating memory on the
|
// PongBuf is a slice we'll reuse instead of allocating memory on the
|
||||||
// heap. Since only reads will occur and no writes, there is no need
|
// heap. Since only reads will occur and no writes, there is no need
|
||||||
// for any synchronization primitives. As a result, it's safe to share
|
// for any synchronization primitives. As a result, it's safe to share
|
||||||
@ -902,6 +906,9 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
|
|||||||
p.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
p.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
||||||
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
||||||
})
|
})
|
||||||
|
p.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
|
||||||
|
chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
|
||||||
|
})
|
||||||
lnChan, err := lnwallet.NewLightningChannel(
|
lnChan, err := lnwallet.NewLightningChannel(
|
||||||
p.cfg.Signer, dbChan, p.cfg.SigPool, chanOpts...,
|
p.cfg.Signer, dbChan, p.cfg.SigPool, chanOpts...,
|
||||||
)
|
)
|
||||||
@ -4030,6 +4037,9 @@ func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
|
|||||||
p.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
p.cfg.AuxLeafStore.WhenSome(func(s lnwallet.AuxLeafStore) {
|
||||||
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
chanOpts = append(chanOpts, lnwallet.WithLeafStore(s))
|
||||||
})
|
})
|
||||||
|
p.cfg.AuxSigner.WhenSome(func(s lnwallet.AuxSigner) {
|
||||||
|
chanOpts = append(chanOpts, lnwallet.WithAuxSigner(s))
|
||||||
|
})
|
||||||
|
|
||||||
// If not already active, we'll add this channel to the set of active
|
// If not already active, we'll add this channel to the set of active
|
||||||
// channels, so we can look it up later easily according to its channel
|
// channels, so we can look it up later easily according to its channel
|
||||||
|
@ -1249,6 +1249,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
return &pc.Incoming
|
return &pc.Incoming
|
||||||
},
|
},
|
||||||
AuxLeafStore: implCfg.AuxLeafStore,
|
AuxLeafStore: implCfg.AuxLeafStore,
|
||||||
|
AuxSigner: implCfg.AuxSigner,
|
||||||
}, dbs.ChanStateDB)
|
}, dbs.ChanStateDB)
|
||||||
|
|
||||||
// Select the configuration and funding parameters for Bitcoin.
|
// Select the configuration and funding parameters for Bitcoin.
|
||||||
@ -3913,6 +3914,7 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq,
|
|||||||
DisallowRouteBlinding: s.cfg.ProtocolOptions.NoRouteBlinding(),
|
DisallowRouteBlinding: s.cfg.ProtocolOptions.NoRouteBlinding(),
|
||||||
Quit: s.quit,
|
Quit: s.quit,
|
||||||
AuxLeafStore: s.implCfg.AuxLeafStore,
|
AuxLeafStore: s.implCfg.AuxLeafStore,
|
||||||
|
AuxSigner: s.implCfg.AuxSigner,
|
||||||
MsgRouter: s.implCfg.MsgRouter,
|
MsgRouter: s.implCfg.MsgRouter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user