Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions aggsender/aggsender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func TestConfigString(t *testing.T) {
"RequireNoFEPBlockGap: false\n"+
"RetriesToBuildAndSendCertificate: RetryPolicyConfig{Mode: , Config: RetryDelaysConfig{Delays: [], MaxRetries: NO RETRIES}}\n"+
"StorageRetainCertificatesPolicy: retain all certificates, keep history: false\n"+
"MaxLogBlockRange: 0\n"+
"BlockFinalityForL1InfoTree: FinalizedBlock\n"+
"TriggerCertMode: Auto\nTriggerEpochBased: EpochNotificationPercentage: 50\n",
config.AgglayerClient.String())
Expand Down
5 changes: 3 additions & 2 deletions aggsender/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ type Config struct {
CommitteeOverride query.CommitteeOverride `mapstructure:"CommitteeOverride"`
// AgglayerBridgeL2Addr is the address of the bridge L2 sovereign contract on L2 sovereign chain
AgglayerBridgeL2Addr ethCommon.Address `mapstructure:"AgglayerBridgeL2Addr"`
// UnsetClaimsMaxLogBlockRange is the proactive max block range for eth_getLogs queries when fetching unset claims.
// MaxLogBlockRange is the proactive max block range for eth_getLogs queries issued by AggSender.
// 0 means disabled.
UnsetClaimsMaxLogBlockRange uint64 `mapstructure:"UnsetClaimsMaxLogBlockRange"`
MaxLogBlockRange uint64 `mapstructure:"MaxLogBlockRange"`
// BlockFinalityForL1InfoTree indicates the block finality to use when querying for L1InfoRoot to use
BlockFinalityForL1InfoTree aggkittypes.BlockNumberFinality `jsonschema:"enum=LatestBlock, enum=SafeBlock, enum=PendingBlock, enum=FinalizedBlock, enum=EarliestBlock" mapstructure:"BlockFinalityForL1InfoTree"` //nolint:lll
// TriggerCertMode is the mode used to trigger certificate sending
Expand Down Expand Up @@ -172,6 +172,7 @@ func (c Config) String() string {
"RequireNoFEPBlockGap: " + fmt.Sprintf("%t", c.RequireNoFEPBlockGap) + "\n" +
"RetriesToBuildAndSendCertificate: " + c.RetriesToBuildAndSendCertificate.String() + "\n" +
"StorageRetainCertificatesPolicy: " + c.StorageRetainCertificatesPolicy.String() + "\n" +
"MaxLogBlockRange: " + fmt.Sprintf("%d", c.MaxLogBlockRange) + "\n" +
"BlockFinalityForL1InfoTree: " + c.BlockFinalityForL1InfoTree.String() + "\n" +
"TriggerCertMode: " + c.TriggerCertMode.String() + "\n" +
"TriggerEpochBased: " + c.TriggerEpochBased.String() + "\n"
Expand Down
17 changes: 11 additions & 6 deletions aggsender/flows/builder_flow_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

var (
// l2GERReaderFactory is a factory function to create L2 GER reader
l2GERReaderFactory = l2gersync.NewL2EVMGERReader
l2GERReaderFactory = l2gersync.NewL2EVMGERReaderWithMaxLogBlockRange
)

// NewBuilderFlow creates a new AggsenderBuilderFlow based on the provided configuration.
Expand Down Expand Up @@ -55,7 +55,7 @@ func NewBuilderFlow(
true, // fullClaims required (with calldata)
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.UnsetClaimsMaxLogBlockRange,
cfg.MaxLogBlockRange,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
certQuerier,
Expand Down Expand Up @@ -107,7 +107,7 @@ func NewBuilderFlow(
true, // full claims required (with calldata)
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.UnsetClaimsMaxLogBlockRange,
cfg.MaxLogBlockRange,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
certQuerier,
Expand All @@ -117,7 +117,12 @@ func NewBuilderFlow(
return nil, fmt.Errorf("failed to create common flow components: %w", err)
}

l2GERReader, err := l2GERReaderFactory(cfg.GlobalExitRootL2Addr, l2Client, l1InfoTreeSyncer)
l2GERReader, err := l2GERReaderFactory(
cfg.GlobalExitRootL2Addr,
l2Client,
l1InfoTreeSyncer,
cfg.MaxLogBlockRange,
)
if err != nil {
return nil, fmt.Errorf("failed to create L2 GER reader: %w", err)
}
Expand Down Expand Up @@ -176,7 +181,7 @@ func CreateCommonFlowComponents(
fullClaimsRequired bool,
requireCommitteeMembershipCheck bool,
agglayerBridgeL2Addr ethCommon.Address,
unsetClaimsMaxLogBlockRange uint64,
maxLogBlockRange uint64,
globalExitRootL1Addr ethCommon.Address,
blockFinalityForL1InfoTree aggkittypes.BlockNumberFinality,
certQuerier types.CertificateQuerier,
Expand All @@ -196,7 +201,7 @@ func CreateCommonFlowComponents(
agglayerBridgeL2Reader, err := claimsync.NewAgglayerBridgeL2ReaderWithMaxLogBlockRange(
agglayerBridgeL2Addr,
l2Client,
unsetClaimsMaxLogBlockRange,
maxLogBlockRange,
)
if err != nil {
return nil, fmt.Errorf("failed to create bridge L2 sovereign reader: %w", err)
Expand Down
4 changes: 2 additions & 2 deletions aggsender/flows/verifier_flow_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func NewVerifierFlow(
true, // full claims are (eventually) needed in validator mode
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.UnsetClaimsMaxLogBlockRange,
cfg.MaxLogBlockRange,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
nil, // certQuerier not used in validator mode
Expand Down Expand Up @@ -73,7 +73,7 @@ func NewVerifierFlow(
true, // full claims are (eventually) needed in validator mode
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.UnsetClaimsMaxLogBlockRange,
cfg.MaxLogBlockRange,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
nil, // certQuerier not used in validator mode
Expand Down
4 changes: 2 additions & 2 deletions aggsender/validator/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ type Config struct {
RequireCommitteeMembershipCheck bool `mapstructure:"RequireCommitteeMembershipCheck"`
// AgglayerBridgeL2Addr is the address of the bridge L2 sovereign contract on L2 sovereign chain
AgglayerBridgeL2Addr ethCommon.Address `mapstructure:"AgglayerBridgeL2Addr"`
// UnsetClaimsMaxLogBlockRange is the proactive max block range for eth_getLogs queries when fetching unset claims.
// MaxLogBlockRange is the proactive max block range for eth_getLogs queries issued by the validator.
// 0 means disabled.
UnsetClaimsMaxLogBlockRange uint64 `mapstructure:"UnsetClaimsMaxLogBlockRange"`
MaxLogBlockRange uint64 `mapstructure:"MaxLogBlockRange"`
// GlobalExitRootL1Addr is the address of the GlobalExitRootManager contract on L1
GlobalExitRootL1Addr ethCommon.Address `mapstructure:"GlobalExitRootL1Addr"`
// BlockFinalityForL1InfoTree indicates the block finality to use when querying for L1InfoRoot to use
Expand Down
16 changes: 8 additions & 8 deletions claimsync/agglayer_bridge_l2_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
// AgglayerBridgeL2Reader provides functionality to read and interact with the AggLayer Bridge L2 contract.
// It encapsulates the contract instance and provides methods to query bridge-related data from the L2 chain.
type AgglayerBridgeL2Reader struct {
agglayerBridgeL2 *agglayerbridgel2.Agglayerbridgel2
unsetClaimsMaxLogBlockRange uint64
agglayerBridgeL2 *agglayerbridgel2.Agglayerbridgel2
maxLogBlockRange uint64
}

// NewAgglayerBridgeL2Reader creates a new instance of AgglayerBridgeL2Reader.
Expand All @@ -39,20 +39,20 @@ func NewAgglayerBridgeL2Reader(
}

// NewAgglayerBridgeL2ReaderWithMaxLogBlockRange creates a new instance of AgglayerBridgeL2Reader
// with an optional proactive max block range for unset claims eth_getLogs queries.
// with an optional proactive max block range for eth_getLogs queries.
func NewAgglayerBridgeL2ReaderWithMaxLogBlockRange(
bridgeAddr common.Address,
l2Client aggkittypes.BaseEthereumClienter,
unsetClaimsMaxLogBlockRange uint64,
maxLogBlockRange uint64,
) (*AgglayerBridgeL2Reader, error) {
agglayerBridgeL2Contract, err := agglayerbridgel2.NewAgglayerbridgel2(bridgeAddr, l2Client)
if err != nil {
return nil, err
}

return &AgglayerBridgeL2Reader{
agglayerBridgeL2: agglayerBridgeL2Contract,
unsetClaimsMaxLogBlockRange: unsetClaimsMaxLogBlockRange,
agglayerBridgeL2: agglayerBridgeL2Contract,
maxLogBlockRange: maxLogBlockRange,
}, nil
}

Expand All @@ -75,8 +75,8 @@ func (r *AgglayerBridgeL2Reader) GetUnsetClaimsForBlockRange(ctx context.Context
return nil, fmt.Errorf("invalid block range: fromBlock(%d) > toBlock(%d)", fromBlock, toBlock)
}

if r.unsetClaimsMaxLogBlockRange > 0 && toBlock-fromBlock >= r.unsetClaimsMaxLogBlockRange {
return r.getUnsetClaimsInChunks(ctx, fromBlock, toBlock, r.unsetClaimsMaxLogBlockRange)
if r.maxLogBlockRange > 0 && toBlock-fromBlock >= r.maxLogBlockRange {
return r.getUnsetClaimsInChunks(ctx, fromBlock, toBlock, r.maxLogBlockRange)
}

return r.fetchUnsetClaimsWithFallbackChunking(ctx, fromBlock, toBlock)
Expand Down
10 changes: 9 additions & 1 deletion common/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,24 @@ var (
reExceededBlockRange = regexp.MustCompile(`exceeded maximum block range:\s*(\d+)`)
// Matches "eth_getLogs is limited to a 10,000 range" (number may contain comma thousands separators)
reEthGetLogsLimited = regexp.MustCompile(`eth_getLogs is limited to a\s+([\d,]+)\s+range`)
// Matches "query exceeds max block range 100000"
reQueryExceedsMaxBlockRange = regexp.MustCompile(`query exceeds max block range\s+([\d,]+)`)
)

// ParseMaxRangeFromError extracts the max range value from error message
// Expected formats:
// - "block range too large, max range: 1000"
// - "exceeded maximum block range: 5000"
// - "eth_getLogs is limited to a 10,000 range"
// - "query exceeds max block range 100000"
func ParseMaxRangeFromError(errMsg string) (uint64, bool) {
var matches []string
for _, re := range []*regexp.Regexp{reMaxRange, reExceededBlockRange, reEthGetLogsLimited} {
for _, re := range []*regexp.Regexp{
reMaxRange,
reExceededBlockRange,
reEthGetLogsLimited,
reQueryExceedsMaxBlockRange,
} {
matches = re.FindStringSubmatch(errMsg)
if len(matches) >= maxRangeMatchGroups {
break
Expand Down
13 changes: 13 additions & 0 deletions common/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,26 @@ func TestParseMaxRangeFromError(t *testing.T) {
expectedMaxBlock: 100000,
expectedIsMaxRange: true,
},
{
name: "query exceeds max block range",
errorMsg: "query exceeds max block range 100000",
expectedMaxBlock: 100000,
expectedIsMaxRange: true,
},
{
name: "query exceeds max block range with comma-formatted number",
errorMsg: "query exceeds max block range 100,000",
expectedMaxBlock: 100000,
expectedIsMaxRange: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, isMaxRangeErr := ParseMaxRangeFromError(tt.errorMsg)
if tt.expectedIsMaxRange {
require.True(t, isMaxRangeErr)
require.Equal(t, tt.expectedMaxBlock, result)
} else {
require.False(t, isMaxRangeErr)
require.Equal(t, tt.expectedMaxBlock, result)
Expand Down
9 changes: 9 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const (
networkIDDeprecatedHint = "Common.NetworkID is deprecated, remove it from configuration"
urlRPCL1DeprecatedHint = "URLRPCL1 field is deprecated, remove it from configuration"
aggsenderEpochPercentageHint = "AggSender.EpochNotificationPercentage moved to AggSender.TriggerEpochBased.EpochNotificationPercentage" //nolint:lll
maxLogBlockRangeHint = "UnsetClaimsMaxLogBlockRange moved to MaxLogBlockRange"
)

type DeprecatedFieldsError struct {
Expand Down Expand Up @@ -239,6 +240,14 @@ var (
FieldNamePattern: "AggSender.EpochNotificationPercentage",
Reason: aggsenderEpochPercentageHint,
},
{
FieldNamePattern: "AggSender.UnsetClaimsMaxLogBlockRange",
Reason: maxLogBlockRangeHint,
},
{
FieldNamePattern: "Validator.UnsetClaimsMaxLogBlockRange",
Reason: maxLogBlockRangeHint,
},
}
)

Expand Down
4 changes: 2 additions & 2 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ func TestLoadDefaultConfig(t *testing.T) {
require.Equal(t, cfg.Validator.AgglayerClient.GRPC.MinConnectTimeout, cfg.AggSender.AgglayerClient.GRPC.MinConnectTimeout)
require.Equal(t, cfg.Validator.AgglayerClient.GRPC.Retry.MaxAttempts, cfg.AggSender.AgglayerClient.GRPC.Retry.MaxAttempts)
require.Equal(t, cfg.AggSender.RollupManagerAddr, cfg.Validator.LerQuerier.RollupManagerAddr)
require.Equal(t, uint64(0), cfg.AggSender.UnsetClaimsMaxLogBlockRange)
require.Equal(t, cfg.AggSender.UnsetClaimsMaxLogBlockRange, cfg.Validator.UnsetClaimsMaxLogBlockRange)
require.Equal(t, uint64(0), cfg.AggSender.MaxLogBlockRange)
require.Equal(t, cfg.AggSender.MaxLogBlockRange, cfg.Validator.MaxLogBlockRange)
require.Equal(t, aggsendertypes.AutoMode, cfg.AggSender.Mode)
require.Equal(t, aggsendertypes.AutoMode, cfg.Validator.Mode)
require.Equal(t, cfg.AggSender.StorageRetainCertificatesPolicy.String(), "retain all certificates, keep history: true")
Expand Down
8 changes: 4 additions & 4 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,8 @@ MaxL2BlockNumber = 0
StopOnFinishedSendingAllCertificates = false
RequireCommitteeMembershipCheck = false
AgglayerBridgeL2Addr = "{{L2Config.BridgeAddr}}"
# Max block range per eth_getLogs call for unset-claims queries. 0 disables proactive chunking.
UnsetClaimsMaxLogBlockRange = 0
# Max block range per eth_getLogs call issued by AggSender. 0 disables proactive chunking.
MaxLogBlockRange = 0
BlockFinalityForL1InfoTree = "FinalizedBlock"
TriggerCertMode = "Auto"
[AggSender.TriggerEpochBased]
Expand Down Expand Up @@ -345,8 +345,8 @@ DelayBetweenRetries = "{{AggSender.DelayBetweenRetries}}"
Mode = "{{AggSender.Mode}}"
RequireCommitteeMembershipCheck = {{AggSender.RequireCommitteeMembershipCheck}}
AgglayerBridgeL2Addr = "{{L2Config.BridgeAddr}}"
# Max block range per eth_getLogs call for unset-claims queries. 0 disables proactive chunking.
UnsetClaimsMaxLogBlockRange = {{AggSender.UnsetClaimsMaxLogBlockRange}}
# Max block range per eth_getLogs call issued by the validator. 0 disables proactive chunking.
MaxLogBlockRange = {{AggSender.MaxLogBlockRange}}
GlobalExitRootL1Addr = "{{L1Config.polygonZkEVMGlobalExitRootAddress}}"
BlockFinalityForL1InfoTree = "{{AggSender.BlockFinalityForL1InfoTree}}"
[Validator.ServerConfig]
Expand Down
2 changes: 1 addition & 1 deletion docs/aggsender.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ The certificate is the data submitted to `Agglayer`. Must be signed to be accept
| MaxL2BlockNumber | uint64 | Set the last block to be included in a certificate (0 = disabled)
|StopOnFinishedSendingAllCertificates| bool | Stop when there are no more certificates to send due to MaxL2BlockNumber
|StorageRetainCertificatesPolicy| [StorageRetainCertificatesPolicy](#storageretaincertificatespolicy) | Configure the certificate retain policy
| UnsetClaimsMaxLogBlockRange | uint64 | Proactive max block range for `eth_getLogs` queries when fetching unset claims. 0 means disabled (fallback to reactive chunking on error)
| MaxLogBlockRange | uint64 | Proactive max block range for `eth_getLogs` calls issued while building certificates, including unset claims and injected/removed GERs. 0 disables proactive chunking; recognized RPC max-range errors still trigger reactive chunking.

## StorageRetainCertificatesPolicy
The `StorageRetainCertificatesPolicy` structure configures the certificate retain policy
Expand Down
4 changes: 2 additions & 2 deletions docs/aggsender_validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ The validator is configured using a `.toml` file. Check the default values in th

| Name | Type | Description |
|-------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------|
| UnsetClaimsMaxLogBlockRange | uint64 | Proactive max block range for `eth_getLogs` queries when fetching unset claims. 0 means disabled (fallback to reactive chunking on error) |
| MaxLogBlockRange | uint64 | Proactive max block range for `eth_getLogs` calls issued while validating certificates. 0 disables proactive chunking; recognized RPC max-range errors still trigger reactive chunking. |

### Running the Validator

Expand Down Expand Up @@ -388,4 +388,4 @@ if err != nil {
log.Errorf("Remote validation failed: %v", err)
return err
}
```
```
Loading
Loading