Skip to content

Commit 555f99a

Browse files
committed
updates
1 parent 0d9c0ff commit 555f99a

3 files changed

Lines changed: 11 additions & 19 deletions

File tree

block/internal/syncing/syncer.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,11 @@ func (s *Syncer) TrySyncNextBlock(ctx context.Context, event *common.DAHeightEve
749749
}
750750

751751
// Verify forced inclusion transactions if configured
752+
// TODO: Eventually move VerifyForcedInclusionTxs to a the DA retriever, so verification happens in the background
753+
// This would allow to verify P2P blocks once the node is caught up with DA. This is tricky to implement because for
754+
// P2P blocks, the DA hints are not yet available when synced to the head.
755+
// Another scenario is to setup DA only nodes, made to alert others nodes when the DA layer becomes malicious.
756+
// The flow below allows that.
752757
if event.Source == common.SourceDA {
753758
if err := s.VerifyForcedInclusionTxs(ctx, currentState.DAHeight, data); err != nil {
754759
s.logger.Error().Err(err).Uint64("height", nextHeight).Msg("forced inclusion verification failed")

docs/adr/adr-019-forced-inclusion-mechanism.md

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ based_sequencer = true # Use based sequencer
686686

687687
### Full Node Verification Flow
688688

689-
1. Receive block from DA or P2P
689+
1. Receive block from DA
690690
2. Before applying block:
691691
a. Fetch forced inclusion txs from DA at block's DA height (epoch-based)
692692
b. Build map of transactions in block
@@ -699,6 +699,8 @@ based_sequencer = true # Use based sequencer
699699
h. If txs within grace period: keep in pending queue, allow block
700700
3. Apply block if verification passes
701701

702+
NOTE: P2P nodes only do not proceed to any verification. This is because DA inclusion happens later than block productions, and thus DA hints are added later to broadcasted blocks.
703+
702704
**Grace Period Example** (with base grace period = 1 epoch, `DAEpochForcedInclusion = 50`):
703705

704706
- Forced tx appears in epoch ending at DA height 100
@@ -722,18 +724,6 @@ based_sequencer = true # Use based sequencer
722724

723725
Every `DAEpochForcedInclusion` DA blocks
724726

725-
### Security Considerations
726-
727-
1. **Malicious Proposer Detection**: Full nodes reject blocks missing forced transactions
728-
2. **No Timing Attacks**: Epoch boundaries are deterministic, no time-based logic
729-
3. **Blob Size Limits**: Two-tier size validation prevents DoS
730-
- Absolute limit (1.5MB): Blobs exceeding this are permanently rejected
731-
- Batch limit (`MaxBytes`): Ensures no batch exceeds DA submission limits
732-
4. **Graceful Degradation**: Continues operation if forced inclusion not configured
733-
5. **Height Validation**: Handles "height from future" errors without state corruption
734-
6. **Transaction Preservation**: No valid transactions are lost due to size constraints
735-
7. **Strict MaxBytes Enforcement**: Batches NEVER exceed `req.MaxBytes`, preventing DA layer rejections
736-
737727
**Attack Vectors**:
738728

739729
### Security Considerations
@@ -774,11 +764,9 @@ Accepted and Implemented
774764
### Negative
775765

776766
1. **Increased Latency**: Forced transactions subject to epoch boundaries
777-
2. **DA Dependency**: Requires DA layer to support multiple namespaces
767+
2. **DA Dependency**: Requires DA layer to be enabled on nodes for verification
778768
3. **Higher DA Costs**: Users pay DA posting fees for forced inclusion
779-
4. **Additional Complexity**: New component (DA Retriever) and verification logic with grace period tracking
780-
5. **Epoch Configuration**: Requires setting `DAEpochForcedInclusion` in genesis (consensus parameter)
781-
6. **Grace Period Adjustment**: Grace period is dynamically adjusted based on block fullness to balance censorship detection with operational reliability
769+
4. **Epoch Configuration**: Requires setting `DAEpochForcedInclusion` in genesis (consensus parameter)
782770

783771
### Neutral
784772

test/e2e/evm_force_inclusion_e2e_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,6 @@ func setupFullNodeWithForceInclusionCheck(t *testing.T, sut *SystemUnderTest, fu
401401
// Note: This test simulates the scenario by having the sequencer configured to
402402
// listen to the wrong namespace, while we submit directly to the correct namespace.
403403
func TestEvmSyncerMaliciousSequencerForceInclusionE2E(t *testing.T) {
404-
t.Skip() // Unskip once https://github.com/evstack/ev-node/pull/2963 is merged
405-
406404
sut := NewSystemUnderTest(t)
407405
workDir := t.TempDir()
408406
sequencerHome := filepath.Join(workDir, "sequencer")
@@ -413,6 +411,7 @@ func TestEvmSyncerMaliciousSequencerForceInclusionE2E(t *testing.T) {
413411
t.Log("Malicious sequencer started listening to WRONG forced inclusion namespace")
414412
t.Log("NOTE: Sequencer listens to 'wrong-namespace', won't see txs on 'forced-inc'")
415413

414+
// TODO: disable P2P based on the limitations describes in the ADR.
416415
sequencerP2PAddress := getNodeP2PAddress(t, sut, sequencerHome, endpoints.RollkitRPCPort)
417416
t.Logf("Sequencer P2P address: %s", sequencerP2PAddress)
418417

0 commit comments

Comments
 (0)