state-diff configs & kv functions (#15903)

* state-diff configs

* state diff kv functions

* potuz's comments

* Update config.go

* fix merge conflicts

* apply bazel's suggestion and fix some bugs

* preston's feedback
This commit is contained in:
Bastin
2025-11-19 20:27:56 +01:00
committed by GitHub
parent eb9feabd6f
commit 207f36065a
17 changed files with 1329 additions and 4 deletions

View File

@@ -18,7 +18,9 @@ go_library(
],
deps = [
"//cmd:go_default_library",
"//config/features:go_default_library",
"//config/params:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
],
@@ -26,7 +28,13 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["api_module_test.go"],
srcs = [
"api_module_test.go",
"config_test.go",
],
embed = [":go_default_library"],
deps = ["//testing/assert:go_default_library"],
deps = [
"//testing/assert:go_default_library",
"//testing/require:go_default_library",
],
)

View File

@@ -345,4 +345,10 @@ var (
Usage: "Maximum number of signatures to batch verify at once for beacon attestation p2p gossip.",
Value: 1000,
}
// StateDiffExponents defines the state diff tree hierarchy levels.
StateDiffExponents = &cli.IntSliceFlag{
Name: "state-diff-exponents",
Usage: "A comma-separated list of exponents (of 2) in decreasing order, defining the state diff hierarchy levels. The last exponent must be greater than or equal to 5.",
Value: cli.NewIntSlice(21, 18, 16, 13, 11, 9, 5),
}
)

View File

@@ -2,9 +2,13 @@ package flags
import (
"github.com/OffchainLabs/prysm/v7/cmd"
"github.com/OffchainLabs/prysm/v7/config/features"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)
const maxStateDiffExponents = 30
// GlobalFlags specifies all the global flags for the
// beacon node.
type GlobalFlags struct {
@@ -19,6 +23,7 @@ type GlobalFlags struct {
BlobBatchLimitBurstFactor int
DataColumnBatchLimit int
DataColumnBatchLimitBurstFactor int
StateDiffExponents []int
}
var globalConfig *GlobalFlags
@@ -38,7 +43,7 @@ func Init(c *GlobalFlags) {
// ConfigureGlobalFlags initializes the global config.
// based on the provided cli context.
func ConfigureGlobalFlags(ctx *cli.Context) {
func ConfigureGlobalFlags(ctx *cli.Context) error {
cfg := &GlobalFlags{}
if ctx.Bool(SubscribeToAllSubnets.Name) {
@@ -51,6 +56,18 @@ func ConfigureGlobalFlags(ctx *cli.Context) {
cfg.SubscribeAllDataSubnets = true
}
// State-diff-exponents
cfg.StateDiffExponents = ctx.IntSlice(StateDiffExponents.Name)
if features.Get().EnableStateDiff {
if err := validateStateDiffExponents(cfg.StateDiffExponents); err != nil {
return err
}
} else {
if ctx.IsSet(StateDiffExponents.Name) {
log.Warn("--state-diff-exponents is set but --enable-state-diff is not; the value will be ignored.")
}
}
cfg.BlockBatchLimit = ctx.Int(BlockBatchLimit.Name)
cfg.BlockBatchLimitBurstFactor = ctx.Int(BlockBatchLimitBurstFactor.Name)
cfg.BlobBatchLimit = ctx.Int(BlobBatchLimit.Name)
@@ -63,6 +80,7 @@ func ConfigureGlobalFlags(ctx *cli.Context) {
configureMinimumPeers(ctx, cfg)
Init(cfg)
return nil
}
// MaxDialIsActive checks if the user has enabled the max dial flag.
@@ -78,3 +96,26 @@ func configureMinimumPeers(ctx *cli.Context, cfg *GlobalFlags) {
cfg.MinimumSyncPeers = maxPeers
}
}
// validateStateDiffExponents validates the provided exponents for state diffs with these constraints in mind:
// - Must contain between 1 and 15 values.
// - Exponents must be in strictly decreasing order.
// - Every exponent must be <= 30. (2^30 slots is more than 300 years at 12s slots)
// - The last (smallest) exponent must be >= 5. (This ensures diffs are at least 1 epoch apart)
func validateStateDiffExponents(exponents []int) error {
length := len(exponents)
if length == 0 || length > 15 {
return errors.New("state diff exponents must contain between 1 and 15 values")
}
if exponents[length-1] < 5 {
return errors.New("the last state diff exponent must be at least 5")
}
prev := maxStateDiffExponents + 1
for _, exp := range exponents {
if exp >= prev {
return errors.New("state diff exponents must be in strictly decreasing order, and each exponent must be <= 30")
}
prev = exp
}
return nil
}

View File

@@ -0,0 +1,39 @@
package flags
import (
"strconv"
"testing"
"github.com/OffchainLabs/prysm/v7/testing/require"
)
func TestValidateStateDiffExponents(t *testing.T) {
tests := []struct {
exponents []int
wantErr bool
errMsg string
}{
{exponents: []int{0, 1, 2}, wantErr: true, errMsg: "at least 5"},
{exponents: []int{1, 2, 3}, wantErr: true, errMsg: "at least 5"},
{exponents: []int{9, 8, 4}, wantErr: true, errMsg: "at least 5"},
{exponents: []int{3, 4, 5}, wantErr: true, errMsg: "decreasing"},
{exponents: []int{15, 14, 14, 12, 11}, wantErr: true, errMsg: "decreasing"},
{exponents: []int{15, 14, 13, 12, 11}, wantErr: false},
{exponents: []int{21, 18, 16, 13, 11, 9, 5}, wantErr: false},
{exponents: []int{30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 18, 16, 13, 11, 9, 5}, wantErr: true, errMsg: "between 1 and 15 values"},
{exponents: []int{}, wantErr: true, errMsg: "between 1 and 15 values"},
{exponents: []int{30, 18, 16, 13, 11, 9, 5}, wantErr: false},
{exponents: []int{31, 18, 16, 13, 11, 9, 5}, wantErr: true, errMsg: "<= 30"},
}
for i, tt := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
err := validateStateDiffExponents(tt.exponents)
if tt.wantErr {
require.ErrorContains(t, tt.errMsg, err)
} else {
require.NoError(t, err)
}
})
}
}