Skip to content

Commit

Permalink
faet: aggsender
Browse files Browse the repository at this point in the history
feat: expand config

fix: nothing to send

feat: use finality as the syncer

fix: rebase

feat: add sequencer private key to config

fix: add new fields

fix: config

fix: merge fix

fix: remove ImportedExitRoots field

feat: build certificates for L1 as well

feat: set previous and new exit root in certificate

fix: reorg detector for both l1 and l2

fix: rebase

feat: add aggsender to run cmd

feat: sign certificate POC

feat: latest spec types

fix: update comments

fix: resolve TODOs on claim

fix: height

fix: rebase

feat: new changes

fix: lint
  • Loading branch information
goran-ethernal committed Sep 19, 2024
1 parent db81a26 commit e7c7d70
Show file tree
Hide file tree
Showing 20 changed files with 699 additions and 38 deletions.
17 changes: 16 additions & 1 deletion aggregator/agglayer_client.go → agglayer/client.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aggregator
package agglayer

import (
"context"
Expand All @@ -17,6 +17,7 @@ import (
type AgglayerClientInterface interface {
SendTx(signedTx SignedTx) (common.Hash, error)
WaitTxToBeMined(hash common.Hash, ctx context.Context) error
SendCertificate(certificate *SignedCertificate) error
}

// AggLayerClient is the client that will be used to interact with the AggLayer
Expand Down Expand Up @@ -79,3 +80,17 @@ func (c *AggLayerClient) WaitTxToBeMined(hash common.Hash, ctx context.Context)
}
}
}

// SendCertificate sends a certificate to the AggLayer
func (c *AggLayerClient) SendCertificate(certificate *SignedCertificate) error {
response, err := rpc.JSONRPCCall(c.url, "interop_sendCertificate", certificate)
if err != nil {
return err
}

if response.Error != nil {
return fmt.Errorf("%v %v", response.Error.Code, response.Error.Message)
}

return nil
}
2 changes: 1 addition & 1 deletion aggregator/agglayer_tx.go → agglayer/tx.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aggregator
package agglayer

import (
"crypto/ecdsa"
Expand Down
104 changes: 104 additions & 0 deletions agglayer/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package agglayer

import (
"math/big"

cdkcommon "github.com/0xPolygon/cdk/common"
"github.com/0xPolygon/cdk/tree/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)

type LeafType uint8

func (l LeafType) Uint8() uint8 {
return uint8(l)
}

const (
LeafTypeAsset LeafType = 0
LeafTypeMessage LeafType = 1
)

// Certificate is the data structure that will be sent to the aggLayer
type Certificate struct {
NetworkID uint32 `json:"network_id"`
Height uint64 `json:"height"`
PrevLocalExitRoot common.Hash `json:"prev_local_exit_root"`
NewLocalExitRoot common.Hash `json:"new_local_exit_root"`
BridgeExits []*BridgeExit `json:"bridge_exits"`
ImportedBridgeExits []*ImportedBridgeExit `json:"imported_bridge_exits"`
}

// Hash returns a hash that uniquely identifies the certificate
func (c *Certificate) Hash() common.Hash {
importedBridgeHashes := make([][]byte, 0, len(c.ImportedBridgeExits))
for _, claim := range c.ImportedBridgeExits {
importedBridgeHashes = append(importedBridgeHashes, claim.Hash().Bytes())
}

incomeCommitment := crypto.Keccak256Hash(importedBridgeHashes...)
outcomeCommitment := c.NewLocalExitRoot

return crypto.Keccak256Hash(outcomeCommitment.Bytes(), incomeCommitment.Bytes())
}

// SignedCertificate is the struct that contains the certificate and the signature of the signer
type SignedCertificate struct {
*Certificate
Signature []byte `json:"signature"`
}

// TokenInfo encapsulates the information to uniquely identify a token on the origin network.
type TokenInfo struct {
OriginNetwork uint32 `json:"origin_network"`
OriginTokenAddress common.Address `json:"origin_token_address"`
}

// GlobalIndex represents the global index of an imported bridge exit
type GlobalIndex struct {
MainnetFlag bool `json:"mainnet_flag"`
RollupIndex uint32 `json:"rollup_index"`
LeafIndex uint32 `json:"leaf_index"`
}

// BridgeExit represents a token bridge exit
type BridgeExit struct {
LeafType LeafType `json:"leaf_type"`
TokenInfo *TokenInfo `json:"token_info"`
DestinationNetwork uint32 `json:"destination_network"`
DestinationAddress common.Address `json:"destination_address"`
Amount *big.Int `json:"amount"`
Metadata []byte `json:"metadata"`
}

// Hash returns a hash that uniquely identifies the bridge exit
func (c *BridgeExit) Hash() common.Hash {
if c.Amount == nil {
c.Amount = big.NewInt(0)
}

return crypto.Keccak256Hash(
[]byte{c.LeafType.Uint8()},
cdkcommon.Uint32ToBytes(c.TokenInfo.OriginNetwork),
c.TokenInfo.OriginTokenAddress.Bytes(),
cdkcommon.Uint32ToBytes(c.DestinationNetwork),
c.DestinationAddress.Bytes(),
c.Amount.Bytes(),
crypto.Keccak256(c.Metadata),
)
}

// 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 [types.DefaultHeight]common.Hash `json:"inclusion_proof"`
InclusionProofRER [types.DefaultHeight]common.Hash `json:"inclusion_proof_rer"`
GlobalIndex *GlobalIndex `json:"global_index"`
}

// Hash returns a hash that uniquely identifies the imported bridge exit
func (c *ImportedBridgeExit) Hash() common.Hash {
return c.BridgeExit.Hash()
}
13 changes: 7 additions & 6 deletions aggregator/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/0xPolygon/cdk-rpc/rpc"
cdkTypes "github.com/0xPolygon/cdk-rpc/types"
"github.com/0xPolygon/cdk/agglayer"
ethmanTypes "github.com/0xPolygon/cdk/aggregator/ethmantypes"
"github.com/0xPolygon/cdk/aggregator/prover"
cdkcommon "github.com/0xPolygon/cdk/common"
Expand Down Expand Up @@ -95,7 +96,7 @@ type Aggregator struct {
exit context.CancelFunc

sequencerPrivateKey *ecdsa.PrivateKey
aggLayerClient AgglayerClientInterface
aggLayerClient agglayer.AgglayerClientInterface
}

// New creates a new aggregator.
Expand Down Expand Up @@ -165,14 +166,14 @@ func New(
}

var (
aggLayerClient AgglayerClientInterface
aggLayerClient agglayer.AgglayerClientInterface
sequencerPrivateKey *ecdsa.PrivateKey
)

if !cfg.SyncModeOnlyEnabled && cfg.SettlementBackend == AggLayer {
aggLayerClient = NewAggLayerClient(cfg.AggLayerURL)
aggLayerClient = agglayer.NewAggLayerClient(cfg.AggLayerURL)

sequencerPrivateKey, err = newKeyFromKeystore(cfg.SequencerPrivateKey)
sequencerPrivateKey, err = cdkcommon.NewKeyFromKeystore(cfg.SequencerPrivateKey)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -919,10 +920,10 @@ func (a *Aggregator) settleWithAggLayer(
inputs ethmanTypes.FinalProofInputs) bool {
proofStrNo0x := strings.TrimPrefix(inputs.FinalProof.Proof, "0x")
proofBytes := common.Hex2Bytes(proofStrNo0x)
tx := Tx{
tx := agglayer.Tx{
LastVerifiedBatch: cdkTypes.ArgUint64(proof.BatchNumber - 1),
NewVerifiedBatch: cdkTypes.ArgUint64(proof.BatchNumberFinal),
ZKP: ZKP{
ZKP: agglayer.ZKP{
NewStateRoot: common.BytesToHash(inputs.NewStateRoot),
NewLocalExitRoot: common.BytesToHash(inputs.NewLocalExitRoot),
Proof: cdkTypes.ArgBytes(proofBytes),
Expand Down
21 changes: 0 additions & 21 deletions aggregator/config.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package aggregator

import (
"crypto/ecdsa"
"fmt"
"math/big"
"os"
"path/filepath"

"github.com/0xPolygon/cdk/aggregator/db"
"github.com/0xPolygon/cdk/config/types"
"github.com/0xPolygon/cdk/log"
"github.com/0xPolygonHermez/zkevm-ethtx-manager/ethtxmanager"
syncronizerConfig "github.com/0xPolygonHermez/zkevm-synchronizer-l1/config"
"github.com/ethereum/go-ethereum/accounts/keystore"
)

// SettlementBackend is the type of the settlement backend
Expand Down Expand Up @@ -164,20 +160,3 @@ type StreamClientCfg struct {
// Log is the log configuration
Log log.Config `mapstructure:"Log"`
}

// newKeyFromKeystore creates a private key from a keystore file
func newKeyFromKeystore(cfg types.KeystoreFileConfig) (*ecdsa.PrivateKey, error) {
if cfg.Path == "" && cfg.Password == "" {
return nil, nil
}
keystoreEncrypted, err := os.ReadFile(filepath.Clean(cfg.Path))
if err != nil {
return nil, err
}
key, err := keystore.DecryptKey(keystoreEncrypted, cfg.Password)
if err != nil {
return nil, err
}

return key.PrivateKey, nil
}
Loading

0 comments on commit e7c7d70

Please sign in to comment.