Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5509d38
basic prunning
pthmas Jan 16, 2026
95a3876
prune metadata from ev-node store
pthmas Jan 23, 2026
b8ca7fb
wiring prunning config to go-header
pthmas Jan 23, 2026
d09b803
prune evm exec store
pthmas Jan 26, 2026
c329f76
add parameters validation
pthmas Jan 26, 2026
9ae2f6a
make error handling consistent
pthmas Jan 26, 2026
907f28c
add method to tracedstore to respect interface
pthmas Jan 27, 2026
b022f10
add prune block to mockstore
pthmas Jan 27, 2026
99d586b
fix helper for flag for consistency
pthmas Jan 28, 2026
f798b18
add replace statement for local packages
pthmas Jan 28, 2026
70e4901
flags
pthmas Jan 28, 2026
9315c6c
add safetey mechanism for pruning only da included blocks
pthmas Feb 2, 2026
23af6b7
fix rebase
pthmas Feb 2, 2026
f250b64
remove useless check
pthmas Feb 3, 2026
135c925
use lastprunedheight in Tail() to optimize
pthmas Feb 3, 2026
c1168c9
move pruning from executor to dainclusionloop
pthmas Feb 3, 2026
155ed5c
don't prune go-header store
pthmas Feb 3, 2026
52c005e
update tail function
pthmas Feb 4, 2026
9e046c4
rename execmetapruner to execpruner
pthmas Feb 4, 2026
3c1641b
Update core/execution/execution.go
pthmas Feb 4, 2026
2566dae
Update execution/evm/execution.go
pthmas Feb 4, 2026
535cf1c
trigger pruning every ticker
pthmas Feb 4, 2026
4ee40d6
add store to store adapter
pthmas Feb 4, 2026
a4434d1
invalidate cache store data after pruning
pthmas Feb 4, 2026
86eb1a2
nit
pthmas Feb 4, 2026
ca26acd
move pruning to it's own function
pthmas Feb 10, 2026
b1a6a09
update config.md file
pthmas Feb 10, 2026
fec4fb4
remove ai comments
pthmas Feb 10, 2026
40216c8
Merge branch 'main' into pierrick/prunning
julienrbrt Feb 12, 2026
c01d909
Merge branch 'main' into pierrick/prunning
julienrbrt Feb 12, 2026
9ec6221
feat: add recovery history depth pruner (#3064)
Copilot Feb 12, 2026
9e11d5a
cl
julienrbrt Feb 12, 2026
eedfc18
typo
julienrbrt Feb 12, 2026
050b58c
updates
julienrbrt Feb 12, 2026
ce25d7d
cleanup
julienrbrt Feb 12, 2026
d64b338
updates
julienrbrt Feb 12, 2026
83b4500
delete unused key
julienrbrt Feb 12, 2026
22bc5e7
prevent aggresive pruning
julienrbrt Feb 12, 2026
0d218b6
Merge branch 'main' into pierrick/prunning
julienrbrt Feb 12, 2026
c1ef25b
config
julienrbrt Feb 12, 2026
21b7933
feedback
julienrbrt Feb 12, 2026
8111810
shorter key
julienrbrt Feb 13, 2026
fc38d6c
add logs
julienrbrt Feb 13, 2026
4419111
improve batch size
julienrbrt Feb 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Node pruning support. [#2984](https://github.com/evstack/ev-node/pull/2984)
- Two different sort of pruning implemented:
_Classic pruning_ (`all`): prunes given `HEAD-n` blocks from the databases, including store metadatas.
_Auto Storage Optimization_ (`metadata`): prunes only the state metadatas, keeps all blocks.
By using one or the other, you are losing the ability to rollback or replay transactions earlier than `HEAD-n`.
When using _classic pruning_, you aren't able to fetch blocks prior to `HEAD-n`.

## v1.0.0-rc.4

### Changes
Expand Down
8 changes: 5 additions & 3 deletions apps/evm/cmd/rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ethereum/go-ethereum/common"
ds "github.com/ipfs/go-datastore"
"github.com/rs/zerolog"
"github.com/spf13/cobra"

"github.com/evstack/ev-node/execution/evm"
Expand All @@ -30,6 +31,7 @@ func NewRollbackCmd() *cobra.Command {
if err != nil {
return err
}
logger := rollcmd.SetupLogger(nodeConfig.Log)

goCtx := cmd.Context()
if goCtx == nil {
Expand Down Expand Up @@ -69,7 +71,7 @@ func NewRollbackCmd() *cobra.Command {
}

// rollback execution layer via EngineClient
engineClient, err := createRollbackEngineClient(cmd, rawEvolveDB)
engineClient, err := createRollbackEngineClient(cmd, rawEvolveDB, logger)
if err != nil {
cmd.Printf("Warning: failed to create engine client, skipping EL rollback: %v\n", err)
} else {
Expand Down Expand Up @@ -99,7 +101,7 @@ func NewRollbackCmd() *cobra.Command {
return cmd
}

func createRollbackEngineClient(cmd *cobra.Command, db ds.Batching) (*evm.EngineClient, error) {
func createRollbackEngineClient(cmd *cobra.Command, db ds.Batching, logger zerolog.Logger) (*evm.EngineClient, error) {
ethURL, err := cmd.Flags().GetString(evm.FlagEvmEthURL)
if err != nil {
return nil, fmt.Errorf("failed to get '%s' flag: %w", evm.FlagEvmEthURL, err)
Expand Down Expand Up @@ -128,5 +130,5 @@ func createRollbackEngineClient(cmd *cobra.Command, db ds.Batching) (*evm.Engine
return nil, fmt.Errorf("JWT secret file '%s' is empty", jwtSecretFile)
}

return evm.NewEngineExecutionClient(ethURL, engineURL, jwtSecret, common.Hash{}, common.Address{}, db, false)
return evm.NewEngineExecutionClient(ethURL, engineURL, jwtSecret, common.Hash{}, common.Address{}, db, false, logger)
}
11 changes: 3 additions & 8 deletions apps/evm/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ var RunCmd = &cobra.Command{
}

tracingEnabled := nodeConfig.Instrumentation.IsTracingEnabled()
executor, err := createExecutionClient(cmd, datastore, tracingEnabled)
executor, err := createExecutionClient(cmd, datastore, tracingEnabled, logger)
if err != nil {
return err
}
Expand All @@ -67,11 +67,6 @@ var RunCmd = &cobra.Command{

daClient := block.NewDAClient(blobClient, nodeConfig, logger)

// Attach logger to the EVM engine client if available
if ec, ok := executor.(*evm.EngineClient); ok {
ec.SetLogger(logger.With().Str("module", "engine_client").Logger())
}

headerNamespace := da.NamespaceFromString(nodeConfig.DA.GetNamespace())
dataNamespace := da.NamespaceFromString(nodeConfig.DA.GetDataNamespace())

Expand Down Expand Up @@ -192,7 +187,7 @@ func createSequencer(
return sequencer, nil
}

func createExecutionClient(cmd *cobra.Command, db datastore.Batching, tracingEnabled bool) (execution.Executor, error) {
func createExecutionClient(cmd *cobra.Command, db datastore.Batching, tracingEnabled bool, logger zerolog.Logger) (execution.Executor, error) {
// Read execution client parameters from flags
ethURL, err := cmd.Flags().GetString(evm.FlagEvmEthURL)
if err != nil {
Expand Down Expand Up @@ -237,7 +232,7 @@ func createExecutionClient(cmd *cobra.Command, db datastore.Batching, tracingEna
genesisHash := common.HexToHash(genesisHashStr)
feeRecipient := common.HexToAddress(feeRecipientStr)

return evm.NewEngineExecutionClient(ethURL, engineURL, jwtSecret, genesisHash, feeRecipient, db, tracingEnabled)
return evm.NewEngineExecutionClient(ethURL, engineURL, jwtSecret, genesisHash, feeRecipient, db, tracingEnabled, logger)
}

// addFlags adds flags related to the EVM execution client
Expand Down
9 changes: 5 additions & 4 deletions apps/evm/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module github.com/evstack/ev-node/apps/evm

go 1.25.6

//replace (
// github.com/evstack/ev-node => ../../
// github.com/evstack/ev-node/execution/evm => ../../execution/evm
//)
replace (
github.com/evstack/ev-node => ../../
github.com/evstack/ev-node/core => ../../core
github.com/evstack/ev-node/execution/evm => ../../execution/evm
)

require (
github.com/ethereum/go-ethereum v1.16.8
Expand Down
6 changes: 0 additions & 6 deletions apps/evm/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -411,12 +411,6 @@ github.com/ethereum/go-ethereum v1.16.8 h1:LLLfkZWijhR5m6yrAXbdlTeXoqontH+Ga2f9i
github.com/ethereum/go-ethereum v1.16.8/go.mod h1:Fs6QebQbavneQTYcA39PEKv2+zIjX7rPUZ14DER46wk=
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
github.com/evstack/ev-node v1.0.0-rc.4 h1:Ju7pSETFdadBZxmAj0//4z7hHkXbSRDy9iTzhF60Dew=
github.com/evstack/ev-node v1.0.0-rc.4/go.mod h1:xGCH5NCdGiYk6v3GVPm4NhzAtcKQgnaVnORg8b4tbOk=
github.com/evstack/ev-node/core v1.0.0-rc.1 h1:Dic2PMUMAYUl5JW6DkDj6HXDEWYzorVJQuuUJOV0FjE=
github.com/evstack/ev-node/core v1.0.0-rc.1/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
github.com/evstack/ev-node/execution/evm v1.0.0-rc.3 h1:3o8H1TNywnst56lo2RlS2SXulDfp9yZJtkYYh7ZJrdM=
github.com/evstack/ev-node/execution/evm v1.0.0-rc.3/go.mod h1:VUEEklKoclg45GL7dzLoDwu3UQ4ptT3rF8bw5zUmnRk=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
Expand Down
9 changes: 5 additions & 4 deletions apps/grpc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module github.com/evstack/ev-node/apps/grpc

go 1.25.6

//replace (
// github.com/evstack/ev-node => ../../
// github.com/evstack/ev-node/execution/grpc => ../../execution/grpc
//)
replace (
github.com/evstack/ev-node => ../../
github.com/evstack/ev-node/core => ../../core
github.com/evstack/ev-node/execution/grpc => ../../execution/grpc
)

require (
github.com/evstack/ev-node v1.0.0-rc.4
Expand Down
6 changes: 0 additions & 6 deletions apps/grpc/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,6 @@ github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6Ni
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/evstack/ev-node v1.0.0-rc.4 h1:Ju7pSETFdadBZxmAj0//4z7hHkXbSRDy9iTzhF60Dew=
github.com/evstack/ev-node v1.0.0-rc.4/go.mod h1:xGCH5NCdGiYk6v3GVPm4NhzAtcKQgnaVnORg8b4tbOk=
github.com/evstack/ev-node/core v1.0.0-rc.1 h1:Dic2PMUMAYUl5JW6DkDj6HXDEWYzorVJQuuUJOV0FjE=
github.com/evstack/ev-node/core v1.0.0-rc.1/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
github.com/evstack/ev-node/execution/grpc v1.0.0-rc.1 h1:OzrWLDDY6/9+LWx0XmUqPzxs/CHZRJICOwQ0Me/i6dY=
github.com/evstack/ev-node/execution/grpc v1.0.0-rc.1/go.mod h1:Pr/sF6Zx8am9ZeWFcoz1jYPs0kXmf+OmL8Tz2Gyq7E4=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
Expand Down
5 changes: 4 additions & 1 deletion apps/testapp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module github.com/evstack/ev-node/apps/testapp

go 1.25.6

//replace github.com/evstack/ev-node => ../../
replace (
github.com/evstack/ev-node => ../../.
github.com/evstack/ev-node/core => ../../core
)

require (
github.com/evstack/ev-node v1.0.0-rc.4
Expand Down
4 changes: 0 additions & 4 deletions apps/testapp/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,6 @@ github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6Ni
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/evstack/ev-node v1.0.0-rc.4 h1:Ju7pSETFdadBZxmAj0//4z7hHkXbSRDy9iTzhF60Dew=
github.com/evstack/ev-node v1.0.0-rc.4/go.mod h1:xGCH5NCdGiYk6v3GVPm4NhzAtcKQgnaVnORg8b4tbOk=
github.com/evstack/ev-node/core v1.0.0-rc.1 h1:Dic2PMUMAYUl5JW6DkDj6HXDEWYzorVJQuuUJOV0FjE=
github.com/evstack/ev-node/core v1.0.0-rc.1/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
Expand Down
27 changes: 27 additions & 0 deletions block/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/evstack/ev-node/block/internal/common"
da "github.com/evstack/ev-node/block/internal/da"
"github.com/evstack/ev-node/block/internal/executing"
"github.com/evstack/ev-node/block/internal/pruner"
"github.com/evstack/ev-node/block/internal/reaping"
"github.com/evstack/ev-node/block/internal/submitting"
"github.com/evstack/ev-node/block/internal/syncing"
Expand All @@ -29,6 +30,7 @@ import (
// Components represents the block-related components
type Components struct {
Executor *executing.Executor
Pruner *pruner.Pruner
Reaper *reaping.Reaper
Syncer *syncing.Syncer
Submitter *submitting.Submitter
Expand Down Expand Up @@ -60,6 +62,11 @@ func (bc *Components) Start(ctx context.Context) error {
return fmt.Errorf("failed to start executor: %w", err)
}
}
if bc.Pruner != nil {
if err := bc.Pruner.Start(ctxWithCancel); err != nil {
return fmt.Errorf("failed to start pruner: %w", err)
}
}
if bc.Reaper != nil {
if err := bc.Reaper.Start(ctxWithCancel); err != nil {
return fmt.Errorf("failed to start reaper: %w", err)
Expand Down Expand Up @@ -96,6 +103,11 @@ func (bc *Components) Stop() error {
errs = errors.Join(errs, fmt.Errorf("failed to stop executor: %w", err))
}
}
if bc.Pruner != nil {
if err := bc.Pruner.Stop(); err != nil {
errs = errors.Join(errs, fmt.Errorf("failed to stop pruner: %w", err))
}
}
if bc.Reaper != nil {
if err := bc.Reaper.Stop(); err != nil {
errs = errors.Join(errs, fmt.Errorf("failed to stop reaper: %w", err))
Expand Down Expand Up @@ -166,6 +178,12 @@ func NewSyncComponents(
syncer.SetBlockSyncer(syncing.WithTracingBlockSyncer(syncer))
}

var execPruner coreexecutor.ExecPruner
if p, ok := exec.(coreexecutor.ExecPruner); ok {
execPruner = p
}
pruner := pruner.New(logger, store, execPruner, config.Pruning, config.Node.BlockTime.Duration)

// Create submitter for sync nodes (no signer, only DA inclusion processing)
var daSubmitter submitting.DASubmitterAPI = submitting.NewDASubmitter(daClient, config, genesis, blockOpts, metrics, logger, headerDAHintAppender, dataDAHintAppender)
if config.Instrumentation.IsTracingEnabled() {
Expand All @@ -189,6 +207,7 @@ func NewSyncComponents(
Syncer: syncer,
Submitter: submitter,
Cache: cacheManager,
Pruner: pruner,
errorCh: errorCh,
}, nil
}
Expand Down Expand Up @@ -248,6 +267,12 @@ func NewAggregatorComponents(
executor.SetBlockProducer(executing.WithTracingBlockProducer(executor))
}

var execPruner coreexecutor.ExecPruner
if p, ok := exec.(coreexecutor.ExecPruner); ok {
execPruner = p
}
pruner := pruner.New(logger, store, execPruner, config.Pruning, config.Node.BlockTime.Duration)

reaper, err := reaping.NewReaper(
exec,
sequencer,
Expand All @@ -264,6 +289,7 @@ func NewAggregatorComponents(
if config.Node.BasedSequencer { // no submissions needed for bases sequencer
return &Components{
Executor: executor,
Pruner: pruner,
Reaper: reaper,
Cache: cacheManager,
errorCh: errorCh,
Expand All @@ -290,6 +316,7 @@ func NewAggregatorComponents(

return &Components{
Executor: executor,
Pruner: pruner,
Reaper: reaper,
Submitter: submitter,
Cache: cacheManager,
Expand Down
2 changes: 2 additions & 0 deletions block/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func TestNewSyncComponents_Creation(t *testing.T) {
assert.NotNil(t, components.Syncer)
assert.NotNil(t, components.Submitter)
assert.NotNil(t, components.Cache)
assert.NotNil(t, components.Pruner)
assert.NotNil(t, components.errorCh)
assert.Nil(t, components.Executor) // Sync nodes don't have executors
}
Expand Down Expand Up @@ -183,6 +184,7 @@ func TestNewAggregatorComponents_Creation(t *testing.T) {
assert.NotNil(t, components.Executor)
assert.NotNil(t, components.Submitter)
assert.NotNil(t, components.Cache)
assert.NotNil(t, components.Pruner)
assert.NotNil(t, components.errorCh)
assert.Nil(t, components.Syncer) // Aggregator nodes currently don't create syncers in this constructor
}
Expand Down
Loading
Loading