Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add SyncL2TxHashRelayer #105

Merged
merged 3 commits into from
Apr 18, 2024
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
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));
}
});
Loading