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
3 changes: 2 additions & 1 deletion aggsender/aggsender.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ func newAggsender(
return nil, fmt.Errorf("error creating verifier flow: %w", err)
}

l1InfoTreeQuerier, err := query.NewL1InfoTreeDataQuerier(l1Client, cfg.GlobalExitRootL1Addr, l1InfoTreeSyncer)
l1InfoTreeQuerier, err := query.NewL1InfoTreeDataQuerier(l1Client, cfg.GlobalExitRootL1Addr, l1InfoTreeSyncer,
cfg.BlockFinalityForL1InfoTree)
if err != nil {
return nil, fmt.Errorf("error creating L1 Info tree data querier: %w", err)
}
Expand Down
5 changes: 4 additions & 1 deletion aggsender/aggsender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/agglayer/aggkit/grpc"
"github.com/agglayer/aggkit/log"
treetypes "github.com/agglayer/aggkit/tree/types"
aggkittypes "github.com/agglayer/aggkit/types"
"github.com/agglayer/go_signer/signer"
signertypes "github.com/agglayer/go_signer/signer/types"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -51,6 +52,7 @@ func TestConfigString(t *testing.T) {
EpochNotificationPercentage: 50,
Mode: "PP",
SovereignRollupAddr: common.HexToAddress("0x1"),
BlockFinalityForL1InfoTree: aggkittypes.FinalizedBlock,
}

expected := fmt.Sprintf("StoragePath: /path/to/storage\n"+
Expand All @@ -67,7 +69,8 @@ func TestConfigString(t *testing.T) {
"SovereignRollupAddr: 0x0000000000000000000000000000000000000001\n"+
"RequireNoFEPBlockGap: false\n"+
"RetriesToBuildAndSendCertificate: RetryPolicyConfig{Mode: , Config: RetryDelaysConfig{Delays: [], MaxRetries: NO RETRIES}}\n"+
"StorageRetainCertificatesPolicy: retain all certificates, keep history: false\n",
"StorageRetainCertificatesPolicy: retain all certificates, keep history: false\n"+
"BlockFinalityForL1InfoTree: FinalizedBlock\n",
config.AgglayerClient.String())

require.Equal(t, expected, config.String())
Expand Down
9 changes: 8 additions & 1 deletion aggsender/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/agglayer/aggkit/common"
"github.com/agglayer/aggkit/config/types"
"github.com/agglayer/aggkit/grpc"
aggkittypes "github.com/agglayer/aggkit/types"
signertypes "github.com/agglayer/go_signer/signer/types"
ethCommon "github.com/ethereum/go-ethereum/common"
)
Expand Down Expand Up @@ -96,6 +97,8 @@ 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"`
// 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
}

func (c Config) CheckCertConfigBriefString() string {
Expand All @@ -118,7 +121,8 @@ func (c Config) String() string {
"SovereignRollupAddr: " + c.SovereignRollupAddr.Hex() + "\n" +
"RequireNoFEPBlockGap: " + fmt.Sprintf("%t", c.RequireNoFEPBlockGap) + "\n" +
"RetriesToBuildAndSendCertificate: " + c.RetriesToBuildAndSendCertificate.String() + "\n" +
"StorageRetainCertificatesPolicy: " + c.StorageRetainCertificatesPolicy.String() + "\n"
"StorageRetainCertificatesPolicy: " + c.StorageRetainCertificatesPolicy.String() + "\n" +
"BlockFinalityForL1InfoTree: " + c.BlockFinalityForL1InfoTree.String() + "\n"
}

// Validate checks if the configuration is valid
Expand All @@ -138,5 +142,8 @@ func (c Config) Validate() error {
if err := c.StorageRetainCertificatesPolicy.Validate(); err != nil {
return fmt.Errorf("invalid StorageRetainCertificatesPolicy config: %w", err)
}
if err := c.BlockFinalityForL1InfoTree.Validate(); err != nil {
return fmt.Errorf("invalid BlockFinalityForL1InfoTree configuration: %w", err)
}
return nil
}
19 changes: 19 additions & 0 deletions aggsender/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/agglayer/aggkit/common"
"github.com/agglayer/aggkit/config/types"
"github.com/agglayer/aggkit/grpc"
aggkittypes "github.com/agglayer/aggkit/types"
signertypes "github.com/agglayer/go_signer/signer/types"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
Expand All @@ -29,6 +30,7 @@ func TestValidate(t *testing.T) {
URL: "",
},
},
BlockFinalityForL1InfoTree: aggkittypes.FinalizedBlock,
},
expectedErr: "invalid agglayer client config",
},
Expand All @@ -44,6 +46,7 @@ func TestValidate(t *testing.T) {
AggkitProverClient: &grpc.ClientConfig{
URL: "",
},
BlockFinalityForL1InfoTree: aggkittypes.FinalizedBlock,
},
expectedErr: "invalid aggkit prover client config",
},
Expand All @@ -59,8 +62,24 @@ func TestValidate(t *testing.T) {
AggkitProverClient: &grpc.ClientConfig{
URL: "",
},
BlockFinalityForL1InfoTree: aggkittypes.FinalizedBlock,
},
},
{
name: "nBlockFinalityForL1InfoTree not set",
config: Config{
Mode: aggsendertypes.PessimisticProofMode,
AgglayerClient: agglayer.ClientConfig{GRPC: &grpc.ClientConfig{
URL: "http://localhost:9090",
MinConnectTimeout: types.NewDuration(5 * time.Second),
},
},
AggkitProverClient: &grpc.ClientConfig{
URL: "",
},
},
expectedErr: "BlockFinalityForL1InfoTree",
},
}

for _, tc := range testCases {
Expand Down
6 changes: 5 additions & 1 deletion aggsender/flows/builder_flow_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func NewBuilderFlow(
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
)
if err != nil {
return nil, fmt.Errorf("failed to create common flow components: %w", err)
Expand Down Expand Up @@ -100,6 +101,7 @@ func NewBuilderFlow(
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
)
if err != nil {
return nil, fmt.Errorf("failed to create common flow components: %w", err)
Expand Down Expand Up @@ -166,6 +168,7 @@ func CreateCommonFlowComponents(
requireCommitteeMembershipCheck bool,
agglayerBridgeL2Addr ethCommon.Address,
globalExitRootL1Addr ethCommon.Address,
blockFinalityForL1InfoTree aggkittypes.BlockNumberFinality,
) (*CommonFlowComponents, error) {
l2ChainID, err := rollupDataQuerier.GetRollupChainID()
if err != nil {
Expand All @@ -184,7 +187,8 @@ func CreateCommonFlowComponents(
}

l2BridgeQuerier := query.NewBridgeDataQuerier(logger, l2Syncer, delayBetweenRetries, agglayerBridgeL2Reader)
l1InfoTreeQuerier, err := query.NewL1InfoTreeDataQuerier(l1Client, globalExitRootL1Addr, l1InfoTreeSyncer)
l1InfoTreeQuerier, err := query.NewL1InfoTreeDataQuerier(l1Client, globalExitRootL1Addr, l1InfoTreeSyncer,
blockFinalityForL1InfoTree)
if err != nil {
return nil, fmt.Errorf("error creating L1 Info tree data querier: %w", err)
}
Expand Down
2 changes: 2 additions & 0 deletions aggsender/flows/verifier_flow_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func NewVerifierFlow(
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
)
if err != nil {
return nil, nil, fmt.Errorf("failed to create common flow components: %w", err)
Expand Down Expand Up @@ -67,6 +68,7 @@ func NewVerifierFlow(
cfg.RequireCommitteeMembershipCheck,
cfg.AgglayerBridgeL2Addr,
cfg.GlobalExitRootL1Addr,
cfg.BlockFinalityForL1InfoTree,
)
if err != nil {
return nil, nil, fmt.Errorf("failed to create common flow components: %w", err)
Expand Down
10 changes: 6 additions & 4 deletions aggsender/prover/proof_generation_tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ func NewAggchainProofGenerationTool(
return nil, fmt.Errorf("failed to create AggchainProofClient: %w", err)
}

l1InfoTreeQuerier, err := query.NewL1InfoTreeDataQuerier(l1Client, cfg.GlobalExitRootL1Addr, l1InfoTreeSyncer,
aggkittypes.FinalizedBlock)
if err != nil {
return nil, fmt.Errorf("error creating L1 Info tree data querier: %w", err)
}

l2GERReader, err := l2gersync.NewL2EVMGERReader(cfg.GlobalExitRootL2Addr, l2Client, l1InfoTreeSyncer)
if err != nil {
return nil, fmt.Errorf("error creating L2 GER reader: %w", err)
Expand All @@ -97,10 +103,6 @@ func NewAggchainProofGenerationTool(
return nil, fmt.Errorf("failed to create bridge L2 sovereign reader: %w", err)
}

l1InfoTreeQuerier, err := query.NewL1InfoTreeDataQuerier(l1Client, cfg.GlobalExitRootL1Addr, l1InfoTreeSyncer)
if err != nil {
return nil, fmt.Errorf("error creating L1 Info tree data querier: %w", err)
}
l2BridgeQuerier := query.NewBridgeDataQuerier(logger, l2Syncer, time.Second, agglayerBridgeL2Reader)

baseFlow := flows.NewBaseFlow(
Expand Down
10 changes: 10 additions & 0 deletions aggsender/prover/proof_generation_tool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
aggkitgrpc "github.com/agglayer/aggkit/grpc"
"github.com/agglayer/aggkit/log"
aggkittypesmocks "github.com/agglayer/aggkit/types/mocks"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -156,4 +157,13 @@ func TestNewAggchainProofGenerationTool(t *testing.T) {
_, err := NewAggchainProofGenerationTool(context.TODO(), log.WithFields("module", "test"),
Config{AggkitProverClient: aggkitgrpc.DefaultConfig()}, mockL1Client, mockL2Client, mockL2Syncer, nil)
require.Error(t, err)

cfg := Config{
AggkitProverClient: aggkitgrpc.DefaultConfig(),
GlobalExitRootL2Addr: common.HexToAddress("0xbeef"),
}
mockL1InfoTreeSyncer := mocks.NewL1InfoTreeSyncer(t)
_, err = NewAggchainProofGenerationTool(context.TODO(), log.WithFields("module", "test"),
cfg, mockL1Client, mockL2Client, mockL2Syncer, mockL1InfoTreeSyncer)
require.ErrorContains(t, err, "L2 GER reader")
}
21 changes: 11 additions & 10 deletions aggsender/query/l1info_tree_data_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,31 @@ import (
"github.com/ethereum/go-ethereum/common"
)

var finalizedBlockBigInt = big.NewInt(int64(aggkittypes.Finalized))

var _ types.L1InfoTreeDataQuerier = (*L1InfoTreeDataQuerier)(nil)

// L1InfoTreeDataQuerier is a struct that holds the logic to query the L1 Info tree data
type L1InfoTreeDataQuerier struct {
l1Client aggkittypes.BaseEthereumClienter
l1GERManager *agglayerger.Agglayerger
l1InfoTreeSyncer types.L1InfoTreeSyncer
l1Client aggkittypes.BaseEthereumClienter
l1GERManager *agglayerger.Agglayerger
l1InfoTreeSyncer types.L1InfoTreeSyncer
blockFinalityForL1InfoTree aggkittypes.BlockNumberFinality
}

// NewL1InfoTreeDataQuerier returns a new instance of the L1InfoTreeDataQuery
func NewL1InfoTreeDataQuerier(
l1Client aggkittypes.BaseEthereumClienter,
l1GERAddr common.Address,
l1InfoTreeSyncer types.L1InfoTreeSyncer) (*L1InfoTreeDataQuerier, error) {
l1InfoTreeSyncer types.L1InfoTreeSyncer,
blockFinalityForL1InfoTree aggkittypes.BlockNumberFinality) (*L1InfoTreeDataQuerier, error) {
l1GERManager, err := agglayerger.NewAgglayerger(l1GERAddr, l1Client)
if err != nil {
return nil, err
}
return &L1InfoTreeDataQuerier{
l1Client: l1Client,
l1GERManager: l1GERManager,
l1InfoTreeSyncer: l1InfoTreeSyncer,
l1Client: l1Client,
l1GERManager: l1GERManager,
l1InfoTreeSyncer: l1InfoTreeSyncer,
blockFinalityForL1InfoTree: blockFinalityForL1InfoTree,
}, nil
}

Expand Down Expand Up @@ -143,7 +144,7 @@ func (l *L1InfoTreeDataQuerier) GetProofForGER(

// getLatestProcessedFinalizedBlock returns the latest processed finalized block from the l1infotreesyncer
func (l *L1InfoTreeDataQuerier) getLatestProcessedFinalizedBlock(ctx context.Context) (uint64, error) {
lastFinalizedL1Block, err := l.l1Client.HeaderByNumber(ctx, finalizedBlockBigInt)
lastFinalizedL1Block, err := l.blockFinalityForL1InfoTree.BlockHeader(ctx, l.l1Client)
if err != nil {
return 0, fmt.Errorf("error getting latest finalized L1 block: %w", err)
}
Expand Down
11 changes: 7 additions & 4 deletions aggsender/query/l1info_tree_data_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import (
"github.com/agglayer/aggkit/aggsender/mocks"
"github.com/agglayer/aggkit/l1infotreesync"
treetypes "github.com/agglayer/aggkit/tree/types"
aggkittypes "github.com/agglayer/aggkit/types"
aggkittypesmocks "github.com/agglayer/aggkit/types/mocks"
"github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/require"
)

var finalizedBlockBigInt = big.NewInt(int64(aggkittypes.Finalized))

func Test_GetFinalizedL1InfoTreeData(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -83,7 +86,7 @@ func Test_GetFinalizedL1InfoTreeData(t *testing.T) {

mockL1InfoTreeSyncer := mocks.NewL1InfoTreeSyncer(t)
mockL1Client := aggkittypesmocks.NewBaseEthereumClienter(t)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(mockL1Client, common.Address{}, mockL1InfoTreeSyncer)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(mockL1Client, common.Address{}, mockL1InfoTreeSyncer, aggkittypes.FinalizedBlock)
require.NoError(t, err)

tc.mockFn(mockL1InfoTreeSyncer)
Expand Down Expand Up @@ -179,7 +182,7 @@ func Test_AggchainProverFlow_GetLatestProcessedFinalizedBlock(t *testing.T) {

mockL1InfoTreeSyncer := mocks.NewL1InfoTreeSyncer(t)
mockL1Client := aggkittypesmocks.NewBaseEthereumClienter(t)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(mockL1Client, common.Address{}, mockL1InfoTreeSyncer)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(mockL1Client, common.Address{}, mockL1InfoTreeSyncer, aggkittypes.FinalizedBlock)
require.NoError(t, err)

tc.mockFn(mockL1InfoTreeSyncer, mockL1Client)
Expand Down Expand Up @@ -263,7 +266,7 @@ func Test_GetProofForGER(t *testing.T) {
t.Parallel()

mockL1InfoTreeSyncer := mocks.NewL1InfoTreeSyncer(t)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(nil, common.Address{}, mockL1InfoTreeSyncer)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(nil, common.Address{}, mockL1InfoTreeSyncer, aggkittypes.FinalizedBlock)
require.NoError(t, err)

tc.mockFn(mockL1InfoTreeSyncer)
Expand Down Expand Up @@ -374,7 +377,7 @@ func Test_IsGERFinalized(t *testing.T) {
t.Parallel()

mockL1InfoTreeSyncer := mocks.NewL1InfoTreeSyncer(t)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(nil, common.Address{}, mockL1InfoTreeSyncer)
l1InfoTreeDataQuery, err := NewL1InfoTreeDataQuerier(nil, common.Address{}, mockL1InfoTreeSyncer, aggkittypes.FinalizedBlock)
require.NoError(t, err)

tc.mockFn(mockL1InfoTreeSyncer)
Expand Down
8 changes: 8 additions & 0 deletions aggsender/validator/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
aggkitcommon "github.com/agglayer/aggkit/common"
"github.com/agglayer/aggkit/config/types"
aggkitgrpc "github.com/agglayer/aggkit/grpc"
aggkittypes "github.com/agglayer/aggkit/types"
signertypes "github.com/agglayer/go_signer/signer/types"
ethCommon "github.com/ethereum/go-ethereum/common"
)
Expand Down Expand Up @@ -48,6 +49,9 @@ type Config struct {
AgglayerBridgeL2Addr ethCommon.Address `mapstructure:"AgglayerBridgeL2Addr"`
// 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
BlockFinalityForL1InfoTree aggkittypes.BlockNumberFinality `jsonschema:"enum=LatestBlock, enum=SafeBlock, enum=PendingBlock, enum=FinalizedBlock, enum=EarliestBlock" mapstructure:"BlockFinalityForL1InfoTree"` //nolint:lll

}

type PPConfig struct {
Expand Down Expand Up @@ -90,5 +94,9 @@ func (c *Config) Validate() error {
return fmt.Errorf("invalid agglayer client config: %w", err)
}

if err := c.BlockFinalityForL1InfoTree.Validate(); err != nil {
return fmt.Errorf("invalid BlockFinalityForL1InfoTree configuration: %w", err)
}

return nil
}
Loading
Loading