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 whiteList contract and method #12

Merged
merged 11 commits into from Aug 16, 2021
@@ -27,3 +27,5 @@ src/.DS_Store

apidoc/
node_modules

artifacts/
@@ -9,4 +9,5 @@ interface IUpgradableECCM {
function paused() external view returns (bool);
function upgradeToNew(address) external returns (bool);
function isOwner() external view returns (bool);
function setChainId(uint64 _newChainId) external returns (bool);
}
@@ -2,7 +2,10 @@ pragma solidity ^0.5.0;
import "./../../../libs/common/ZeroCopySource.sol";
import "./../../../libs/common/ZeroCopySink.sol";
import "./../../../libs/utils/Utils.sol";
import "./../../../libs/math/SafeMath.sol";
library ECCUtils {
using SafeMath for uint256;

struct Header {
uint32 version;
uint64 chainId;
@@ -47,7 +50,7 @@ library ECCUtils {
(value, off) = ZeroCopySource.NextVarBytes(_auditPath, off);

bytes32 hash = Utils.hashLeaf(value);
uint size = (_auditPath.length - off) / 33;
uint size = _auditPath.length.sub(off).div(33);
bytes32 nodeHash;
byte pos;
for (uint i = 0; i < size; i++) {
@@ -111,8 +114,7 @@ library ECCUtils {
function verifySig(bytes memory _rawHeader, bytes memory _sigList, address[] memory _keepers, uint _m) internal pure returns (bool){
bytes32 hash = getHeaderHash(_rawHeader);

uint signed = 0;
uint sigCount = _sigList.length / POLYCHAIN_SIGNATURE_LEN;
uint sigCount = _sigList.length.div(POLYCHAIN_SIGNATURE_LEN);
address[] memory signers = new address[](sigCount);
bytes32 r;
bytes32 s;
@@ -1,4 +1,5 @@
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

import "./../../../libs/math/SafeMath.sol";
import "./../../../libs/common/ZeroCopySource.sol";
@@ -11,12 +12,41 @@ import "./../interface/IEthCrossChainData.sol";
contract EthCrossChainManager is IEthCrossChainManager, UpgradableECCM {
using SafeMath for uint256;

mapping(address => bool) public whiteListFromContract;
mapping(address => bool) public whiteListToContract;
mapping(bytes => bool) public whiteListMethod;
mapping(bytes => bool) public unsetEpochPkBytes;

event InitGenesisBlockEvent(uint256 height, bytes rawHeader);
event ChangeBookKeeperEvent(uint256 height, bytes rawHeader);
event CrossChainEvent(address indexed sender, bytes txId, address proxyOrAssetContract, uint64 toChainId, bytes toContract, bytes rawdata);
event VerifyHeaderAndExecuteTxEvent(uint64 fromChainID, bytes toContract, bytes crossChainTxHash, bytes fromChainTxHash);
constructor(address _eccd) UpgradableECCM(_eccd) public {}
constructor(
address _eccd,
uint64 _chainId,
address[] memory fromContractWhiteList,
address[] memory toContractWhiteList,
bytes[] memory methodWhiteList,
bytes memory curEpochPkBytes
) UpgradableECCM(_eccd,_chainId) public {
for (uint i=0;i<fromContractWhiteList.length;i++) {
whiteListFromContract[fromContractWhiteList[i]] = true;
}
for (uint i=0;i<toContractWhiteList.length;i++) {
whiteListToContract[toContractWhiteList[i]] = true;
}
for (uint i=0;i<methodWhiteList.length;i++) {
whiteListMethod[methodWhiteList[i]] = true;
}
unsetEpochPkBytes[curEpochPkBytes] = true;
}

function recoverEpochPk(bytes memory EpochPkBytes) whenPaused public {
require(unsetEpochPkBytes[EpochPkBytes],"Don't arbitrarily set");
unsetEpochPkBytes[EpochPkBytes] = false;
IEthCrossChainData(EthCrossChainDataAddress).putCurEpochConPubKeyBytes(EpochPkBytes);
}

/* @notice sync Poly chain genesis block header to smart contrat
* @dev this function can only be called once, nextbookkeeper of rawHeader can't be empty
* @param rawHeader Poly chain genesis block raw header or raw Header including switching consensus peers info
@@ -89,6 +119,9 @@ contract EthCrossChainManager is IEthCrossChainManager, UpgradableECCM {
* @return true or false
*/
function crossChain(uint64 toChainId, bytes calldata toContract, bytes calldata method, bytes calldata txData) whenNotPaused external returns (bool) {
// Only allow whitelist contract to call
require(whiteListFromContract[msg.sender],"Invalid from contract");

// Load Ethereum cross chain data contract
IEthCrossChainData eccd = IEthCrossChainData(EthCrossChainDataAddress);

@@ -157,11 +190,15 @@ contract EthCrossChainManager is IEthCrossChainManager, UpgradableECCM {
require(eccd.markFromChainTxExist(toMerkleValue.fromChainID, Utils.bytesToBytes32(toMerkleValue.txHash)), "Save crosschain tx exist failed!");

// Ethereum ChainId is 2, we need to check the transaction is for Ethereum network
require(toMerkleValue.makeTxParam.toChainId == uint64(2), "This Tx is not aiming at Ethereum network!");
require(toMerkleValue.makeTxParam.toChainId == chainId, "This Tx is not aiming at this network!");

// Obtain the targeting contract, so that Ethereum cross chain manager contract can trigger the executation of cross chain tx on Ethereum side
address toContract = Utils.bytesToAddress(toMerkleValue.makeTxParam.toContract);

// only invoke PreWhiteListed Contract and method For Now
require(whiteListToContract[toContract],"Invalid to contract");
require(whiteListMethod[toMerkleValue.makeTxParam.method],"Invalid method");

//TODO: check this part to make sure we commit the next line when doing local net UT test
require(_executeCrossChainTx(toContract, toMerkleValue.makeTxParam.method, toMerkleValue.makeTxParam.args, toMerkleValue.makeTxParam.fromContract, toMerkleValue.fromChainID), "Execute CrossChain Tx failed!");

@@ -48,4 +48,11 @@ contract EthCrossChainManagerProxy is IEthCrossChainManagerProxy, Ownable, Pausa
function getEthCrossChainManager() whenNotPaused public view returns (address) {
return EthCrossChainManagerAddr_;
}
function changeManagerChainID(uint64 _newChainId) onlyOwner whenPaused public {
IUpgradableECCM eccm = IUpgradableECCM(EthCrossChainManagerAddr_);
if (!eccm.paused()) {
require(eccm.pause(), "Pause old EthCrossChainManager contract failed!");
}
require(eccm.setChainId(_newChainId), "set chain ID failed. ");
}
}
@@ -7,8 +7,11 @@ import "./../../../libs/ownership/Ownable.sol";

contract UpgradableECCM is IUpgradableECCM, Ownable, Pausable {
address public EthCrossChainDataAddress;
constructor (address ethCrossChainDataAddr) Pausable() Ownable() public {
uint64 public chainId;

constructor (address ethCrossChainDataAddr, uint64 _chainId) Pausable() Ownable() public {
EthCrossChainDataAddress = ethCrossChainDataAddr;
chainId = _chainId;
}
function pause() onlyOwner public returns (bool) {
if (!paused()) {
@@ -38,4 +41,9 @@ contract UpgradableECCM is IUpgradableECCM, Ownable, Pausable {
eccd.transferOwnership(newEthCrossChainManagerAddress);
return true;
}

function setChainId(uint64 _newChainId) whenPaused onlyOwner public returns (bool) {
chainId = _newChainId;
return true;
}
}