multi: add new NoRevLogAmtData config option

In this commit, a new `--db.no-rev-log-amt-data` flag is added. The
config option is passed though to everywhere that it will be used. Note
that it is still a no-op in this commit. An upcoming commit will make
use of the flag.
This commit is contained in:
Elle Mouton
2023-02-10 10:13:34 +02:00
parent 9c01916bc0
commit 0730337cc7
11 changed files with 55 additions and 12 deletions

View File

@@ -2657,8 +2657,8 @@ func (c *OpenChannel) AdvanceCommitChainTail(fwdPkg *FwdPkg,
// With the commitment pointer swapped, we can now add the // With the commitment pointer swapped, we can now add the
// revoked (prior) state to the revocation log. // revoked (prior) state to the revocation log.
err = putRevocationLog( err = putRevocationLog(
logBucket, &c.RemoteCommitment, logBucket, &c.RemoteCommitment, ourOutputIndex,
ourOutputIndex, theirOutputIndex, theirOutputIndex, c.Db.parent.noRevLogAmtData,
) )
if err != nil { if err != nil {
return err return err

View File

@@ -324,6 +324,10 @@ type DB struct {
dryRun bool dryRun bool
keepFailedPaymentAttempts bool keepFailedPaymentAttempts bool
storeFinalHtlcResolutions bool storeFinalHtlcResolutions bool
// noRevLogAmtData if true, means that commitment transaction amount
// data should not be stored in the revocation log.
noRevLogAmtData bool
} }
// Open opens or creates channeldb. Any necessary schemas migrations due // Open opens or creates channeldb. Any necessary schemas migrations due
@@ -382,6 +386,7 @@ func CreateWithBackend(backend kvdb.Backend,
dryRun: opts.dryRun, dryRun: opts.dryRun,
keepFailedPaymentAttempts: opts.keepFailedPaymentAttempts, keepFailedPaymentAttempts: opts.keepFailedPaymentAttempts,
storeFinalHtlcResolutions: opts.storeFinalHtlcResolutions, storeFinalHtlcResolutions: opts.storeFinalHtlcResolutions,
noRevLogAmtData: opts.NoRevLogAmtData,
} }
// Set the parent pointer (only used in tests). // Set the parent pointer (only used in tests).
@@ -1562,7 +1567,9 @@ func (d *DB) applyOptionalVersions(cfg OptionalMiragtionConfig) error {
log.Infof("Performing database optional migration: %s", version.name) log.Infof("Performing database optional migration: %s", version.name)
migrationCfg := &MigrationConfigImpl{ migrationCfg := &MigrationConfigImpl{
migration30.MigrateRevLogConfigImpl{}, migration30.MigrateRevLogConfigImpl{
NoAmountData: d.noRevLogAmtData,
},
} }
// Migrate the data. // Migrate the data.

View File

@@ -223,7 +223,7 @@ type RevocationLog struct {
// disk. It also saves our output index and their output index, which are // disk. It also saves our output index and their output index, which are
// useful when creating breach retribution. // useful when creating breach retribution.
func putRevocationLog(bucket kvdb.RwBucket, commit *mig.ChannelCommitment, func putRevocationLog(bucket kvdb.RwBucket, commit *mig.ChannelCommitment,
ourOutputIndex, theirOutputIndex uint32) error { ourOutputIndex, theirOutputIndex uint32, noAmtData bool) error {
// Sanity check that the output indexes can be safely converted. // Sanity check that the output indexes can be safely converted.
if ourOutputIndex > math.MaxUint16 { if ourOutputIndex > math.MaxUint16 {

View File

@@ -306,7 +306,7 @@ func setupTestLogs(db kvdb.Backend, c *mig26.OpenChannel,
} }
// Create new logs. // Create new logs.
return writeNewRevocationLogs(chanBucket, newLogs) return writeNewRevocationLogs(chanBucket, newLogs, !withAmtData)
}, func() {}) }, func() {})
} }
@@ -460,7 +460,7 @@ func writeOldRevocationLogs(chanBucket kvdb.RwBucket,
// writeNewRevocationLogs saves a new revocation log to db. // writeNewRevocationLogs saves a new revocation log to db.
func writeNewRevocationLogs(chanBucket kvdb.RwBucket, func writeNewRevocationLogs(chanBucket kvdb.RwBucket,
oldLogs []mig.ChannelCommitment) error { oldLogs []mig.ChannelCommitment, noAmtData bool) error {
// Don't bother continue if the logs are empty. // Don't bother continue if the logs are empty.
if len(oldLogs) == 0 { if len(oldLogs) == 0 {
@@ -480,7 +480,7 @@ func writeNewRevocationLogs(chanBucket kvdb.RwBucket,
// old commit tx. We do this intentionally so we can // old commit tx. We do this intentionally so we can
// distinguish a newly created log from an already saved one. // distinguish a newly created log from an already saved one.
err := putRevocationLog( err := putRevocationLog(
logBucket, &c, testOurIndex, testTheirIndex, logBucket, &c, testOurIndex, testTheirIndex, noAmtData,
) )
if err != nil { if err != nil {
return err return err

View File

@@ -64,6 +64,10 @@ type Options struct {
// applications that use the channeldb package as a library. // applications that use the channeldb package as a library.
NoMigration bool NoMigration bool
// NoRevLogAmtData when set to true, indicates that amount data should
// not be stored in the revocation log.
NoRevLogAmtData bool
// clock is the time source used by the database. // clock is the time source used by the database.
clock clock.Clock clock clock.Clock
@@ -130,6 +134,14 @@ func OptionSetUseGraphCache(use bool) OptionModifier {
} }
} }
// OptionNoRevLogAmtData sets the NoRevLogAmtData option to the given value. If
// it is set to true then amount data will not be stored in the revocation log.
func OptionNoRevLogAmtData(noAmtData bool) OptionModifier {
return func(o *Options) {
o.NoRevLogAmtData = noAmtData
}
}
// OptionSetSyncFreelist allows the database to sync its freelist. // OptionSetSyncFreelist allows the database to sync its freelist.
func OptionSetSyncFreelist(b bool) OptionModifier { func OptionSetSyncFreelist(b bool) OptionModifier {
return func(o *Options) { return func(o *Options) {

View File

@@ -211,7 +211,7 @@ type RevocationLog struct {
// disk. It also saves our output index and their output index, which are // disk. It also saves our output index and their output index, which are
// useful when creating breach retribution. // useful when creating breach retribution.
func putRevocationLog(bucket kvdb.RwBucket, commit *ChannelCommitment, func putRevocationLog(bucket kvdb.RwBucket, commit *ChannelCommitment,
ourOutputIndex, theirOutputIndex uint32) error { ourOutputIndex, theirOutputIndex uint32, noAmtData bool) error {
// Sanity check that the output indexes can be safely converted. // Sanity check that the output indexes can be safely converted.
if ourOutputIndex > math.MaxUint16 { if ourOutputIndex > math.MaxUint16 {

View File

@@ -368,6 +368,7 @@ func TestPutRevocationLog(t *testing.T) {
commit ChannelCommitment commit ChannelCommitment
ourIndex uint32 ourIndex uint32
theirIndex uint32 theirIndex uint32
noAmtData bool
expectedErr error expectedErr error
expectedLog RevocationLog expectedLog RevocationLog
}{ }{
@@ -435,6 +436,7 @@ func TestPutRevocationLog(t *testing.T) {
// Save the log. // Save the log.
err = putRevocationLog( err = putRevocationLog(
bucket, &tc.commit, tc.ourIndex, tc.theirIndex, bucket, &tc.commit, tc.ourIndex, tc.theirIndex,
tc.noAmtData,
) )
if err != nil { if err != nil {
return RevocationLog{}, err return RevocationLog{}, err
@@ -542,7 +544,7 @@ func TestFetchRevocationLogCompatible(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
err = putRevocationLog( err = putRevocationLog(
lb, &testChannelCommit, 0, 1, lb, &testChannelCommit, 0, 1, false,
) )
require.NoError(t, err) require.NoError(t, err)
} }

View File

@@ -981,6 +981,13 @@ func ValidateConfig(cfg Config, interceptor signal.Interceptor, fileParser,
) )
} }
// Ensure that the amount data for revoked commitment transactions is
// stored if the watchtower client is active.
if cfg.DB.NoRevLogAmtData && cfg.WtClient.Active {
return nil, mkErr("revocation log amount data must be stored " +
"if the watchtower client is active")
}
// Ensure a valid max channel fee allocation was set. // Ensure a valid max channel fee allocation was set.
if cfg.MaxChannelFeeAllocation <= 0 || cfg.MaxChannelFeeAllocation > 1 { if cfg.MaxChannelFeeAllocation <= 0 || cfg.MaxChannelFeeAllocation > 1 {
return nil, mkErr("invalid max channel fee allocation: %v, "+ return nil, mkErr("invalid max channel fee allocation: %v, "+

View File

@@ -867,15 +867,22 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
dbOptions := []channeldb.OptionModifier{ dbOptions := []channeldb.OptionModifier{
channeldb.OptionSetRejectCacheSize(cfg.Caches.RejectCacheSize), channeldb.OptionSetRejectCacheSize(cfg.Caches.RejectCacheSize),
channeldb.OptionSetChannelCacheSize(cfg.Caches.ChannelCacheSize), channeldb.OptionSetChannelCacheSize(
channeldb.OptionSetBatchCommitInterval(cfg.DB.BatchCommitInterval), cfg.Caches.ChannelCacheSize,
),
channeldb.OptionSetBatchCommitInterval(
cfg.DB.BatchCommitInterval,
),
channeldb.OptionDryRunMigration(cfg.DryRunMigration), channeldb.OptionDryRunMigration(cfg.DryRunMigration),
channeldb.OptionSetUseGraphCache(!cfg.DB.NoGraphCache), channeldb.OptionSetUseGraphCache(!cfg.DB.NoGraphCache),
channeldb.OptionKeepFailedPaymentAttempts(cfg.KeepFailedPaymentAttempts), channeldb.OptionKeepFailedPaymentAttempts(
cfg.KeepFailedPaymentAttempts,
),
channeldb.OptionStoreFinalHtlcResolutions( channeldb.OptionStoreFinalHtlcResolutions(
cfg.StoreFinalHtlcResolutions, cfg.StoreFinalHtlcResolutions,
), ),
channeldb.OptionPruneRevocationLog(cfg.DB.PruneRevocation), channeldb.OptionPruneRevocationLog(cfg.DB.PruneRevocation),
channeldb.OptionNoRevLogAmtData(cfg.DB.NoRevLogAmtData),
} }
// We want to pre-allocate the channel graph cache according to what we // We want to pre-allocate the channel graph cache according to what we

View File

@@ -85,6 +85,8 @@ type DB struct {
NoGraphCache bool `long:"no-graph-cache" description:"Don't use the in-memory graph cache for path finding. Much slower but uses less RAM. Can only be used with a bolt database backend."` NoGraphCache bool `long:"no-graph-cache" description:"Don't use the in-memory graph cache for path finding. Much slower but uses less RAM. Can only be used with a bolt database backend."`
PruneRevocation bool `long:"prune-revocation" description:"Run the optional migration that prunes the revocation logs to save disk space."` PruneRevocation bool `long:"prune-revocation" description:"Run the optional migration that prunes the revocation logs to save disk space."`
NoRevLogAmtData bool `long:"no-rev-log-amt-data" description:"If set, the to-local and to-remote output amounts of revoked commitment transactions will not be stored in the revocation log. Note that once this data is lost, a watchtower client will not be able to back up the revoked state."`
} }
// DefaultDB creates and returns a new default DB config. // DefaultDB creates and returns a new default DB config.

View File

@@ -1241,6 +1241,12 @@ litecoin.node=ltcd
; channels prior to lnd@v0.15.0. ; channels prior to lnd@v0.15.0.
; db.prune-revocation=false ; db.prune-revocation=false
; If set to true, then the to-local and to-remote output amount data of revoked
; commitment transactions will not be stored in the revocation log. Note that
; this flag can only be set if --wtclient.active is not set. It is not
; recommended to set this flag if you plan on ever setting wtclient.active in
; the future.
; db.no-rev-log-amt-data=false
[etcd] [etcd]