diff --git a/aggoracle/chaingersender/evm.go b/aggoracle/chaingersender/evm.go index c004208d6..5af3e443d 100644 --- a/aggoracle/chaingersender/evm.go +++ b/aggoracle/chaingersender/evm.go @@ -6,17 +6,21 @@ import ( "math/big" "time" - "github.com/0xPolygon/cdk-contracts-tooling/contracts/l2-sovereign-chain-paris/polygonzkevmglobalexitrootv2" - cfgTypes "github.com/0xPolygon/cdk/config/types" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/l2-sovereign-chain-paris/globalexitrootmanagerl2sovereignchain" + cdkcommon "github.com/0xPolygon/cdk/common" + cfgtypes "github.com/0xPolygon/cdk/config/types" "github.com/0xPolygon/cdk/log" "github.com/0xPolygon/zkevm-ethtx-manager/ethtxmanager" ethtxtypes "github.com/0xPolygon/zkevm-ethtx-manager/types" "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) +const insertGERFuncName = "insertGlobalExitRoot" + type EthClienter interface { ethereum.LogFilterer ethereum.BlockNumberReader @@ -39,43 +43,51 @@ type EthTxManager interface { ) (common.Hash, error) } -type EVMChainGERSender struct { - logger *log.Logger - gerContract *polygonzkevmglobalexitrootv2.Polygonzkevmglobalexitrootv2 - gerAddr common.Address - client EthClienter - ethTxMan EthTxManager - gasOffset uint64 - waitPeriodMonitorTx time.Duration -} - type EVMConfig struct { GlobalExitRootL2Addr common.Address `mapstructure:"GlobalExitRootL2"` URLRPCL2 string `mapstructure:"URLRPCL2"` ChainIDL2 uint64 `mapstructure:"ChainIDL2"` GasOffset uint64 `mapstructure:"GasOffset"` - WaitPeriodMonitorTx cfgTypes.Duration `mapstructure:"WaitPeriodMonitorTx"` + WaitPeriodMonitorTx cfgtypes.Duration `mapstructure:"WaitPeriodMonitorTx"` EthTxManager ethtxmanager.Config `mapstructure:"EthTxManager"` } +type EVMChainGERSender struct { + logger *log.Logger + + l2GERManager *globalexitrootmanagerl2sovereignchain.Globalexitrootmanagerl2sovereignchain + l2GERManagerAddr common.Address + l2GERManagerAbi *abi.ABI + + ethTxMan EthTxManager + gasOffset uint64 + waitPeriodMonitorTx time.Duration +} + func NewEVMChainGERSender( logger *log.Logger, - l2GlobalExitRoot common.Address, + l2GERManagerAddr common.Address, l2Client EthClienter, ethTxMan EthTxManager, gasOffset uint64, waitPeriodMonitorTx time.Duration, ) (*EVMChainGERSender, error) { - gerContract, err := polygonzkevmglobalexitrootv2.NewPolygonzkevmglobalexitrootv2(l2GlobalExitRoot, l2Client) + l2GERManager, err := globalexitrootmanagerl2sovereignchain.NewGlobalexitrootmanagerl2sovereignchain( + l2GERManagerAddr, l2Client) + if err != nil { + return nil, err + } + + l2GERAbi, err := globalexitrootmanagerl2sovereignchain.Globalexitrootmanagerl2sovereignchainMetaData.GetAbi() if err != nil { return nil, err } return &EVMChainGERSender{ logger: logger, - gerContract: gerContract, - gerAddr: l2GlobalExitRoot, - client: l2Client, + l2GERManager: l2GERManager, + l2GERManagerAddr: l2GERManagerAddr, + l2GERManagerAbi: l2GERAbi, ethTxMan: ethTxMan, gasOffset: gasOffset, waitPeriodMonitorTx: waitPeriodMonitorTx, @@ -83,40 +95,36 @@ func NewEVMChainGERSender( } func (c *EVMChainGERSender) IsGERInjected(ger common.Hash) (bool, error) { - blockHashBigInt, err := c.gerContract.GlobalExitRootMap(&bind.CallOpts{Pending: false}, ger) + blockHashBigInt, err := c.l2GERManager.GlobalExitRootMap(&bind.CallOpts{Pending: false}, ger) if err != nil { - return false, fmt.Errorf("error calling gerContract.GlobalExitRootMap: %w", err) + return false, fmt.Errorf("failed to check if global exit root is injected %s: %w", ger, err) } - return common.BigToHash(blockHashBigInt) != common.Hash{}, nil + return common.BigToHash(blockHashBigInt) != cdkcommon.ZeroHash, nil } func (c *EVMChainGERSender) InjectGER(ctx context.Context, ger common.Hash) error { ticker := time.NewTicker(c.waitPeriodMonitorTx) defer ticker.Stop() - gerABI, err := polygonzkevmglobalexitrootv2.Polygonzkevmglobalexitrootv2MetaData.GetAbi() + updateGERTxInput, err := c.l2GERManagerAbi.Pack(insertGERFuncName, ger) if err != nil { return err } - // TODO: @Stefan-Ethernal should we invoke the PolygonZkEVMBridgeV2.updateGlobalExitRoot? - updateGERTxInput, err := gerABI.Pack("updateExitRoot", ger) + id, err := c.ethTxMan.Add(ctx, &c.l2GERManagerAddr, common.Big0, updateGERTxInput, c.gasOffset, nil) if err != nil { return err } - id, err := c.ethTxMan.Add(ctx, &c.gerAddr, big.NewInt(0), updateGERTxInput, c.gasOffset, nil) - if err != nil { - return err - } for { <-ticker.C c.logger.Debugf("waiting for tx %s to be mined", id.Hex()) res, err := c.ethTxMan.Result(ctx, id) if err != nil { - c.logger.Error("error calling ethTxMan.Result: ", err) + c.logger.Errorf("failed to check the transaction %s status: %s", id.Hex(), err) + continue } switch res.Status { @@ -124,13 +132,13 @@ func (c *EVMChainGERSender) InjectGER(ctx context.Context, ger common.Hash) erro ethtxtypes.MonitoredTxStatusSent: continue case ethtxtypes.MonitoredTxStatusFailed: - return fmt.Errorf("tx %s failed", res.ID) + return fmt.Errorf("tx %s failed", id.Hex()) case ethtxtypes.MonitoredTxStatusMined, ethtxtypes.MonitoredTxStatusSafe, ethtxtypes.MonitoredTxStatusFinalized: return nil default: - c.logger.Error("unexpected tx status: ", res.Status) + c.logger.Error("unexpected tx status:", res.Status) } } } diff --git a/aggoracle/oracle.go b/aggoracle/oracle.go index 82378f300..88ee56cec 100644 --- a/aggoracle/oracle.go +++ b/aggoracle/oracle.go @@ -68,6 +68,7 @@ func (a *AggOracle) Start(ctx context.Context) { if err := a.processLatestGER(ctx, &blockNumToFetch); err != nil { a.handleGERProcessingError(err, blockNumToFetch) } + case <-ctx.Done(): return } @@ -85,12 +86,13 @@ func (a *AggOracle) processLatestGER(ctx context.Context, blockNumToFetch *uint6 // Update the block number for the next iteration *blockNumToFetch = blockNum - alreadyInjected, err := a.chainSender.IsGERInjected(gerToInject) + isGERInjected, err := a.chainSender.IsGERInjected(gerToInject) if err != nil { return fmt.Errorf("error checking if GER is already injected: %w", err) } - if alreadyInjected { - a.logger.Debugf("GER %s already injected", gerToInject.Hex()) + + if isGERInjected { + a.logger.Debugf("GER %s is already injected", gerToInject.Hex()) return nil } diff --git a/common/common.go b/common/common.go index 152069027..2fe71dce2 100644 --- a/common/common.go +++ b/common/common.go @@ -14,6 +14,10 @@ import ( "github.com/iden3/go-iden3-crypto/keccak256" ) +var ( + ZeroHash = common.HexToHash("0x0") +) + // Uint64ToBytes converts a uint64 to a byte slice func Uint64ToBytes(num uint64) []byte { const uint64ByteSize = 8 diff --git a/go.mod b/go.mod index 6b0482477..4f42d6e72 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/0xPolygon/cdk go 1.22.4 require ( - github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20241211191239-915ad3f37c3b + github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20241217070745-faeedeaaea77 github.com/0xPolygon/cdk-data-availability v0.0.10 github.com/0xPolygon/cdk-rpc v0.0.0-20241004114257-6c3cb6eebfb6 github.com/0xPolygon/zkevm-ethtx-manager v0.2.1 diff --git a/go.sum b/go.sum index 29fb57330..ebddd6299 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ -github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20240826154954-f6182d2b17a2 h1:N5qvWG4amhUt6d1F4Kf8AdJZs4z7/xZfE3v/Im2afNM= -github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20240826154954-f6182d2b17a2/go.mod h1:mFlcEjsm2YBBsu8atHJ3zyVnwM+Z/fMXpVmIJge+WVU= -github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20241211191239-915ad3f37c3b h1:IvCbb1Pl6W0Ty7GFyq71O0KGOtSg82nqn5zi6UVGivk= -github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20241211191239-915ad3f37c3b/go.mod h1:mFlcEjsm2YBBsu8atHJ3zyVnwM+Z/fMXpVmIJge+WVU= +github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20241217070745-faeedeaaea77 h1:EEPwISL8b1mIh0k7l0/2b2MxzbHfakkIUdFNKiD+dwg= +github.com/0xPolygon/cdk-contracts-tooling v0.0.0-20241217070745-faeedeaaea77/go.mod h1:mFlcEjsm2YBBsu8atHJ3zyVnwM+Z/fMXpVmIJge+WVU= github.com/0xPolygon/cdk-data-availability v0.0.10 h1:pVcke2I7GuPH7JeRLKokEOHffPMwEHmJd9yDXHqh9B4= github.com/0xPolygon/cdk-data-availability v0.0.10/go.mod h1:nn5RmnkzOiugAxizSbaYnA+em79YLLLoR25i0UlKc5Q= github.com/0xPolygon/cdk-rpc v0.0.0-20241004114257-6c3cb6eebfb6 h1:FXL/rcO7/GtZ3kRFw+C7J6vmGnl8gcazg+Gh/NVmnas= diff --git a/lastgersync/evmdownloader.go b/lastgersync/evmdownloader.go index 7a695faa3..9217dfa12 100644 --- a/lastgersync/evmdownloader.go +++ b/lastgersync/evmdownloader.go @@ -7,7 +7,8 @@ import ( "math/big" "time" - "github.com/0xPolygon/cdk-contracts-tooling/contracts/l2-sovereign-chain-paris/polygonzkevmglobalexitrootv2" + "github.com/0xPolygon/cdk-contracts-tooling/contracts/l2-sovereign-chain-paris/globalexitrootmanagerl2sovereignchain" + cdkcommon "github.com/0xPolygon/cdk/common" "github.com/0xPolygon/cdk/db" "github.com/0xPolygon/cdk/l1infotreesync" "github.com/0xPolygon/cdk/log" @@ -26,8 +27,7 @@ type EthClienter interface { type downloader struct { *sync.EVMDownloaderImplementation - l2Client EthClienter - gerContract *polygonzkevmglobalexitrootv2.Polygonzkevmglobalexitrootv2 + l2GERManager *globalexitrootmanagerl2sovereignchain.Globalexitrootmanagerl2sovereignchain l1InfoTreesync *l1infotreesync.L1InfoTreeSync processor *processor rh *sync.RetryHandler @@ -35,14 +35,15 @@ type downloader struct { func newDownloader( l2Client EthClienter, - globalExitRootL2 common.Address, - l1InfoTreesync *l1infotreesync.L1InfoTreeSync, + l2GERAddr common.Address, + l1InfoTreeSync *l1infotreesync.L1InfoTreeSync, processor *processor, rh *sync.RetryHandler, blockFinality *big.Int, waitForNewBlocksPeriod time.Duration, ) (*downloader, error) { - gerContract, err := polygonzkevmglobalexitrootv2.NewPolygonzkevmglobalexitrootv2(globalExitRootL2, l2Client) + gerContract, err := globalexitrootmanagerl2sovereignchain.NewGlobalexitrootmanagerl2sovereignchain( + l2GERAddr, l2Client) if err != nil { return nil, err } @@ -51,9 +52,8 @@ func newDownloader( EVMDownloaderImplementation: sync.NewEVMDownloaderImplementation( "lastgersync", l2Client, blockFinality, waitForNewBlocksPeriod, nil, nil, nil, rh, ), - l2Client: l2Client, - gerContract: gerContract, - l1InfoTreesync: l1InfoTreesync, + l2GERManager: gerContract, + l1InfoTreesync: l1InfoTreeSync, processor: processor, rh: rh, }, nil @@ -148,10 +148,11 @@ func (d *downloader) getGERsFromIndex(ctx context.Context, fromL1InfoTreeIndex u if err != nil { return nil, fmt.Errorf("error calling GetInfoByIndex: %w", err) } - gers = append(gers, Event{ - L1InfoTreeIndex: i, - GlobalExitRoot: info.GlobalExitRoot, - }) + gers = append(gers, + Event{ + L1InfoTreeIndex: i, + GlobalExitRoot: info.GlobalExitRoot, + }) } return gers, nil @@ -161,20 +162,16 @@ func (d *downloader) setGreatestGERInjectedFromList(b *sync.EVMBlock, list []Eve for _, event := range list { var attempts int for { - timestamp, err := d.gerContract.GlobalExitRootMap( - &bind.CallOpts{Pending: false}, event.GlobalExitRoot, - ) + blockHashBigInt, err := d.l2GERManager.GlobalExitRootMap(&bind.CallOpts{Pending: false}, event.GlobalExitRoot) if err != nil { attempts++ - log.Errorf( - "error calling contract function GlobalExitRootMap with ger %s: %v", - event.GlobalExitRoot.Hex(), err, - ) + log.Errorf("failed to check if global exit root %s is injected on L2: %s", event.GlobalExitRoot.Hex(), err) d.rh.Handle("GlobalExitRootMap", attempts) continue } - if timestamp.Cmp(big.NewInt(0)) == 1 { + + if common.BigToHash(blockHashBigInt) != cdkcommon.ZeroHash { b.Events = []interface{}{event} } diff --git a/sync/evmdownloader.go b/sync/evmdownloader.go index 20f48f489..b849a5173 100644 --- a/sync/evmdownloader.go +++ b/sync/evmdownloader.go @@ -98,7 +98,7 @@ func (d *EVMDownloader) Download(ctx context.Context, fromBlock uint64, download lastBlock = d.WaitForNewBlocks(ctx, fromBlock-1) continue } - d.log.Debugf("getting events from blocks %d to %d", fromBlock, toBlock) + d.log.Debugf("getting events from blocks %d to %d", fromBlock, toBlock) blocks := d.GetEventsByBlockRange(ctx, fromBlock, toBlock) for _, b := range blocks { d.log.Debugf("sending block %d to the driver (with events)", b.Num)