Skip to content
Draft
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
cbb6451
feat: forced inclusion for executor
julienrbrt Oct 30, 2025
eb5144c
add disclaimer
julienrbrt Oct 30, 2025
b8a4969
Merge branch 'main' into julien/fi
julienrbrt Nov 1, 2025
ed89c2b
Merge branch 'main' into julien/fi
julienrbrt Nov 4, 2025
3dd46e8
add for sync node
julienrbrt Nov 5, 2025
0f8d7d5
updates
julienrbrt Nov 5, 2025
c0a38c7
based
julienrbrt Nov 5, 2025
97345be
fix mock
julienrbrt Nov 5, 2025
2c5fdbf
updates
julienrbrt Nov 5, 2025
16889f5
move to sequencer
julienrbrt Nov 5, 2025
4f808c8
simplify
julienrbrt Nov 5, 2025
0c06e1c
fix
julienrbrt Nov 5, 2025
0a7c258
refactor: remove adaptor + add comments (feedback 1/n)
julienrbrt Nov 6, 2025
2d6d933
fix: add description error and halt node (feedback 2/n)
julienrbrt Nov 6, 2025
1bef7d9
refactor: add limits check and improvements (feedback 3/n)
julienrbrt Nov 6, 2025
c417d0a
test: add max size test
julienrbrt Nov 6, 2025
e0dc6b2
feat: add epoch calculation, set sequencer height, improve fetching
julienrbrt Nov 6, 2025
bd0a9a1
lint
julienrbrt Nov 6, 2025
975a3ef
Merge branch 'main' into julien/fi
julienrbrt Nov 6, 2025
9f03c71
Update adr-019-forced-inclusion-mechanism.md
julienrbrt Nov 10, 2025
c3bac1b
extract epoch calculation
julienrbrt Nov 10, 2025
3c4132d
move da epoch from config to genesis
julienrbrt Nov 10, 2025
09f55ef
Merge branch 'main' into julien/fi
julienrbrt Nov 10, 2025
ecc55ce
fixes
julienrbrt Nov 10, 2025
e192c82
fixes
julienrbrt Nov 10, 2025
e13bd5a
Merge branch 'main' into julien/fi
julienrbrt Nov 10, 2025
cdd8afa
cleanup
julienrbrt Nov 10, 2025
272027d
update executor for based sequencer flow
julienrbrt Nov 11, 2025
bb9284d
Merge branch 'main' into julien/fi
julienrbrt Nov 11, 2025
47bfd38
add size filtering in da retriever
julienrbrt Nov 12, 2025
cb3135d
use checksum as key
julienrbrt Nov 12, 2025
2e3472f
extract errors
julienrbrt Nov 13, 2025
8ebeec3
Merge branch 'main' into julien/fi
julienrbrt Nov 13, 2025
ef8849a
merge fixes
julienrbrt Nov 13, 2025
27c1390
fix unit tests
julienrbrt Nov 13, 2025
6ba4059
remove nil check
julienrbrt Nov 13, 2025
d89fed8
split manager in two
julienrbrt Nov 13, 2025
18ce1ce
fix epochs calculation
julienrbrt Nov 13, 2025
0d790ef
disable force inclusion in prod
julienrbrt Nov 13, 2025
b39f28c
add changelog
julienrbrt Nov 13, 2025
9896bc6
feat: optimize force inclusion fetching
julienrbrt Nov 14, 2025
d60b5e7
improve api
julienrbrt Nov 14, 2025
60ad091
refactor(block): extract da logic into da client and fi retriever (#2…
julienrbrt Nov 17, 2025
27efa13
Merge branch 'main' into julien/fi
julienrbrt Nov 17, 2025
4f6ea3f
remove file
julienrbrt Nov 17, 2025
c65c330
update adr with ai
julienrbrt Nov 17, 2025
36f3d0e
feat: merge julien/fi into julien/async-fi
julienrbrt Nov 17, 2025
096d70e
rebase
julienrbrt Nov 17, 2025
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
4 changes: 2 additions & 2 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ packages:
filename: external/hstore.go
github.com/evstack/ev-node/block/internal/syncing:
interfaces:
daRetriever:
DARetriever:
config:
dir: ./block/internal/syncing
pkgname: syncing
filename: syncer_mock.go
filename: da_retriever_mock.go
p2pHandler:
config:
dir: ./block/internal/syncing
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Enhanced health check system with separate liveness (`/health/live`) and readiness (`/health/ready`) HTTP endpoints. Readiness endpoint includes P2P listening check and aggregator block production rate validation (5x block time threshold). ([#2800](https://github.com/evstack/ev-node/pull/2800))
- Implement forced inclusion and based sequencing ([#2797](https://github.com/evstack/ev-node/pull/2797))
This changes requires to add a `da_epoch_forced_inclusion` field in `genesis.json` file.
To enable this feature, set the force inclusion namespace in the `evnode.yaml`.

### Changed

Expand Down
97 changes: 75 additions & 22 deletions apps/evm/single/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,27 @@ import (
"os"
"path/filepath"

"github.com/evstack/ev-node/core/da"
"github.com/evstack/ev-node/da/jsonrpc"
"github.com/evstack/ev-node/node"
"github.com/evstack/ev-node/sequencers/single"

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

"github.com/evstack/ev-node/execution/evm"

"github.com/evstack/ev-node/block"
"github.com/evstack/ev-node/core/da"
"github.com/evstack/ev-node/core/execution"
coresequencer "github.com/evstack/ev-node/core/sequencer"
"github.com/evstack/ev-node/da/jsonrpc"
"github.com/evstack/ev-node/execution/evm"
"github.com/evstack/ev-node/node"
rollcmd "github.com/evstack/ev-node/pkg/cmd"
"github.com/evstack/ev-node/pkg/config"
"github.com/evstack/ev-node/pkg/genesis"
genesispkg "github.com/evstack/ev-node/pkg/genesis"
"github.com/evstack/ev-node/pkg/p2p"
"github.com/evstack/ev-node/pkg/p2p/key"
"github.com/evstack/ev-node/pkg/store"
"github.com/evstack/ev-node/sequencers/based"
"github.com/evstack/ev-node/sequencers/single"
)

var RunCmd = &cobra.Command{
Expand Down Expand Up @@ -73,21 +77,8 @@ var RunCmd = &cobra.Command{
logger.Warn().Msg("da_start_height is not set in genesis.json, ask your chain developer")
}

singleMetrics, err := single.DefaultMetricsProvider(nodeConfig.Instrumentation.IsPrometheusEnabled())(genesis.ChainID)
if err != nil {
return err
}

sequencer, err := single.NewSequencer(
context.Background(),
logger,
datastore,
&daJrpc.DA,
[]byte(genesis.ChainID),
nodeConfig.Node.BlockTime.Duration,
singleMetrics,
nodeConfig.Node.Aggregator,
)
// Create sequencer based on configuration
sequencer, err := createSequencer(context.Background(), logger, datastore, &daJrpc.DA, nodeConfig, genesis)
if err != nil {
return err
}
Expand All @@ -111,6 +102,68 @@ func init() {
addFlags(RunCmd)
}

// createSequencer creates a sequencer based on the configuration.
// If BasedSequencer is enabled, it creates a based sequencer that fetches transactions from DA.
// Otherwise, it creates a single (traditional) sequencer.
func createSequencer(
ctx context.Context,
logger zerolog.Logger,
datastore datastore.Batching,
da da.DA,
nodeConfig config.Config,
genesis genesis.Genesis,
) (coresequencer.Sequencer, error) {
daRetriever, err := block.NewDARetriever(da, nodeConfig, genesis, logger)
if err != nil {
return nil, fmt.Errorf("failed to create DA retriever: %w", err)
}

if nodeConfig.Node.BasedSequencer {
// Based sequencer mode - fetch transactions only from DA
if !nodeConfig.Node.Aggregator {
return nil, fmt.Errorf("based sequencer mode requires aggregator mode to be enabled")
}

basedSeq := based.NewBasedSequencer(daRetriever, da, nodeConfig, genesis, logger)

logger.Info().
Str("forced_inclusion_namespace", nodeConfig.DA.GetForcedInclusionNamespace()).
Uint64("da_epoch", genesis.DAEpochForcedInclusion).
Msg("based sequencer initialized")

return basedSeq, nil
}

singleMetrics, err := single.NopMetrics()
if err != nil {
return nil, fmt.Errorf("failed to create single sequencer metrics: %w", err)
}

sequencer, err := single.NewSequencer(
ctx,
logger,
datastore,
da,
[]byte(genesis.ChainID),
nodeConfig.Node.BlockTime.Duration,
singleMetrics,
nodeConfig.Node.Aggregator,
1000,
daRetriever,
genesis,
)
if err != nil {
return nil, fmt.Errorf("failed to create single sequencer: %w", err)
}

logger.Info().
Bool("forced_inclusion_enabled", daRetriever != nil).
Str("forced_inclusion_namespace", nodeConfig.DA.GetForcedInclusionNamespace()).
Msg("single sequencer initialized")

return sequencer, nil
}

func createExecutionClient(cmd *cobra.Command) (execution.Executor, error) {
// Read execution client parameters from flags
ethURL, err := cmd.Flags().GetString(evm.FlagEvmEthURL)
Expand Down
12 changes: 6 additions & 6 deletions apps/evm/single/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ go 1.24.6

replace github.com/celestiaorg/go-header => github.com/julienrbrt/go-header v0.0.0-20251008134330-747c8c192fa8 // TODO: to remove after https://github.com/celestiaorg/go-header/pull/347

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

require (
github.com/celestiaorg/go-header v0.7.3
Expand All @@ -14,6 +18,7 @@ require (
github.com/evstack/ev-node/da v1.0.0-beta.5
github.com/evstack/ev-node/execution/evm v1.0.0-beta.3
github.com/ipfs/go-datastore v0.9.0
github.com/rs/zerolog v1.34.0
github.com/spf13/cobra v1.10.1
)

Expand Down Expand Up @@ -145,7 +150,6 @@ require (
github.com/quic-go/quic-go v0.54.1 // indirect
github.com/quic-go/webtransport-go v0.9.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rs/zerolog v1.34.0 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
Expand Down Expand Up @@ -191,7 +195,3 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.4.1 // indirect
)

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

replace github.com/evstack/ev-node/da => ../../../da
88 changes: 71 additions & 17 deletions apps/grpc/single/cmd/run.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
package cmd

import (
"context"
"fmt"
"path/filepath"

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

"github.com/evstack/ev-node/block"
"github.com/evstack/ev-node/core/da"
"github.com/evstack/ev-node/core/execution"
coresequencer "github.com/evstack/ev-node/core/sequencer"
"github.com/evstack/ev-node/da/jsonrpc"
executiongrpc "github.com/evstack/ev-node/execution/grpc"
"github.com/evstack/ev-node/node"
rollcmd "github.com/evstack/ev-node/pkg/cmd"
"github.com/evstack/ev-node/pkg/config"
"github.com/evstack/ev-node/pkg/genesis"
rollgenesis "github.com/evstack/ev-node/pkg/genesis"
"github.com/evstack/ev-node/pkg/p2p"
"github.com/evstack/ev-node/pkg/p2p/key"
"github.com/evstack/ev-node/pkg/store"
"github.com/evstack/ev-node/sequencers/based"
"github.com/evstack/ev-node/sequencers/single"
)

Expand Down Expand Up @@ -73,23 +80,8 @@ The execution client must implement the Evolve execution gRPC interface.`,
logger.Warn().Msg("da_start_height is not set in genesis.json, ask your chain developer")
}

// Create metrics provider
singleMetrics, err := single.DefaultMetricsProvider(nodeConfig.Instrumentation.IsPrometheusEnabled())(genesis.ChainID)
if err != nil {
return err
}

// Create sequencer
sequencer, err := single.NewSequencer(
cmd.Context(),
logger,
datastore,
&daJrpc.DA,
[]byte(genesis.ChainID),
nodeConfig.Node.BlockTime.Duration,
singleMetrics,
nodeConfig.Node.Aggregator,
)
// Create sequencer based on configuration
sequencer, err := createSequencer(cmd.Context(), logger, datastore, &daJrpc.DA, nodeConfig, genesis)
if err != nil {
return err
}
Expand Down Expand Up @@ -119,6 +111,68 @@ func init() {
addGRPCFlags(RunCmd)
}

// createSequencer creates a sequencer based on the configuration.
// If BasedSequencer is enabled, it creates a based sequencer that fetches transactions from DA.
// Otherwise, it creates a single (traditional) sequencer.
func createSequencer(
ctx context.Context,
logger zerolog.Logger,
datastore datastore.Batching,
da da.DA,
nodeConfig config.Config,
genesis genesis.Genesis,
) (coresequencer.Sequencer, error) {
daRetriever, err := block.NewDARetriever(da, nodeConfig, genesis, logger)
if err != nil {
return nil, fmt.Errorf("failed to create DA retriever: %w", err)
}

if nodeConfig.Node.BasedSequencer {
// Based sequencer mode - fetch transactions only from DA
if !nodeConfig.Node.Aggregator {
return nil, fmt.Errorf("based sequencer mode requires aggregator mode to be enabled")
}

basedSeq := based.NewBasedSequencer(daRetriever, da, nodeConfig, genesis, logger)

logger.Info().
Str("forced_inclusion_namespace", nodeConfig.DA.GetForcedInclusionNamespace()).
Uint64("da_epoch", genesis.DAEpochForcedInclusion).
Msg("based sequencer initialized")

return basedSeq, nil
}

singleMetrics, err := single.NopMetrics()
if err != nil {
return nil, fmt.Errorf("failed to create single sequencer metrics: %w", err)
}

sequencer, err := single.NewSequencer(
ctx,
logger,
datastore,
da,
[]byte(genesis.ChainID),
nodeConfig.Node.BlockTime.Duration,
singleMetrics,
nodeConfig.Node.Aggregator,
1000,
daRetriever,
genesis,
)
if err != nil {
return nil, fmt.Errorf("failed to create single sequencer: %w", err)
}

logger.Info().
Bool("forced_inclusion_enabled", daRetriever != nil).
Str("forced_inclusion_namespace", nodeConfig.DA.GetForcedInclusionNamespace()).
Msg("single sequencer initialized")

return sequencer, nil
}

// createGRPCExecutionClient creates a new gRPC execution client from command flags
func createGRPCExecutionClient(cmd *cobra.Command) (execution.Executor, error) {
// Get the gRPC executor URL from flags
Expand Down
12 changes: 5 additions & 7 deletions apps/grpc/single/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require (
github.com/evstack/ev-node/core v1.0.0-beta.4
github.com/evstack/ev-node/da v1.0.0-beta.5
github.com/evstack/ev-node/execution/grpc v0.0.0
github.com/ipfs/go-datastore v0.9.0
github.com/rs/zerolog v1.34.0
github.com/spf13/cobra v1.10.1
)

Expand Down Expand Up @@ -49,7 +51,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/ipfs/boxo v0.35.0 // indirect
github.com/ipfs/go-cid v0.5.0 // indirect
github.com/ipfs/go-datastore v0.9.0 // indirect
github.com/ipfs/go-ds-badger4 v0.1.8 // indirect
github.com/ipfs/go-log/v2 v2.8.1 // indirect
github.com/ipld/go-ipld-prime v0.21.0 // indirect
Expand All @@ -73,7 +74,7 @@ require (
github.com/libp2p/go-reuseport v0.4.0 // indirect
github.com/libp2p/go-yamux/v5 v5.0.1 // indirect
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/miekg/dns v1.1.68 // indirect
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
Expand Down Expand Up @@ -123,7 +124,6 @@ require (
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.1 // indirect
github.com/quic-go/webtransport-go v0.9.0 // indirect
github.com/rs/zerolog v1.34.0 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
Expand Down Expand Up @@ -167,9 +167,7 @@ require (

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

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

replace github.com/evstack/ev-node/da => ../../../da
3 changes: 2 additions & 1 deletion apps/grpc/single/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,9 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk=
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
Expand Down
Loading
Loading