Skip to content

Commit 58df585

Browse files
authored
chore: connect visualiser (#2705)
<!-- Please read and fill out this form before submitting your PR. Please make sure you have reviewed our contributors guide before submitting your first PR. NOTE: PR titles should follow semantic commits: https://www.conventionalcommits.org/en/v1.0.0/ --> ## Overview <!-- Please provide an explanation of the PR, including the appropriate context, background, goal, and rationale. If there is an issue with this information, please provide a tl;dr and link the issue. Ex: Closes #<issue number> -->
1 parent 51283d0 commit 58df585

File tree

6 files changed

+49
-5
lines changed

6 files changed

+49
-5
lines changed

block/internal/submitting/da_submitter.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,19 @@ func NewDASubmitter(
134134
options common.BlockOptions,
135135
logger zerolog.Logger,
136136
) *DASubmitter {
137+
daSubmitterLogger := logger.With().Str("component", "da_submitter").Logger()
138+
139+
if config.RPC.EnableDAVisualization {
140+
visualizerLogger := logger.With().Str("component", "da_visualization").Logger()
141+
server.SetDAVisualizationServer(server.NewDAVisualizationServer(da, visualizerLogger, config.Node.Aggregator))
142+
}
137143

138144
return &DASubmitter{
139145
da: da,
140146
config: config,
141147
genesis: genesis,
142148
options: options,
143-
logger: logger.With().Str("component", "da_submitter").Logger(),
149+
logger: daSubmitterLogger,
144150
namespaceBz: coreda.NamespaceFromString(config.DA.GetNamespace()).Bytes(),
145151
namespaceDataBz: coreda.NamespaceFromString(config.DA.GetDataNamespace()).Bytes(),
146152
}

block/internal/submitting/da_submitter_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
coreda "github.com/evstack/ev-node/core/da"
1919
"github.com/evstack/ev-node/pkg/config"
2020
"github.com/evstack/ev-node/pkg/genesis"
21+
"github.com/evstack/ev-node/pkg/rpc/server"
2122
"github.com/evstack/ev-node/pkg/signer"
2223
"github.com/evstack/ev-node/pkg/signer/noop"
2324
"github.com/evstack/ev-node/pkg/store"
@@ -83,6 +84,27 @@ func TestDASubmitter_NewDASubmitter(t *testing.T) {
8384
assert.NotNil(t, submitter.genesis)
8485
}
8586

87+
func TestNewDASubmitterSetsVisualizerWhenEnabled(t *testing.T) {
88+
t.Helper()
89+
defer server.SetDAVisualizationServer(nil)
90+
91+
cfg := config.DefaultConfig()
92+
cfg.RPC.EnableDAVisualization = true
93+
cfg.Node.Aggregator = true
94+
95+
dummyDA := coreda.NewDummyDA(10_000_000, 0, 0, 10*time.Millisecond)
96+
97+
NewDASubmitter(
98+
dummyDA,
99+
cfg,
100+
genesis.Genesis{},
101+
common.DefaultBlockOptions(),
102+
zerolog.Nop(),
103+
)
104+
105+
require.NotNil(t, server.GetDAVisualizationServer())
106+
}
107+
86108
func TestDASubmitter_SubmitHeaders_Success(t *testing.T) {
87109
submitter, st, cm, _, gen := setupDASubmitterTest(t)
88110
ctx := context.Background()

block/internal/submitting/submitter_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/evstack/ev-node/block/internal/common"
2020
"github.com/evstack/ev-node/pkg/config"
2121
"github.com/evstack/ev-node/pkg/genesis"
22+
"github.com/evstack/ev-node/pkg/rpc/server"
2223
"github.com/evstack/ev-node/pkg/signer"
2324
"github.com/evstack/ev-node/pkg/store"
2425
testmocks "github.com/evstack/ev-node/test/mocks"
@@ -141,11 +142,16 @@ func TestSubmitter_processDAInclusionLoop_advances(t *testing.T) {
141142
ctx, cancel := context.WithCancel(context.Background())
142143
defer cancel()
143144

145+
// Clean up any existing visualization server
146+
defer server.SetDAVisualizationServer(nil)
147+
server.SetDAVisualizationServer(nil)
148+
144149
cm, st := newTestCacheAndStore(t)
145150

146151
// small block time to tick quickly
147152
cfg := config.DefaultConfig()
148153
cfg.DA.BlockTime.Duration = 5 * time.Millisecond
154+
cfg.RPC.EnableDAVisualization = false // Ensure visualization is disabled
149155
metrics := common.PrometheusMetrics("test")
150156

151157
exec := testmocks.NewMockExecutor(t)

docs/learn/specs/block-manager.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,20 +595,20 @@ When both header and data are available for a height:
595595

596596
The components communicate through well-defined interfaces:
597597

598-
#### Executor ↔ Core Executor:
598+
#### Executor ↔ Core Executor
599599

600600
- `InitChain`: initializes the chain state with the given genesis time, initial height, and chain ID using `InitChainSync` on the executor to obtain initial `appHash` and initialize the state.
601601
- `CreateBlock`: prepares a block with transactions from the provided batch data.
602602
- `ApplyBlock`: validates the block, executes the block (apply transactions), captures validator updates, and returns updated state.
603603
- `SetFinal`: marks the block as final when both its header and data are confirmed on the DA layer.
604604
- `GetTxs`: retrieves transactions from the application (used by Reaper component).
605605

606-
#### Reaper ↔ Sequencer:
606+
#### Reaper ↔ Sequencer
607607

608608
- `GetNextBatch`: retrieves the next batch of transactions to include in a block.
609609
- `VerifyBatch`: validates that a batch came from the expected sequencer.
610610

611-
#### Submitter/Syncer ↔ DA Layer:
611+
#### Submitter/Syncer ↔ DA Layer
612612

613613
- `Submit`: submits headers or data blobs to the DA network.
614614
- `Get`: retrieves headers or data blobs from the DA network.
@@ -617,17 +617,20 @@ The components communicate through well-defined interfaces:
617617
## Assumptions and Considerations
618618

619619
### Component Architecture
620+
620621
- The block package uses a modular component architecture instead of a monolithic manager
621622
- Components are created based on node type: aggregator nodes get all components, non-aggregator nodes only get synchronization components
622623
- Each component has a specific responsibility and communicates through well-defined interfaces
623624
- Components share a common Cache Manager for coordination and state tracking
624625

625626
### Initialization and State Management
627+
626628
- Components load the initial state from the local store and use genesis if not found in the local store, when the node (re)starts
627629
- The default mode for aggregator nodes is normal (not lazy)
628630
- Components coordinate through channels and shared cache structures
629631

630632
### Block Production (Executor Component)
633+
631634
- The Executor can produce empty blocks
632635
- In lazy aggregation mode, the Executor maintains consistency with the DA layer by producing empty blocks at regular intervals, ensuring a 1:1 mapping between DA layer blocks and execution layer blocks
633636
- The lazy aggregation mechanism uses a dual timer approach:
@@ -637,6 +640,7 @@ The components communicate through well-defined interfaces:
637640
- Transaction notifications from the `Reaper` to the `Executor` are handled via a non-blocking notification channel (`txNotifyCh`) to prevent backpressure
638641

639642
### DA Submission (Submitter Component)
643+
640644
- The Submitter enforces `MaxPendingHeadersAndData` limit to prevent unbounded growth of pending queues during DA submission issues
641645
- Headers and data are submitted separately to the DA layer using different namespaces, supporting the header/data separation architecture
642646
- The Cache Manager uses persistent caches for headers and data to track seen items and DA inclusion status
@@ -645,16 +649,19 @@ The components communicate through well-defined interfaces:
645649
- Gas price management in the Submitter includes automatic adjustment with `GasMultiplier` on DA submission retries
646650

647651
### Storage and Persistence
652+
648653
- Components use persistent storage (disk) when the `root_dir` and `db_path` configuration parameters are specified in `config.yaml` file under the app directory. If these configuration parameters are not specified, the in-memory storage is used, which will not be persistent if the node stops
649654
- The Syncer does not re-apply blocks when they transition from soft confirmed to DA included status. The block is only marked DA included in the caches
650655
- Header and data stores use separate prefixes for isolation in the underlying database
651656
- The genesis `ChainID` is used to create separate `PubSubTopID`s for headers and data in go-header
652657

653658
### P2P and Synchronization
659+
654660
- Block sync over the P2P network works only when a full node is connected to the P2P network by specifying the initial seeds to connect to via `P2PConfig.Seeds` configuration parameter when starting the full node
655661
- Node's context is passed down to all components to support graceful shutdown and cancellation
656662

657663
### Architecture Design Decisions
664+
658665
- The Executor supports custom signature payload providers for headers, enabling flexible signing schemes
659666
- The component architecture supports the separation of header and data structures in Evolve. This allows for expanding the sequencing scheme beyond single sequencing and enables the use of a decentralized sequencer mode. For detailed information on this architecture, see the [Header and Data Separation ADR](../../adr/adr-014-header-and-data-separation.md)
660667
- Components process blocks with a minimal header format, which is designed to eliminate dependency on CometBFT's header format and can be used to produce an execution layer tailored header if needed. For details on this header structure, see the [Evolve Minimal Header](../../adr/adr-015-rollkit-minimal-header.md) specification

docs/learn/specs/full_node.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ The [Store] is initialized with `DefaultStore`, an implementation of the [store
3535
The [Block Components] provide a modular architecture for managing block-related operations. Instead of a single monolithic manager, the system uses specialized components:
3636

3737
**For Aggregator Nodes:**
38+
3839
- **Executor**: Block production (normal and lazy modes) and state transitions
3940
- **Reaper**: Transaction collection and submission to sequencer
4041
- **Submitter**: Header and data submission to DA layer
4142
- **Syncer**: Block retrieval and synchronization from DA and P2P
4243
- **Cache Manager**: Coordination and tracking across all components
4344

4445
**For Non-Aggregator Nodes:**
46+
4547
- **Syncer**: Block retrieval and synchronization from DA and P2P
4648
- **Cache Manager**: Tracking and caching of synchronized blocks
4749

pkg/config/defaults.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ func DefaultConfig() Config {
7474
SignerPath: "config",
7575
},
7676
RPC: RPCConfig{
77-
Address: "127.0.0.1:7331",
77+
Address: "127.0.0.1:7331",
78+
EnableDAVisualization: false,
7879
},
7980
}
8081
}

0 commit comments

Comments
 (0)