Skip to content
Merged
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
19 changes: 17 additions & 2 deletions aggsender/aggsender.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type AggSender struct {
aggLayerClient agglayer.AgglayerClientInterface
compatibilityStoragedChecker compatibility.CompatibilityChecker
certStatusChecker types.CertificateStatusChecker
certQuerier types.CertificateQuerier
rollupDataQuerier types.RollupDataQuerier

cfg config.Config

Expand Down Expand Up @@ -126,6 +128,8 @@ func New(
rateLimiter: rateLimit,
compatibilityStoragedChecker: compatibilityStoragedChecker,
l2OriginNetwork: l2OriginNetwork,
certQuerier: certQuerier,
rollupDataQuerier: rollupDataQuerier,
certStatusChecker: statuschecker.NewCertStatusChecker(
logger, storage, aggLayerClient, certQuerier, l2OriginNetwork),
}, nil
Expand All @@ -149,6 +153,14 @@ func (a *AggSender) GetFlow() types.AggsenderFlow {
return a.flow
}

func (a *AggSender) GetCertQuerier() types.CertificateQuerier {
return a.certQuerier
}

func (a *AggSender) GetLERQuerier() types.LERQuerier {
return query.NewLERDataQuerier(a.cfg.RollupCreationBlockL1, a.rollupDataQuerier)
}

func (a *AggSender) Info() types.AggsenderInfo {
res := types.AggsenderInfo{
AggsenderStatus: *a.status,
Expand Down Expand Up @@ -332,8 +344,11 @@ func (a *AggSender) sendCertificate(ctx context.Context) (*agglayertypes.Certifi

validatorSignature, err := a.callValidator(ctx, certificate, certificateParams.ToBlock)
if err != nil {
a.saveNonAcceptedCert(ctx, certificate, certificateParams.CreatedAt, err)
return nil, fmt.Errorf("certificate validation failed: %w", err)
// TODO - agglayer has not yet implemented the endpoints needed to validate a certificate
// so lets just log the error and continue. This will be changed when the agglayer is ready
// a.saveNonAcceptedCert(ctx, certificate, certificateParams.CreatedAt, err)
// return nil, fmt.Errorf("certificate validation failed: %w", err)
a.log.Warnf("certificate validation failed: %w. Cert: %s", err, certificate.Brief())
}
a.log.Infof("certificate ready to be sent to AggLayer: %s start: %s, end: %s",
certificate.Brief(), startEpochStatus.String(), a.epochNotifier.GetEpochStatus().String())
Expand Down
7 changes: 5 additions & 2 deletions aggsender/aggsender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ func TestExtractFromCertificateMetadataToBlock(t *testing.T) {
}
}

//nolint:dupl
func TestSendCertificate(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -399,14 +400,16 @@ func TestSendCertificate(t *testing.T) {
NewLocalExitRoot: common.HexToHash("0x1"),
BridgeExits: []*agglayertypes.BridgeExit{{}},
}, nil).Once()
mockStorage.EXPECT().SaveNonAcceptedCertificate(mock.Anything, mock.Anything).Return(nil).Once()
// mockStorage.EXPECT().SaveNonAcceptedCertificate(mock.Anything, mock.Anything).Return(nil).Once()
mockAgglayerClient.EXPECT().SendCertificate(mock.Anything, mock.Anything, mock.Anything).Return(common.HexToHash("0x22"), nil).Once()
mockStorage.EXPECT().SaveLastSentCertificate(mock.Anything, mock.Anything).Return(nil).Once()
},
mockValidatorFn: func() *mocks.CertificateValidateAndSigner {
mockValidator := mocks.NewCertificateValidateAndSigner(t)
mockValidator.EXPECT().ValidateAndSignCertificate(mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("some error")).Once()
return mockValidator
},
expectedError: "certificate validation failed: some error",
// expectedError: "certificate validation failed: some error", // TODO - this will be fixed when the agglayer is ready
},
{
name: "successful validation and sending of a certificate",
Expand Down
4 changes: 3 additions & 1 deletion aggsender/aggsender_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ func NewAggsenderValidator(ctx context.Context,
flowPP validator.FlowInterface,
l1InfoTreeDataQuerier validator.L1InfoTreeRootByLeafQuerier,
aggLayerClient agglayer.AggLayerClientCertificateIDQuerier,
certQuerier types.CertificateQuerier,
lerQuerier types.LERQuerier,
signer signertypes.Signer) (*AggsenderValidator, error) {
validatorCert := validator.NewAggsenderValidator(
logger, flowPP, l1InfoTreeDataQuerier)
logger, flowPP, l1InfoTreeDataQuerier, certQuerier, lerQuerier)
grpcServer, err := grpc.NewServer(cfg.ServerConfig)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion aggsender/aggsender_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestNewAggsenderValidator(t *testing.T) {
}
// Call the function
validator, err := NewAggsenderValidator(ctx, mockLogger, cfg, mockFlowPP, mockL1InfoTreeDataQuerier,
mockAggLayerClient, nil)
mockAggLayerClient, nil, nil, nil)

// Assertions
require.NoError(t, err, "Expected no error when creating AggsenderValidator")
Expand Down
22 changes: 14 additions & 8 deletions aggsender/converters/cert_header_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@ import (

agglayertypes "github.com/agglayer/aggkit/agglayer/types"
"github.com/agglayer/aggkit/aggsender/types"
aggkitcommon "github.com/agglayer/aggkit/common"
)

// ConvertAgglayerCertHeaderToAggsender converts an agglayer CertificateHeader to an aggsender CertificateHeader
func ConvertAgglayerCertHeaderToAggsender(cert *agglayertypes.CertificateHeader) (*types.CertificateHeader, error) {
if cert == nil {
return nil, nil
}
metadataUnmarshal, err := types.NewCertificateMetadataFromHash(cert.Metadata)
if err != nil {
return nil, fmt.Errorf("error parsing cert metadata. Err: %w", err)
}
blockRange, err := metadataUnmarshal.BlockRange()
if err != nil {
return nil, fmt.Errorf("cant get blockRange from certificate metadata. Err: %w", err)

blockRange := types.BlockRangeZero
if cert.Metadata != aggkitcommon.ZeroHash {
// TODO - remove this once we completely decouple metadata from the certificate
metadataUnmarshal, err := types.NewCertificateMetadataFromHash(cert.Metadata)
if err != nil {
return nil, fmt.Errorf("error parsing cert metadata. Err: %w", err)
}
br, err := metadataUnmarshal.BlockRange()
if err != nil {
return nil, fmt.Errorf("cant get blockRange from certificate metadata. Err: %w", err)
}
blockRange = br
}

return &types.CertificateHeader{
Expand All @@ -33,7 +40,6 @@ func ConvertAgglayerCertHeaderToAggsender(cert *agglayertypes.CertificateHeader)
CreatedAt: 0,
UpdatedAt: 0,
FinalizedL1InfoTreeRoot: nil,
CertType: metadataUnmarshal.CertificateType(),
CertSource: types.CertificateSourceAggLayer,
}, nil
}
Expand Down
11 changes: 0 additions & 11 deletions aggsender/converters/cert_header_converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ func TestAgglayerCertificateHeaderToAggsender(t *testing.T) {
require.ErrorContains(t, err, "unsupported certificate metadata")
})

t.Run("Can't get blockRange'", func(t *testing.T) {
badMetadata := make([]byte, common.HashLength)
badMetadata[0] = 0x0 // Version = 0x0 doesn't have blockrange
cert := &agglayertypes.CertificateHeader{
Metadata: common.Hash(badMetadata),
}
result, err := ConvertAgglayerCertHeaderToAggsender(cert)
require.Nil(t, result)
require.Error(t, err)
})

t.Run("ok", func(t *testing.T) {
badMetadata := make([]byte, common.HashLength)
badMetadata[0] = 0x1 // Version = 0xff
Expand Down
109 changes: 64 additions & 45 deletions aggsender/flows/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,20 @@ func NewFlow(
) (types.AggsenderFlow, error) {
switch types.AggsenderMode(cfg.Mode) {
case types.PessimisticProofMode:
signer, err := initializeSigner(ctx, cfg.AggsenderPrivateKey, logger)
if err != nil {
return nil, err
}
logger.Infof("Initializing RollupManager contract at address: %s. Genesis block: %d",
cfg.RollupManagerAddr, cfg.RollupCreationBlockL1)
lerQuerier, err := query.NewLERDataQuerier(
cfg.RollupManagerAddr, cfg.RollupCreationBlockL1, rollupDataQuerier)
commonFlowComponents, err := createCommonComponents(
ctx, cfg, logger, storage, l1Client, l1InfoTreeSyncer, l2Syncer, rollupDataQuerier, 0, false,
)
if err != nil {
return nil, fmt.Errorf("error creating LER data querier: %w", err)
return nil, fmt.Errorf("failed to create common flow components: %w", err)
}

l2BridgeQuerier := query.NewBridgeDataQuerier(logger, l2Syncer, cfg.DelayBetweenRetries.Duration)
l1InfoTreeQuerier := query.NewL1InfoTreeDataQuerier(l1Client, l1InfoTreeSyncer)
logger.Infof("Aggsender signer address: %s", signer.PublicAddress().Hex())
baseFlow := NewBaseFlow(
logger, l2BridgeQuerier, storage, l1InfoTreeQuerier, lerQuerier,
NewBaseFlowConfig(cfg.MaxCertSize, 0, false),
)
return NewPPFlow(
logger,
baseFlow,
commonFlowComponents.baseFlow,
storage,
l1InfoTreeQuerier,
l2BridgeQuerier,
signer,
commonFlowComponents.l1InfoTreeDataQuerier,
commonFlowComponents.l2BridgeQuerier,
commonFlowComponents.signer,
cfg.RequireOneBridgeInPPCertificate,
cfg.MaxL2BlockNumber,
), nil
Expand All @@ -71,69 +59,57 @@ func NewFlow(
return nil, fmt.Errorf("invalid aggkit prover client config: %w", err)
}

signer, err := initializeSigner(ctx, cfg.AggsenderPrivateKey, logger)
if err != nil {
return nil, err
}
logger.Infof("Aggsender signer address: %s", signer.PublicAddress().Hex())

aggchainProofClient, err := aggchainproofclient.NewAggchainProofClient(cfg.AggkitProverClient)
if err != nil {
return nil, fmt.Errorf("aggchainProverFlow - error creating aggkit prover client: %w", err)
}

l1InfoTreeQuerier := query.NewL1InfoTreeDataQuerier(l1Client, l1InfoTreeSyncer)

optimisticSigner, optimisticModeQuerier, err := optimistic.NewOptimistic(
ctx, logger, l1Client, cfg.OptimisticModeConfig)
if err != nil {
return nil, fmt.Errorf("aggchainProverFlow - error creating optimistic mode querier: %w", err)
}

lerQuerier, err := query.NewLERDataQuerier(
cfg.RollupManagerAddr, cfg.RollupCreationBlockL1, rollupDataQuerier)
if err != nil {
return nil, fmt.Errorf("aggchainProverFlow - error creating LER data querier: %w", err)
}

aggchainFEPQuerier, err := query.NewAggchainFEPQuerier(logger, types.AggchainProofMode,
cfg.SovereignRollupAddr, l1Client)
if err != nil {
return nil, fmt.Errorf("aggchainProverFlow - error creating aggchain FEP querier: %w", err)
}

l2BridgeQuerier := query.NewBridgeDataQuerier(logger, l2Syncer, cfg.DelayBetweenRetries.Duration)
baseFlow := NewBaseFlow(
logger, l2BridgeQuerier, storage, l1InfoTreeQuerier, lerQuerier,
NewBaseFlowConfig(cfg.MaxCertSize, aggchainFEPQuerier.StartL2Block(), cfg.RequireNoFEPBlockGap),
commonFlowComponents, err := createCommonComponents(
ctx, cfg, logger, storage, l1Client, l1InfoTreeSyncer, l2Syncer, rollupDataQuerier,
aggchainFEPQuerier.StartL2Block(), cfg.RequireNoFEPBlockGap,
)
if err != nil {
return nil, fmt.Errorf("failed to create common flow components: %w", err)
}

l2GERReader, err := l2GERReaderFactory(cfg.GlobalExitRootL2Addr, l2Client, l1InfoTreeSyncer)
if err != nil {
return nil, fmt.Errorf("failed to create L2 GER reader: %w", err)
}

gerQuerier := query.NewGERDataQuerier(l1InfoTreeQuerier, l2GERReader)
gerQuerier := query.NewGERDataQuerier(commonFlowComponents.l1InfoTreeDataQuerier, l2GERReader)

aggchainProofQuerier := query.NewAggchainProofQuery(
logger,
aggchainProofClient,
l1InfoTreeQuerier,
commonFlowComponents.l1InfoTreeDataQuerier,
optimisticSigner,
baseFlow,
commonFlowComponents.baseFlow,
gerQuerier,
)

return NewAggchainProverFlow(
logger,
NewAggchainProverFlowConfig(cfg.MaxL2BlockNumber),
baseFlow,
commonFlowComponents.baseFlow,
storage,
l1InfoTreeQuerier,
l2BridgeQuerier,
commonFlowComponents.l1InfoTreeDataQuerier,
commonFlowComponents.l2BridgeQuerier,
gerQuerier,
l1Client,
signer,
commonFlowComponents.signer,
optimisticModeQuerier,
aggchainProofQuerier,
), nil
Expand All @@ -143,6 +119,49 @@ func NewFlow(
}
}

type commonFlowComponents struct {
l2BridgeQuerier types.BridgeQuerier
l1InfoTreeDataQuerier types.L1InfoTreeDataQuerier
lerQuerier types.LERQuerier
baseFlow types.AggsenderFlowBaser
signer signerTypes.Signer
}

func createCommonComponents(
ctx context.Context,
cfg config.Config,
logger *log.Logger,
storage db.AggSenderStorage,
l1Client aggkittypes.BaseEthereumClienter,
l1InfoTreeSyncer types.L1InfoTreeSyncer,
l2Syncer types.L2BridgeSyncer,
rollupDataQuerier types.RollupDataQuerier,
startL2Block uint64,
requireNoFEPBlockGap bool,
) (commonFlowComponents, error) {
signer, err := initializeSigner(ctx, cfg.AggsenderPrivateKey, logger)
if err != nil {
return commonFlowComponents{}, err
}

l2BridgeQuerier := query.NewBridgeDataQuerier(logger, l2Syncer, cfg.DelayBetweenRetries.Duration)
l1InfoTreeQuerier := query.NewL1InfoTreeDataQuerier(l1Client, l1InfoTreeSyncer)
lerQuerier := query.NewLERDataQuerier(cfg.RollupCreationBlockL1, rollupDataQuerier)

baseFlow := NewBaseFlow(
logger, l2BridgeQuerier, storage, l1InfoTreeQuerier, lerQuerier,
NewBaseFlowConfig(cfg.MaxCertSize, startL2Block, requireNoFEPBlockGap),
)

return commonFlowComponents{
l2BridgeQuerier: l2BridgeQuerier,
l1InfoTreeDataQuerier: l1InfoTreeQuerier,
lerQuerier: lerQuerier,
baseFlow: baseFlow,
signer: signer,
}, nil
}

func initializeSigner(
ctx context.Context,
signerCfg signerTypes.SignerConfig,
Expand Down
11 changes: 0 additions & 11 deletions aggsender/flows/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,6 @@ func TestNewFlow(t *testing.T) {
},
expectedError: "error signer.Initialize",
},
{
name: "error creating signer in AggchainProofMode",
cfg: config.Config{
Mode: string(types.AggchainProofMode),
AggsenderPrivateKey: signertypes.SignerConfig{
Method: signertypes.MethodLocal,
},
AggkitProverClient: aggkitgrpc.DefaultConfig(),
},
expectedError: "error signer.Initialize",
},
{
name: "error missing AggkitProverClient in AggchainProofMode",
cfg: config.Config{
Expand Down
3 changes: 2 additions & 1 deletion aggsender/flows/flow_aggchain_prover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/agglayer/aggkit/aggsender/query"
"github.com/agglayer/aggkit/aggsender/types"
"github.com/agglayer/aggkit/bridgesync"
aggkitcommon "github.com/agglayer/aggkit/common"
"github.com/agglayer/aggkit/log"
treetypes "github.com/agglayer/aggkit/tree/types"
aggkittypesmocks "github.com/agglayer/aggkit/types/mocks"
Expand Down Expand Up @@ -556,7 +557,7 @@ func Test_AggchainProverFlow_BuildCertificate(t *testing.T) {
Height: 0,
NewLocalExitRoot: types.EmptyLER,
CustomChainData: []byte("some-data"),
Metadata: types.NewCertificateMetadata(1, 9, uint32(createdAt.Unix()), types.CertificateTypeFEP.ToInt()).ToHash(),
Metadata: aggkitcommon.ZeroHash,
BridgeExits: []*agglayertypes.BridgeExit{},
ImportedBridgeExits: []*agglayertypes.ImportedBridgeExit{},
PrevLocalExitRoot: types.EmptyLER,
Expand Down
Loading
Loading