Skip to content

Commit

Permalink
add SyncL2TxHashRelayer (#105)
Browse files Browse the repository at this point in the history
* add SyncL2TxHashRelayer

* optimise SyncL2TxHashRelayer

* del useless dependencies
  • Loading branch information
zkJoaquin authored Apr 18, 2024
1 parent 04155fe commit f8f394d
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 0 deletions.
2 changes: 2 additions & 0 deletions contracts/dev-contracts/DummyArbitrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {IL1Gateway} from "../interfaces/IL1Gateway.sol";
contract DummyArbitrator is IArbitrator, OwnableUpgradeable, UUPSUpgradeable, ReentrancyGuardUpgradeable {
event ReceiveMessage(uint256 value, bytes callData);

IL1Gateway public primaryChainGateway;

function initialize() external initializer {
__Ownable_init();
__UUPSUpgradeable_init();
Expand Down
38 changes: 38 additions & 0 deletions contracts/dev-contracts/SyncL2TxHashRelayer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

pragma solidity ^0.8.0;

import {IArbitrator} from "../interfaces/IArbitrator.sol";
import {IZkLink} from "../interfaces/IZkLink.sol";

contract SyncL2TxHashRelayer {
/// @dev The address of the arbitrator contract
IArbitrator public immutable ARBITRATOR;

constructor(IArbitrator _arbitrator) {
ARBITRATOR = _arbitrator;
}

function claimPrimaryChainSyncL2TxHashMessage(
address _sourceChainCanonicalMessageService,
bytes calldata _sourceChainClaimCallData,
address _secondaryChainL1Gateway,
bytes32 _secondaryChainL2TxHash,
bytes32 _primaryChainL2TxHash,
bytes calldata _forwardParams
) external payable {
// Send l2 tx hash to secondary chain by gateway
bytes[] memory gatewayDataList = new bytes[](1);
bytes memory callData = abi.encodeCall(IZkLink.syncL2TxHash, (_secondaryChainL2TxHash, _primaryChainL2TxHash));
gatewayDataList[0] = abi.encode(_secondaryChainL1Gateway, 0, callData);

ARBITRATOR.claimMessage{value: msg.value}(
_sourceChainCanonicalMessageService,
_sourceChainClaimCallData,
ARBITRATOR.primaryChainGateway(),
0,
abi.encode(gatewayDataList),
_forwardParams
);
}
}
3 changes: 3 additions & 0 deletions contracts/interfaces/IArbitrator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ interface IArbitrator {
/// @notice Return true if relayer is active
function isRelayerActive(address _relayer) external view returns (bool);

/// @notice Return the primary chain gateway
function primaryChainGateway() external view returns (IL1Gateway);

/// @notice Enqueue message from EthereumGateway
/// @dev Used by EthereumGateway to temporarily store message
/// @param _value The msg value
Expand Down
1 change: 1 addition & 0 deletions hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require('./script/deploy_erc20_bridge');
require('./script/deploy_governance');
require('./script/deploy_linea_l2_governance');
require('./script/deploy_zklink_token');
require('./script/deploy_sync_l2_txHash_relayer');

const BaseConfig = require('./hardhat.base.config');

Expand Down
8 changes: 8 additions & 0 deletions script/deploy_log_name.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ const DEPLOY_LOG_ARBITRATOR_VERIFIED = 'arbitratorVerified';
const DEPLOY_LOG_ARBITRATOR_TARGET = 'arbitratorTarget';
const DEPLOY_LOG_ARBITRATOR_TARGET_VERIFIED = 'arbitratorTargetVerified';

// consumed in deploy_sync_l2_txHash_relayer.js
const DEPLOY_SYNCL2TXHASHRELAYER_LOG_PREFIX = 'deploy_syncL2TxHashRelayer';
const DEPLOY_LOG_SYNCL2TXHASHRELAYER = 'syncL2TxHashRelayer';
const DEPLOY_LOG_SYNCL2TXHASHRELAYER_VERIFIED = 'syncL2TxHashRelayerVerified';

// consumed in deploy_governance.js
const DEPLOY_GOVERNANCE_LOG_PREFIX = 'deploy_governance';
const DEPLOY_LOG_GOVERNANCE = 'governance';
Expand Down Expand Up @@ -85,4 +90,7 @@ module.exports = {
DEPLOY_LOG_ZKLINK_TOKEN_TARGET,
DEPLOY_LOG_ZKLINK_TOKEN_PROXY_VERIFIED,
DEPLOY_LOG_ZKLINK_TOKEN_TARGET_VERIFIED,
DEPLOY_SYNCL2TXHASHRELAYER_LOG_PREFIX,
DEPLOY_LOG_SYNCL2TXHASHRELAYER,
DEPLOY_LOG_SYNCL2TXHASHRELAYER_VERIFIED,
};
65 changes: 65 additions & 0 deletions script/deploy_sync_l2_txHash_relayer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const fs = require('fs');
const {
verifyContractCode,
createOrGetDeployLog,
ChainContractDeployer,
getDeployTx,
readDeployLogField,
} = require('./utils');
const logName = require('./deploy_log_name');
const { task, types } = require('hardhat/config');

function getRelayerContractName() {
return 'SyncL2TxHashRelayer';
}

task('deploySyncL2TxHashRelayer', 'Deploy SyncL2TxHashRelayer')
.addParam(
'arbitrator',
'The arbitrator address (default get from arbitrator deploy log)',
undefined,
types.string,
true,
)
.addParam('skipVerify', 'Skip verify', false, types.boolean, true)
.setAction(async (taskArgs, hardhat) => {
let arbitrator = taskArgs.arbitrator;
if (arbitrator === undefined) {
arbitrator = readDeployLogField(logName.DEPLOY_ARBITRATOR_LOG_PREFIX, logName.DEPLOY_LOG_ARBITRATOR);
}
let skipVerify = taskArgs.skipVerify;
console.log('arbitrator', arbitrator);
console.log('skip verify contracts?', skipVerify);

const contractDeployer = new ChainContractDeployer(hardhat);
await contractDeployer.init();
const deployerWallet = contractDeployer.deployerWallet;

const { deployLogPath, deployLog } = createOrGetDeployLog(logName.DEPLOY_SYNCL2TXHASHRELAYER_LOG_PREFIX);
deployLog[logName.DEPLOY_LOG_DEPLOYER] = deployerWallet.address;
fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2));

// deploy syncL2TxHashRelayer
let syncL2TxHashRelayerAddr;
if (!(logName.DEPLOY_LOG_SYNCL2TXHASHRELAYER in deployLog)) {
console.log('deploy syncL2TxHashRelayer...');
const contractName = getRelayerContractName();
const contract = await contractDeployer.deployContract(contractName, [arbitrator]);
const transaction = await getDeployTx(contract);
syncL2TxHashRelayerAddr = await contract.getAddress();
deployLog[logName.DEPLOY_LOG_SYNCL2TXHASHRELAYER] = syncL2TxHashRelayerAddr;
deployLog[logName.DEPLOY_LOG_DEPLOY_TX_HASH] = transaction.hash;
deployLog[logName.DEPLOY_LOG_DEPLOY_BLOCK_NUMBER] = transaction.blockNumber;
fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2));
} else {
syncL2TxHashRelayerAddr = deployLog[logName.DEPLOY_LOG_SYNCL2TXHASHRELAYER];
}
console.log('syncL2TxHashRelayer', syncL2TxHashRelayerAddr);

// verify target contract
if (!(logName.DEPLOY_LOG_SYNCL2TXHASHRELAYER_VERIFIED in deployLog) && !skipVerify) {
await verifyContractCode(hardhat, syncL2TxHashRelayerAddr, [arbitrator]);
deployLog[logName.DEPLOY_LOG_SYNCL2TXHASHRELAYER_VERIFIED] = true;
fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2));
}
});

0 comments on commit f8f394d

Please sign in to comment.