diff --git a/docker/localnode/scripts/step4_config_override.sh b/docker/localnode/scripts/step4_config_override.sh index 9f7fd8e024..b3d8f01f3c 100755 --- a/docker/localnode/scripts/step4_config_override.sh +++ b/docker/localnode/scripts/step4_config_override.sh @@ -109,6 +109,16 @@ if [ "$AUTOBAHN" = "true" ]; then # Generate autobahn config using seid seid tendermint gen-autobahn-config $NODE_DIRS --output "$AUTOBAHN_CONFIG" + # For localnode/throughput-test runs we use a much shorter data_prune_after + # than the production default to keep data.State memory bounded during + # sustained load (cosmos-sdk's pruning is "nothing" in this setup). + if command -v jq >/dev/null 2>&1; then + tmp=$(mktemp) + jq '.data_prune_after = "5m0s"' "$AUTOBAHN_CONFIG" > "$tmp" && mv "$tmp" "$AUTOBAHN_CONFIG" + else + sed -i 's|"data_prune_after": *"[^"]*"|"data_prune_after": "5m0s"|' "$AUTOBAHN_CONFIG" + fi + # Inject autobahn config file path into config.toml # Must be placed before any [section] header so TOML parser reads it as a top-level key. if grep -q "autobahn-config-file" ~/.sei/config/config.toml; then diff --git a/sei-tendermint/cmd/tendermint/commands/gen_autobahn_config.go b/sei-tendermint/cmd/tendermint/commands/gen_autobahn_config.go index 9297fa7a19..865abccf5d 100644 --- a/sei-tendermint/cmd/tendermint/commands/gen_autobahn_config.go +++ b/sei-tendermint/cmd/tendermint/commands/gen_autobahn_config.go @@ -77,6 +77,12 @@ Output is written to the file specified by --output.`, AllowEmptyBlocks: true, ViewTimeout: utils.Duration(1500 * time.Millisecond), DialInterval: utils.Duration(10 * time.Second), + // data_prune_after caps the age of in-memory blocks/QCs/AppProposals + // in data.State. 30m gives operators plenty of recent history for + // /block, /tx, etc. while bounding memory under sustained load. + // Test setups (e.g. docker/localnode) can override this to a + // smaller value. + DataPruneAfter: utils.Some(utils.Duration(30 * time.Minute)), } data, err := json.MarshalIndent(cfg, "", " ") diff --git a/sei-tendermint/config/autobahn.go b/sei-tendermint/config/autobahn.go index d27866828b..3aeb493f62 100644 --- a/sei-tendermint/config/autobahn.go +++ b/sei-tendermint/config/autobahn.go @@ -27,6 +27,9 @@ type AutobahnFileConfig struct { ViewTimeout utils.Duration `json:"view_timeout"` PersistentStateDir utils.Option[string] `json:"persistent_state_dir"` DialInterval utils.Duration `json:"dial_interval"` + // DataPruneAfter is the age at which data.State drops in-memory blocks, + // QCs, and AppProposals; nil disables time-based pruning. + DataPruneAfter utils.Option[utils.Duration] `json:"data_prune_after"` } // Validate performs basic validation of the autobahn file config. diff --git a/sei-tendermint/internal/p2p/giga_router.go b/sei-tendermint/internal/p2p/giga_router.go index 5434979ab0..8479ad93f6 100644 --- a/sei-tendermint/internal/p2p/giga_router.go +++ b/sei-tendermint/internal/p2p/giga_router.go @@ -42,6 +42,12 @@ type GigaRouterConfig struct { Producer *producer.Config TxMempool *mempool.TxMempool GenDoc *types.GenesisDoc + // DataPruneAfter, when set, enables time-based pruning of in-memory + // data.State entries (blocks, AppProposals, QCs). Without it the + // in-memory window is bounded only by cosmos-sdk's RetainHeight via + // PruneBefore — which returns 0 for `pruning="nothing"` setups, leaving + // data.State to grow with the chain. + DataPruneAfter utils.Option[time.Duration] } type GigaRouter struct { @@ -84,7 +90,10 @@ func NewGigaRouter(cfg *GigaRouterConfig, key NodeSecretKey) (*GigaRouter, error if err != nil { return nil, fmt.Errorf("data.NewDataWAL(): %w", err) } - dataState, err := data.NewState(&data.Config{Committee: committee}, dataWAL) + dataState, err := data.NewState(&data.Config{ + Committee: committee, + PruneAfter: cfg.DataPruneAfter, + }, dataWAL) if err != nil { return nil, fmt.Errorf("data.NewState(): %w", err) } diff --git a/sei-tendermint/node/setup.go b/sei-tendermint/node/setup.go index 142b9d2961..630e004a8f 100644 --- a/sei-tendermint/node/setup.go +++ b/sei-tendermint/node/setup.go @@ -240,7 +240,7 @@ func buildGigaConfig( } maxGasPerBlock := uint64(genDoc.ConsensusParams.Block.MaxGas) //nolint:gosec // validated > 0 above - return &p2p.GigaRouterConfig{ + gigaCfg := &p2p.GigaRouterConfig{ DialInterval: time.Duration(fc.DialInterval), ValidatorAddrs: validatorAddrs, Consensus: &autobahnConsensus.Config{ @@ -260,7 +260,11 @@ func buildGigaConfig( }, TxMempool: txMempool, GenDoc: genDoc, - }, nil + } + if d, ok := fc.DataPruneAfter.Get(); ok { + gigaCfg.DataPruneAfter = utils.Some(time.Duration(d)) + } + return gigaCfg, nil } func createRouter(