Skip to content

Commit 5218b25

Browse files
feat: run the l1 info tree syncer with safe block finality (#1148)
## 🔄 Changes Summary - Change the L1 Info Tree Syncer block finality to `safe`, in order to make `aggoracle` runs faster. Re-introduce `BlockFinality` in the `L1InfoTreeSyncer` config and consequently the `ReorgDetector`. - Simplify `keccak256` hash calculations, by relying on go ethereum library. - Remove `URLRPCL1` config parameters from `Aggoracle` and `L1InfoTreeSync`, since they are unused. - Introduce abstractions for merkle trees, in order to test l1 info tree syncer processor more deeply: - `ReadTreer` – provides read-only access to tree data (roots, leaves, proofs). - `LeafWriter` – defines write operations for adding new leaves to the tree. - `ReorganizeTreer` – extends ReadTreer with the ability to handle blockchain reorgs. - `FullTreer` – combines all capabilities (`ReadTreer`, `LeafWriter`, `ReorganizeTreer`), representing a fully functional, mutable Merkle tree. ## ⚠️ Breaking Changes N/A ## 📋 Config Updates - Re-introduce `L1InfoTreeSync.BlockFinality` config param. - Remove `Aggoracle.URLRPCL1` config param. - Remove `L1InfoTreeSync.URLRPCL1` config param. ## ✅ Testing - 🤖 **Automatic**: [Optional: Enumerate E2E tests] - 🖱️ **Manual**: [Optional: Steps to verify] ## 🐞 Issues - Closes #1170 ## 🔗 Related PRs N/A ## 📝 Notes N/A --------- Co-authored-by: Copilot <[email protected]>
1 parent 92a86b0 commit 5218b25

35 files changed

+2206
-413
lines changed

.mockery.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,7 @@ packages:
135135
filename: "mock_{{ .InterfaceName | snakecase }}.go"
136136
mockname: "{{ .InterfaceName }}Mock"
137137
all: true
138-
138+
github.com/agglayer/aggkit/tree/types:
139+
config:
140+
dir: "{{ .InterfaceDir }}/mocks"
141+
all: true

agglayer/types/types_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,10 +1487,11 @@ func TestImportedBridgeExit_VerifyProofs(t *testing.T) {
14871487
DestinationAddress: common.HexToAddress(fmt.Sprintf("0x%040x", i+1)),
14881488
Amount: big.NewInt(int64(i+1) * 1000),
14891489
}
1490-
require.NoError(t, rollupExitTree.AddLeaf(tx, uint64(i), 0, types.Leaf{
1490+
_, err := rollupExitTree.PutLeaf(tx, uint64(i), 0, types.Leaf{
14911491
Index: uint32(i),
14921492
Hash: bridgeExits[i].Hash(),
1493-
}))
1493+
})
1494+
require.NoError(t, err)
14941495
}
14951496

14961497
require.NoError(t, tx.Commit())
@@ -1514,10 +1515,11 @@ func TestImportedBridgeExit_VerifyProofs(t *testing.T) {
15141515
},
15151516
}
15161517

1517-
require.NoError(t, l1InfoTree.AddLeaf(tx, uint64(i), 0, types.Leaf{
1518+
_, err = l1InfoTree.PutLeaf(tx, uint64(i), 0, types.Leaf{
15181519
Index: uint32(i),
15191520
Hash: l1Leaves[i].Hash(),
1520-
}))
1521+
})
1522+
require.NoError(t, err)
15211523
}
15221524

15231525
require.NoError(t, tx.Commit())

aggoracle/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ var (
1717

1818
type Config struct {
1919
TargetChainType TargetChainType `mapstructure:"TargetChainType"`
20-
URLRPCL1 string `mapstructure:"URLRPCL1"`
2120
WaitPeriodNextGER types.Duration `mapstructure:"WaitPeriodNextGER"`
2221
EVMSender chaingersender.EVMConfig `mapstructure:"EVMSender"`
2322
EnableAggOracleCommittee bool `mapstructure:"EnableAggOracleCommittee"`

aggoracle/e2e_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestEVM_GERInjection(t *testing.T) {
4646
cfg.AggOracleCommitteeCfg.EnableAggOracleCommittee = tt.enableAggOracleCommittee
4747
l1, l2 := helpers.NewSimulatedEVMEnvironment(t, cfg)
4848

49-
for i := 0; i < 10; i++ {
49+
for i := range 10 {
5050
rootHash := common.HexToHash(strconv.Itoa(i))
5151
_, err := l1.GERContract.UpdateExitRoot(l1.Auth, rootHash)
5252
require.NoError(t, err)

aggoracle/oracle.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
// L1InfoTreeSyncer is an interface that defines the methods required to interact with the L1 info tree syncer
1616
type L1InfoTreeSyncer interface {
17-
GetLatestL1InfoLeaf(ctx context.Context) (*l1infotreesync.L1InfoTreeLeaf, error)
17+
GetLatestL1InfoGER(ctx context.Context) (common.Hash, error)
1818
}
1919

2020
// ChainSender is an interface that defines the methods required to send Global Exit Roots (GERs) to the chain
@@ -76,15 +76,13 @@ func (a *AggOracle) processLatestGER(ctx context.Context) error {
7676
a.logger.Debugf("checking for new GERs...")
7777
metrics.IncGERProcessCount()
7878
// Fetch the latest GER
79-
latestL1InfoLeaf, err := a.l1Info.GetLatestL1InfoLeaf(ctx)
79+
latestGER, err := a.l1Info.GetLatestL1InfoGER(ctx)
8080
if err != nil {
8181
metrics.IncGERProcessErrCount()
8282
return err
8383
}
8484

85-
a.logger.Debugf("latest l1 info leaf retrieved: %s", latestL1InfoLeaf.String())
86-
87-
latestGER := latestL1InfoLeaf.GlobalExitRoot
85+
a.logger.Debugf("latest GER retrieved: %s", latestGER.String())
8886

8987
go func() {
9088
start := time.Now()

bridgesync/processor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ func (p *processor) ProcessBlock(ctx context.Context, block sync.Block) error {
839839
}
840840

841841
if event.Bridge != nil {
842-
if err = p.exitTree.AddLeaf(tx, block.Num, event.Bridge.BlockPos, types.Leaf{
842+
if _, err = p.exitTree.PutLeaf(tx, block.Num, event.Bridge.BlockPos, types.Leaf{
843843
Index: event.Bridge.DepositCount,
844844
Hash: event.Bridge.Hash(),
845845
}); err != nil {

cmd/run.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"github.com/agglayer/aggkit/pprof"
4141
"github.com/agglayer/aggkit/prometheus"
4242
"github.com/agglayer/aggkit/reorgdetector"
43+
aggkitsync "github.com/agglayer/aggkit/sync"
4344
aggkittypes "github.com/agglayer/aggkit/types"
4445
"github.com/ethereum/go-ethereum/common"
4546
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -107,7 +108,7 @@ func start(cliCtx *cli.Context) error {
107108
// Create WaitGroup for backfill goroutines synchronization
108109
var backfillWg sync.WaitGroup
109110
var rpcServices []jRPC.Service
110-
l1InfoTreeSync := runL1InfoTreeSyncerIfNeeded(ctx, components, *cfg, l1Client)
111+
l1InfoTreeSync := runL1InfoTreeSyncerIfNeeded(ctx, components, *cfg, reorgDetectorL1, l1Client)
111112
if l1InfoTreeSync != nil {
112113
rpcServices = append(rpcServices, l1InfoTreeSync.GetRPCServices()...)
113114
}
@@ -374,14 +375,14 @@ func createAggSender(
374375
}
375376

376377
func createAggoracle(
377-
ethermanClient *etherman.RollupDataQuerier,
378+
rollupDataQuerier *etherman.RollupDataQuerier,
378379
cfg config.Config,
379-
l1Client,
380+
l1Client aggkittypes.BaseEthereumClienter,
380381
l2Client aggkittypes.BaseEthereumClienter,
381-
l1InfoTreeSyncer *l1infotreesync.L1InfoTreeSync,
382+
l1InfoTreeSyncer aggoracle.L1InfoTreeSyncer,
382383
) *aggoracle.AggOracle {
383384
logger := log.WithFields("module", aggkitcommon.AGGORACLE)
384-
l2ChainID, err := ethermanClient.GetRollupChainID()
385+
l2ChainID, err := rollupDataQuerier.GetRollupChainID()
385386
if err != nil {
386387
logger.Errorf("Failed to retrieve L2ChainID: %v", err)
387388
}
@@ -515,6 +516,7 @@ func runL1InfoTreeSyncerIfNeeded(
515516
ctx context.Context,
516517
components []string,
517518
cfg config.Config,
519+
reorgDetectorL1 aggkitsync.ReorgDetector,
518520
l1Client aggkittypes.BaseEthereumClienter,
519521
) *l1infotreesync.L1InfoTreeSync {
520522
if !isNeeded([]string{
@@ -526,10 +528,9 @@ func runL1InfoTreeSyncerIfNeeded(
526528
l1InfoTreeSync, err := l1infotreesync.New(
527529
ctx,
528530
cfg.L1InfoTreeSync,
529-
aggkittypes.FinalizedBlock,
530531
l1Client,
532+
reorgDetectorL1,
531533
l1infotreesync.FlagNone,
532-
aggkittypes.FinalizedBlock,
533534
)
534535
if err != nil {
535536
log.Fatal(err)
@@ -595,12 +596,14 @@ func runReorgDetectorL1IfNeeded(
595596
cfg *reorgdetector.Config,
596597
) (*reorgdetector.ReorgDetector, chan error) {
597598
if !isNeeded([]string{
598-
aggkitcommon.BRIDGE, aggkitcommon.L1BRIDGESYNC},
599+
aggkitcommon.AGGORACLE, aggkitcommon.AGGSENDER, aggkitcommon.AGGSENDERVALIDATOR,
600+
aggkitcommon.BRIDGE, aggkitcommon.L1BRIDGESYNC, aggkitcommon.L1INFOTREESYNC,
601+
aggkitcommon.L2GERSYNC, aggkitcommon.AGGCHAINPROOFGEN},
599602
components) {
600603
return nil, nil
601604
}
602-
rd := newReorgDetector(cfg, l1Client, reorgdetector.L1)
603605

606+
rd := newReorgDetector(cfg, l1Client, reorgdetector.L1)
604607
errChan := make(chan error)
605608
go func() {
606609
if err := rd.Start(ctx); err != nil {
@@ -674,7 +677,7 @@ func runBridgeSyncL1IfNeeded(
674677
ctx context.Context,
675678
components []string,
676679
cfg bridgesync.Config,
677-
reorgDetectorL1 *reorgdetector.ReorgDetector,
680+
reorgDetectorL1 bridgesync.ReorgDetector,
678681
l1Client aggkittypes.EthClienter,
679682
rollupID uint32,
680683
wg *sync.WaitGroup,

config/config.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ const (
6666
delayBetweenRetriesHint = "AggSender.DelayBeetweenRetries is deprecated, " +
6767
"use AggSender.DelayBetweenRetries instead"
6868
aggOracleBlockFinalityDeprecated = "AggOracle.BlockFinality is deprecated, remove it from configuration"
69-
l1InfoTreeSyncBlockFinalityDeprecated = "L1InfoTreeSync.BlockFinality is deprecated, remove it from configuration"
7069
lastGERSyncDeprecatedHint = "LastGERSync is deprecated, use L2GERSync instead"
7170
lastGERSyncSyncModeDeprecatedHint = "LastGERSync.SyncMode is deprecated, remove it from configuration"
7271
l1NetworkConfigURLDeprecatedHint = "L1NetworkConfig.URL is deprecated, use L1NetworkConfig.RPC.URL instead"
7372
requireValidatorCallDeprecatedHint = "RequireValidatorCall is deprecated, remove it from configuration"
7473
maxSubmitCertificateRateDeprecatedHint = "AggSender.MaxSubmitCertificateRate is deprecated, " +
7574
"remove it from configuration, instead use AggSender.AgglayerClient.APIRateLimits"
7675
networkIDDeprecatedHint = "Common.NetworkID is deprecated, remove it from configuration"
76+
urlRPCL1DeprecatedHint = "URLRPCL1 field is deprecated, remove it from configuration"
7777
)
7878

7979
type DeprecatedFieldsError struct {
@@ -191,10 +191,6 @@ var (
191191
FieldNamePattern: "AggOracle.BlockFinality",
192192
Reason: aggOracleBlockFinalityDeprecated,
193193
},
194-
{
195-
FieldNamePattern: "L1InfoTreeSync.BlockFinality",
196-
Reason: l1InfoTreeSyncBlockFinalityDeprecated,
197-
},
198194
{
199195
FieldNamePattern: "LastGERSync.SyncMode",
200196
Reason: lastGERSyncSyncModeDeprecatedHint,
@@ -227,6 +223,18 @@ var (
227223
FieldNamePattern: "Common.NetworkID",
228224
Reason: networkIDDeprecatedHint,
229225
},
226+
{
227+
FieldNamePattern: "Common.NetworkID",
228+
Reason: networkIDDeprecatedHint,
229+
},
230+
{
231+
FieldNamePattern: "AggOracle.URLRPCL1",
232+
Reason: urlRPCL1DeprecatedHint,
233+
},
234+
{
235+
FieldNamePattern: "L1InfoTreeSync.URLRPCL1",
236+
Reason: urlRPCL1DeprecatedHint,
237+
},
230238
}
231239
)
232240

config/config_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,6 @@ func TestLoadConfigWithDeprecatedFields(t *testing.T) {
155155
PolAddr="{{L1Config.polTokenAddress}}"
156156
ZkEVMAddr="{{L1Config.polygonZkEVMAddress}}"
157157
158-
[L1InfoTreeSync]
159-
BlockFinality = "LatestBlock"
160-
161158
[Etherman]
162159
URL = "{{L1URL}}"
163160
[Etherman.EthermanConfig]
@@ -171,6 +168,10 @@ func TestLoadConfigWithDeprecatedFields(t *testing.T) {
171168
172169
[AggOracle]
173170
BlockFinality = "FinalizedBlock"
171+
URLRPCL1 = "http://localhost:8545"
172+
173+
[L1InfoTreeSync]
174+
URLRPCL1 = "http://localhost:8545"
174175
175176
[LastGERSync]
176177
SyncMode = "Legacy"
@@ -198,10 +199,10 @@ func TestLoadConfigWithDeprecatedFields(t *testing.T) {
198199
require.ErrorContains(t, err, l1NetworkConfigUseRollupAddrHint)
199200
require.ErrorContains(t, err, delayBetweenRetriesHint)
200201
require.ErrorContains(t, err, aggOracleBlockFinalityDeprecated)
201-
require.ErrorContains(t, err, l1InfoTreeSyncBlockFinalityDeprecated)
202202
require.ErrorContains(t, err, lastGERSyncDeprecatedHint)
203203
require.ErrorContains(t, err, lastGERSyncSyncModeDeprecatedHint)
204204
require.ErrorContains(t, err, l1NetworkConfigURLDeprecatedHint)
205205
require.ErrorContains(t, err, requireValidatorCallDeprecatedHint)
206206
require.ErrorContains(t, err, maxSubmitCertificateRateDeprecatedHint)
207+
require.ErrorContains(t, err, urlRPCL1DeprecatedHint)
207208
}

config/default.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ FinalizedBlock = "LatestBlock"
9393
DBPath = "{{PathRWData}}/L1InfoTreeSync.sqlite"
9494
GlobalExitRootAddr = "{{L1NetworkConfig.GlobalExitRootManagerAddr}}"
9595
RollupManagerAddr = "{{L1NetworkConfig.RollupManagerAddr}}"
96+
BlockFinality = "SafeBlock"
9697
SyncBlockChunkSize = 100
97-
URLRPCL1 = "{{L1URL}}"
9898
WaitForNewBlocksPeriod = "100ms"
9999
InitialBlock = {{genesisBlockNumber}}
100100
RetryAfterErrorPeriod = "1s"
@@ -103,7 +103,6 @@ RequireStorageContentCompatibility = {{RequireStorageContentCompatibility}}
103103
104104
[AggOracle]
105105
TargetChainType = "EVM"
106-
URLRPCL1 = "{{L1URL}}"
107106
WaitPeriodNextGER = "10s"
108107
EnableAggOracleCommittee = false
109108
[AggOracle.EVMSender]

0 commit comments

Comments
 (0)