diff --git a/agglayer/types.go b/agglayer/types.go index 68ac819b..1349d931 100644 --- a/agglayer/types.go +++ b/agglayer/types.go @@ -4,7 +4,7 @@ import ( "math/big" cdkcommon "github.com/0xPolygon/cdk/common" - "github.com/0xPolygon/cdk/tree" + "github.com/0xPolygon/cdk/tree/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" ) @@ -70,11 +70,11 @@ func (c *BridgeExit) Hash() common.Hash { // ImportedBridgeExit represents a token bridge exit originating on another network but claimed on the current network. type ImportedBridgeExit struct { - BridgeExit *BridgeExit `json:"bridge_exit"` - ImportedLocalExitRoot common.Hash `json:"imported_local_exit_root"` - InclusionProof [tree.DefaultHeight]common.Hash `json:"inclusion_proof"` - InclusionProofRER [tree.DefaultHeight]common.Hash `json:"inclusion_proof_rer"` - GlobalIndex *big.Int `json:"global_index"` + BridgeExit *BridgeExit `json:"bridge_exit"` + ImportedLocalExitRoot common.Hash `json:"imported_local_exit_root"` + InclusionProof [types.DefaultHeight]common.Hash `json:"inclusion_proof"` + InclusionProofRER [types.DefaultHeight]common.Hash `json:"inclusion_proof_rer"` + GlobalIndex *big.Int `json:"global_index"` } // Hash returns a hash that uniquely identifies the imported bridge exit diff --git a/aggsender/aggsender.go b/aggsender/aggsender.go index 61538863..dd251bf1 100644 --- a/aggsender/aggsender.go +++ b/aggsender/aggsender.go @@ -98,20 +98,26 @@ func (a *AggSender) sendCertificates(ctx context.Context) { // buildCertificate builds a certificate from the bridge events func (a *AggSender) buildCertificate(ctx context.Context, - bridgeEvents []bridgesync.Event, + bridges []bridgesync.Bridge, + claims []bridgesync.Claim, previousExitRoot common.Hash, lastHeight uint64) (*agglayer.Certificate, error) { - bridgeExits := make([]*agglayer.BridgeExit, 0, len(bridgeEvents)) - importedBridgeExits := make([]*agglayer.ImportedBridgeExit, 0, len(bridgeEvents)) - - for _, bridgeEvent := range bridgeEvents { - bridgeExit := convertBridgeToBridgeExit(bridgeEvent.Bridge) - importedBridgeExit := convertClaimToImportedBridgeExit(bridgeEvent.Claim, bridgeEvent.Bridge, bridgeExit) + bridgeExits := make([]*agglayer.BridgeExit, 0, len(bridges)) + importedBridgeExits := make([]*agglayer.ImportedBridgeExit, 0, len(claims)) + for _, bridge := range bridges { + bridgeExit := convertBridgeToBridgeExit(bridge) bridgeExits = append(bridgeExits, bridgeExit) + } + + for _, claim := range claims { + importedBridgeExit := convertClaimToImportedBridgeExit(claim) importedBridgeExits = append(importedBridgeExits, importedBridgeExit) } - depositCount := bridgeEvents[len(bridgeEvents)-1].Bridge.DepositCount + var depositCount uint32 + if len(bridges) > 0 { + depositCount = bridges[len(bridges)-1].DepositCount + } exitRoot, err := a.l2Syncer.GetExitRootByIndex(ctx, depositCount) if err != nil { @@ -121,14 +127,14 @@ func (a *AggSender) buildCertificate(ctx context.Context, return &agglayer.Certificate{ NetworkID: a.l2Syncer.OriginNetwork(), PrevLocalExitRoot: previousExitRoot, - NewLocalExitRoot: exitRoot, + NewLocalExitRoot: exitRoot.Hash, BridgeExits: bridgeExits, ImportedBridgeExits: importedBridgeExits, Height: lastHeight + 1, }, nil } -func convertBridgeToBridgeExit(bridge *bridgesync.Bridge) *agglayer.BridgeExit { +func convertBridgeToBridgeExit(bridge bridgesync.Bridge) *agglayer.BridgeExit { return &agglayer.BridgeExit{ LeafType: bridge.LeafType, TokenInfo: &agglayer.TokenInfo{ @@ -142,8 +148,19 @@ func convertBridgeToBridgeExit(bridge *bridgesync.Bridge) *agglayer.BridgeExit { } } -func convertClaimToImportedBridgeExit(claim *bridgesync.Claim, bridge *bridgesync.Bridge, - bridgeExit *agglayer.BridgeExit) *agglayer.ImportedBridgeExit { +func convertClaimToImportedBridgeExit(claim bridgesync.Claim) *agglayer.ImportedBridgeExit { + bridgeExit := &agglayer.BridgeExit{ + // LeafType: claim.LeafType, TODO + TokenInfo: &agglayer.TokenInfo{ + OriginNetwork: claim.OriginNetwork, + OriginTokenAddress: claim.OriginAddress, + }, + DestinationNetwork: claim.DestinationNetwork, + DestinationAddress: claim.DestinationAddress, + Amount: claim.Amount, + Metadata: claim.Metadata, + } + return &agglayer.ImportedBridgeExit{ BridgeExit: bridgeExit, ImportedLocalExitRoot: tree.CalculateRoot(bridgeExit.Hash(), claim.ProofLocalExitRoot, uint32(claim.GlobalIndex.Uint64())), @@ -171,12 +188,17 @@ func (a *AggSender) sendCertificatesForNetwork(ctx context.Context) error { return fmt.Errorf("error getting block number: %w", err) } - bridgeEvents, err := a.l2Syncer.GetClaimsAndBridges(ctx, lastSentCertificateBlock+1, lastFinalizedBlock.Nonce.Uint64()) + bridges, err := a.l2Syncer.GetBridges(ctx, lastSentCertificateBlock+1, lastFinalizedBlock.Nonce.Uint64()) + if err != nil { + return fmt.Errorf("error getting bridges: %w", err) + } + + claims, err := a.l2Syncer.GetClaims(ctx, lastSentCertificateBlock+1, lastFinalizedBlock.Nonce.Uint64()) if err != nil { - return fmt.Errorf("error getting claims and bridges: %w", err) + return fmt.Errorf("error getting claims: %w", err) } - if len(bridgeEvents) == 0 { + if len(bridges) == 0 && len(claims) == 0 { // nothing to send return nil } @@ -188,7 +210,7 @@ func (a *AggSender) sendCertificatesForNetwork(ctx context.Context) error { lastHeight = lastSentCertificate.Height } - certificate, err := a.buildCertificate(ctx, bridgeEvents, previousExitRoot, lastHeight) + certificate, err := a.buildCertificate(ctx, bridges, claims, previousExitRoot, lastHeight) if err != nil { return fmt.Errorf("error building certificate: %w", err) } diff --git a/tree/tree.go b/tree/tree.go index 20d46328..4b7745e5 100644 --- a/tree/tree.go +++ b/tree/tree.go @@ -252,11 +252,11 @@ func (t *Tree) Reorg(tx db.Txer, firstReorgedBlock uint64) error { } // CalculateRoot calculates the Merkle Root based on the leaf and proof of inclusion -func CalculateRoot(leafHash common.Hash, proof [DefaultHeight]common.Hash, index uint32) common.Hash { +func CalculateRoot(leafHash common.Hash, proof [types.DefaultHeight]common.Hash, index uint32) common.Hash { node := leafHash // Compute the Merkle root - for height := uint8(0); height < DefaultHeight; height++ { + for height := uint8(0); height < types.DefaultHeight; height++ { if (index>>height)&1 == 1 { node = crypto.Keccak256Hash(proof[height].Bytes(), node.Bytes()) } else {