diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 0c61850f3a..b7adbf7578 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -108,6 +108,8 @@ var ( utils.UltraLightFractionFlag, utils.UltraLightOnlyAnnounceFlag, utils.WhitelistFlag, + utils.ImmutabilityThresholdFullFlag, + utils.ImmutabilityThresholdLightFlag, utils.CacheFlag, utils.CacheDatabaseFlag, utils.CacheTrieFlag, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 3ad3dd2cde..11623e907d 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -59,6 +59,8 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.IdentityFlag, utils.LightKDFFlag, utils.WhitelistFlag, + utils.ImmutabilityThresholdFullFlag, + utils.ImmutabilityThresholdLightFlag, }, }, { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 820fa9853c..529da57181 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -65,6 +65,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params/types/ctypes" "github.com/ethereum/go-ethereum/params/types/genesisT" + "github.com/ethereum/go-ethereum/params/vars" "github.com/ethereum/go-ethereum/rpc" whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" pcsclite "github.com/gballet/go-libpcsclite" @@ -240,6 +241,16 @@ var ( Name: "whitelist", Usage: "Comma separated block number-to-hash mappings to enforce (=)", } + ImmutabilityThresholdFullFlag = cli.Int64Flag{ + Name: "immutabilitythreshold.full", + Usage: "Full Immutability Threshold is the number of blocks after which a chain segment is considered immutable (i.e. soft finality).", + Value: int64(vars.FullImmutabilityThreshold), + } + ImmutabilityThresholdLightFlag = cli.Int64Flag{ + Name: "immutabilitythreshold.light", + Usage: "Light Immutability Threshold is the number of blocks after which a header chain segment is considered immutable for light client (i.e. soft finality)", + Value: int64(vars.LightImmutabilityThreshold), + } // Light server and client settings LightServeFlag = cli.IntFlag{ Name: "light.serve", @@ -1499,6 +1510,26 @@ func setWhitelist(ctx *cli.Context, cfg *eth.Config) { } } +func setImmutabilityThresholds(ctx *cli.Context) { + if ctx.GlobalIsSet(ImmutabilityThresholdFullFlag.Name) { + v := ctx.GlobalInt64(ImmutabilityThresholdFullFlag.Name) + if v < 0 { + Fatalf("immutability threshold must be greater than or equal to 0") + } + // Type conversion will fail if type max exceeded. That's a far-edge case and not worth handling. + vars.FullImmutabilityThreshold = uint64(v) + log.Info("Using configured full immutability threshold", "threshold", vars.FullImmutabilityThreshold) + } + if ctx.GlobalIsSet(ImmutabilityThresholdLightFlag.Name) { + v := ctx.GlobalInt64(ImmutabilityThresholdLightFlag.Name) + if v < 0 { + Fatalf("immutability threshold must be greater than or equal to 0") + } + vars.LightImmutabilityThreshold = uint64(v) + log.Info("Using configured light immutability threshold", "threshold", vars.LightImmutabilityThreshold) + } +} + // CheckExclusive verifies that only a single instance of the provided flags was // set by the user. Each flag might optionally be followed by a string type to // specialize it further. @@ -1574,6 +1605,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { setEthash(ctx, cfg) setMiner(ctx, &cfg.Miner) setWhitelist(ctx, cfg) + setImmutabilityThresholds(ctx) setLes(ctx, cfg) if ctx.GlobalIsSet(SyncModeFlag.Name) { diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index e0ec387ae2..ecaa959a9d 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -370,7 +370,7 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo // at a checkpoint block without a parent (light client CHT), or we have piled // up more headers than allowed to be reorged (chain reinit from a freezer), // consider the checkpoint trusted and snapshot it. - if number == 0 || (number%c.config.Epoch == 0 && (len(headers) > vars.FullImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) { + if number == 0 || (number%c.config.Epoch == 0 && (uint64(len(headers)) > vars.FullImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) { checkpoint := chain.GetHeaderByNumber(number) if checkpoint != nil { hash := checkpoint.Hash() diff --git a/params/vars/network_params.go b/params/vars/network_params.go index d2ee80940f..f31a233e3e 100644 --- a/params/vars/network_params.go +++ b/params/vars/network_params.go @@ -56,16 +56,18 @@ const ( // CheckpointProcessConfirmations is the number before a checkpoint is generated CheckpointProcessConfirmations = 256 +) +var ( // FullImmutabilityThreshold is the number of blocks after which a chain segment is // considered immutable (i.e. soft finality). It is used by the downloader as a // hard limit against deep ancestors, by the blockchain against deep reorgs, by // the freezer as the cutoff threshold and by clique as the snapshot trust limit. - FullImmutabilityThreshold = 90000 + FullImmutabilityThreshold uint64 = 90000 // LightImmutabilityThreshold is the number of blocks after which a header chain // segment is considered immutable for light client(i.e. soft finality). It is used by // the downloader as a hard limit against deep ancestors, by the blockchain against deep // reorgs, by the light pruner as the pruning validity guarantee. - LightImmutabilityThreshold = 30000 + LightImmutabilityThreshold uint64 = 30000 )