multi: thread thru the AuxLeafStore everywhere

This commit is contained in:
Oliver Gugger committed 2024-08-28 13:26:14 +02:00
1 parent 2510c19024
commit b45d72fe59
15 files changed
+194 -47

No files matched your search

+38 -25
View File
@@ -1965,7 +1965,8 @@ type BreachRetribution struct {
// required to construct the BreachRetribution. If the revocation log is missing
// the required fields then ErrRevLogDataMissing will be returned.
func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
breachHeight uint32, spendTx *wire.MsgTx) (*BreachRetribution, error) {
breachHeight uint32, spendTx *wire.MsgTx,
leafStore fn.Option[AuxLeafStore]) (*BreachRetribution, error) {
// Query the on-disk revocation log for the snapshot which was recorded
// at this particular state num. Based on whether a legacy revocation
@@ -3023,9 +3024,16 @@ func processFeeUpdate(feeUpdate *PaymentDescriptor, nextHeight uint64,
// signature can be submitted to the sigPool to generate all the signatures
// asynchronously and in parallel.
func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
chanType channeldb.ChannelType, isRemoteInitiator bool,
leaseExpiry uint32, localChanCfg, remoteChanCfg *channeldb.ChannelConfig,
remoteCommitView *commitment) ([]SignJob, chan struct{}, error) {
chanState *channeldb.OpenChannel, leaseExpiry uint32,
remoteCommitView *commitment,
leafStore fn.Option[AuxLeafStore]) ([]SignJob, chan struct{}, error) {
var (
isRemoteInitiator = !chanState.IsInitiator
localChanCfg = chanState.LocalChanCfg
remoteChanCfg = chanState.RemoteChanCfg
chanType = chanState.ChanType
)
txHash := remoteCommitView.txn.TxHash()
dustLimit := remoteChanCfg.DustLimit
@@ -3191,9 +3199,9 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
// validate this new state. This function is called right before sending the
// new commitment to the remote party. The commit diff returned contains all
// information necessary for retransmission.
func (lc *LightningChannel) createCommitDiff(
newCommit *commitment, commitSig lnwire.Sig,
htlcSigs []lnwire.Sig) (*channeldb.CommitDiff, error) {
func (lc *LightningChannel) createCommitDiff(newCommit *commitment,
commitSig lnwire.Sig, htlcSigs []lnwire.Sig) (*channeldb.CommitDiff,
error) {
// First, we need to convert the funding outpoint into the ID that's
// used on the wire to identify this channel. We'll use this shortly
@@ -3892,9 +3900,8 @@ func (lc *LightningChannel) SignNextCommitment() (*NewCommitState, error) {
leaseExpiry = lc.channelState.ThawHeight
}
sigBatch, cancelChan, err := genRemoteHtlcSigJobs(
keyRing, lc.channelState.ChanType, !lc.channelState.IsInitiator,
leaseExpiry, &lc.channelState.LocalChanCfg,
&lc.channelState.RemoteChanCfg, newCommitView,
keyRing, lc.channelState, leaseExpiry, newCommitView,
lc.leafStore,
)
if err != nil {
return nil, err
@@ -4465,10 +4472,18 @@ func (lc *LightningChannel) computeView(view *HtlcView,
// meant to verify all the signatures for HTLC's attached to a newly created
// commitment state. The jobs generated are fully populated, and can be sent
// directly into the pool of workers.
func genHtlcSigValidationJobs(localCommitmentView *commitment,
keyRing *CommitmentKeyRing, htlcSigs []lnwire.Sig,
chanType channeldb.ChannelType, isLocalInitiator bool, leaseExpiry uint32,
localChanCfg, remoteChanCfg *channeldb.ChannelConfig) ([]VerifyJob, error) {
//
//nolint:funlen
func genHtlcSigValidationJobs(chanState *channeldb.OpenChannel,
localCommitmentView *commitment, keyRing *CommitmentKeyRing,
htlcSigs []lnwire.Sig, leaseExpiry uint32,
leafStore fn.Option[AuxLeafStore]) ([]VerifyJob, error) {
var (
isLocalInitiator = chanState.IsInitiator
localChanCfg = chanState.LocalChanCfg
chanType = chanState.ChanType
)
txHash := localCommitmentView.txn.TxHash()
feePerKw := localCommitmentView.feePerKw
@@ -4858,10 +4873,8 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSigs *CommitSigs) error {
leaseExpiry = lc.channelState.ThawHeight
}
verifyJobs, err := genHtlcSigValidationJobs(
localCommitmentView, keyRing, commitSigs.HtlcSigs,
lc.channelState.ChanType, lc.channelState.IsInitiator,
leaseExpiry, &lc.channelState.LocalChanCfg,
&lc.channelState.RemoteChanCfg,
lc.channelState, localCommitmentView, keyRing,
commitSigs.HtlcSigs, leaseExpiry, lc.leafStore,
)
if err != nil {
return err
@@ -6308,10 +6321,10 @@ type UnilateralCloseSummary struct {
// happen in case we have lost state) it should be set to an empty struct, in
// which case we will attempt to sweep the non-HTLC output using the passed
// commitPoint.
func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Signer,
commitSpend *chainntnfs.SpendDetail,
remoteCommit channeldb.ChannelCommitment,
commitPoint *btcec.PublicKey) (*UnilateralCloseSummary, error) {
func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel,
signer input.Signer, commitSpend *chainntnfs.SpendDetail,
remoteCommit channeldb.ChannelCommitment, commitPoint *btcec.PublicKey,
leafStore fn.Option[AuxLeafStore]) (*UnilateralCloseSummary, error) {
// First, we'll generate the commitment point and the revocation point
// so we can re-construct the HTLC state and also our payment key.
@@ -7254,7 +7267,7 @@ func (lc *LightningChannel) ForceClose() (*LocalForceCloseSummary, error) {
localCommitment := lc.channelState.LocalCommitment
summary, err := NewLocalForceCloseSummary(
lc.channelState, lc.Signer, commitTx,
localCommitment.CommitHeight,
localCommitment.CommitHeight, lc.leafStore,
)
if err != nil {
return nil, fmt.Errorf("unable to gen force close "+
@@ -7271,8 +7284,8 @@ func (lc *LightningChannel) ForceClose() (*LocalForceCloseSummary, error) {
// channel state. The passed commitTx must be a fully signed commitment
// transaction corresponding to localCommit.
func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel,
signer input.Signer, commitTx *wire.MsgTx, stateNum uint64) (
*LocalForceCloseSummary, error) {
signer input.Signer, commitTx *wire.MsgTx, stateNum uint64,
leafStore fn.Option[AuxLeafStore]) (*LocalForceCloseSummary, error) {
// Re-derive the original pkScript for to-self output within the
// commitment transaction. We'll need this to find the corresponding
+10
View File
@@ -5695,6 +5695,7 @@ func TestChannelUnilateralCloseHtlcResolution(t *testing.T) {
spendDetail,
aliceChannel.channelState.RemoteCommitment,
aliceChannel.channelState.RemoteCurrentRevocation,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.NoError(t, err, "unable to create alice close summary")
@@ -5844,6 +5845,7 @@ func TestChannelUnilateralClosePendingCommit(t *testing.T) {
spendDetail,
aliceChannel.channelState.RemoteCommitment,
aliceChannel.channelState.RemoteCurrentRevocation,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.NoError(t, err, "unable to create alice close summary")
@@ -5861,6 +5863,7 @@ func TestChannelUnilateralClosePendingCommit(t *testing.T) {
spendDetail,
aliceRemoteChainTip.Commitment,
aliceChannel.channelState.RemoteNextRevocation,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.NoError(t, err, "unable to create alice close summary")
@@ -6741,6 +6744,7 @@ func TestNewBreachRetributionSkipsDustHtlcs(t *testing.T) {
breachTx := aliceChannel.channelState.RemoteCommitment.CommitTx
breachRet, err := NewBreachRetribution(
aliceChannel.channelState, revokedStateNum, 100, breachTx,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.NoError(t, err, "unable to create breach retribution")
@@ -10291,6 +10295,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
// error as there are no past delta state saved as revocation logs yet.
_, err = NewBreachRetribution(
aliceChannel.channelState, stateNum, breachHeight, breachTx,
fn.None[AuxLeafStore](),
)
require.ErrorIs(t, err, channeldb.ErrNoPastDeltas)
@@ -10298,6 +10303,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
// provided.
_, err = NewBreachRetribution(
aliceChannel.channelState, stateNum, breachHeight, nil,
fn.None[AuxLeafStore](),
)
require.ErrorIs(t, err, channeldb.ErrNoPastDeltas)
@@ -10343,6 +10349,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
// successfully.
br, err := NewBreachRetribution(
aliceChannel.channelState, stateNum, breachHeight, breachTx,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.NoError(t, err)
@@ -10354,6 +10361,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
// since the necessary info should now be found in the revocation log.
br, err = NewBreachRetribution(
aliceChannel.channelState, stateNum, breachHeight, nil,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.NoError(t, err)
assertRetribution(br, 1, 0)
@@ -10362,6 +10370,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
// error.
_, err = NewBreachRetribution(
aliceChannel.channelState, stateNum+1, breachHeight, breachTx,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.ErrorIs(t, err, channeldb.ErrLogEntryNotFound)
@@ -10369,6 +10378,7 @@ func testNewBreachRetribution(t *testing.T, chanType channeldb.ChannelType) {
// provided.
_, err = NewBreachRetribution(
aliceChannel.channelState, stateNum+1, breachHeight, nil,
fn.Some[AuxLeafStore](&MockAuxLeafStore{}),
)
require.ErrorIs(t, err, channeldb.ErrLogEntryNotFound)
}
+5
View File
@@ -5,6 +5,7 @@ import (
"github.com/btcsuite/btcwallet/wallet"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
@@ -62,4 +63,8 @@ type Config struct {
// CoinSelectionStrategy is the strategy that is used for selecting
// coins when funding a transaction.
CoinSelectionStrategy wallet.CoinSelectionStrategy
// AuxLeafStore is an optional store that can be used to store auxiliary
// leaves for certain custom channel types.
AuxLeafStore fn.Option[AuxLeafStore]
}
+44
View File
@@ -17,8 +17,10 @@ import (
"github.com/btcsuite/btcwallet/wallet/txauthor"
"github.com/btcsuite/btcwallet/wtxmgr"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/tlv"
)
var (
@@ -397,3 +399,45 @@ func (*mockChainIO) GetBlockHeader(
return nil, nil
}
type MockAuxLeafStore struct{}
// A compile time check to ensure that MockAuxLeafStore implements the
// AuxLeafStore interface.
var _ AuxLeafStore = (*MockAuxLeafStore)(nil)
// FetchLeavesFromView attempts to fetch the auxiliary leaves that
// correspond to the passed aux blob, and pending original (unfiltered)
// HTLC view.
func (*MockAuxLeafStore) FetchLeavesFromView(
_ CommitDiffAuxInput) fn.Result[CommitDiffAuxResult] {
return fn.Ok(CommitDiffAuxResult{})
}
// FetchLeavesFromCommit attempts to fetch the auxiliary leaves that
// correspond to the passed aux blob, and an existing channel
// commitment.
func (*MockAuxLeafStore) FetchLeavesFromCommit(_ AuxChanState,
_ channeldb.ChannelCommitment,
_ CommitmentKeyRing) fn.Result[CommitDiffAuxResult] {
return fn.Ok(CommitDiffAuxResult{})
}
// FetchLeavesFromRevocation attempts to fetch the auxiliary leaves
// from a channel revocation that stores balance + blob information.
func (*MockAuxLeafStore) FetchLeavesFromRevocation(
_ *channeldb.RevocationLog) fn.Result[CommitDiffAuxResult] {
return fn.Ok(CommitDiffAuxResult{})
}
// ApplyHtlcView serves as the state transition function for the custom
// channel's blob. Given the old blob, and an HTLC view, then a new
// blob should be returned that reflects the pending updates.
func (*MockAuxLeafStore) ApplyHtlcView(
_ CommitDiffAuxInput) fn.Result[fn.Option[tlv.Blob]] {
return fn.Ok(fn.None[tlv.Blob]())
}
+8 -1
View File
@@ -2496,9 +2496,16 @@ func initStateHints(commit1, commit2 *wire.MsgTx,
func (l *LightningWallet) ValidateChannel(channelState *channeldb.OpenChannel,
fundingTx *wire.MsgTx) error {
var chanOpts []ChannelOpt
l.Cfg.AuxLeafStore.WhenSome(func(s AuxLeafStore) {
chanOpts = append(chanOpts, WithLeafStore(s))
})
// First, we'll obtain a fully signed commitment transaction so we can
// pass into it on the chanvalidate package for verification.
channel, err := NewLightningChannel(l.Cfg.Signer, channelState, nil)
channel, err := NewLightningChannel(
l.Cfg.Signer, channelState, nil, chanOpts...,
)
if err != nil {
return err
}