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

[R4F]Gov/Validator/Slash modification for refactor of cross chain mechanism #14

Merged
merged 10 commits into from
Jun 12, 2020
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
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ node generate-systemReward.js --mock true
node generate-validatorset.js --mock true
node generate-system.js --mock true
node generate-crosschain.js --mock true
node generate-govhub.js --mock true
node generate-tokenhub.js --mock true
node generate-tendermintlightclient.js --mock true
node generate-relayerincentivizecontract.js --roundSize 30 --maximumWeight 3 --mock true
Expand Down
239 changes: 138 additions & 101 deletions contracts/BSCValidatorSet.sol

Large diffs are not rendered by default.

239 changes: 138 additions & 101 deletions contracts/BSCValidatorSet.template

Large diffs are not rendered by default.

45 changes: 18 additions & 27 deletions contracts/CrossChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ contract CrossChain is System, ICrossChain, IParamSubscriber{
uint8 constant public ACK_PACKAGE = 0x01;
uint8 constant public FAIL_ACK_PACKAGE = 0x02;

uint16 constant bscChainID = 0x0060;
uint256 constant crossChainKeyPrefix = 0x0000000000000000000000000000000000000000000000000000000001006000; // last 6 bytes

mapping(uint8 => address) public channelHandlerContractMap;
Expand Down Expand Up @@ -102,6 +101,10 @@ contract CrossChain is System, ICrossChain, IParamSubscriber{
isRelayRewardFromSystemReward[GOV_CHANNELID] = true;
registeredContractMap[GOV_HUB_ADDR] = true;

channelHandlerContractMap[SLASH_CHANNELID] = SLASH_CONTRACT_ADDR;
isRelayRewardFromSystemReward[SLASH_CHANNELID] = true;
registeredContractMap[SLASH_CONTRACT_ADDR] = true;

alreadyInit=true;
}

Expand Down Expand Up @@ -194,7 +197,7 @@ function encodePayload(uint8 packageType, uint256 syncRelayFee, uint256 ackRelay
if (packageType == SYNC_PACKAGE) {
IRelayerIncentivize(INCENTIVIZE_ADDR).addReward(headerRelayer, msg.sender, syncRelayFee, isRelayRewardFromSystemReward[channelIdLocal]);
address handlerContract = channelHandlerContractMap[channelIdLocal];
try IApplication(handlerContract).handleSyncPackage(channelIdLocal, msgBytes) returns (bytes memory responsePayload) {
try IApplication(handlerContract).handleSynPackage(channelIdLocal, msgBytes) returns (bytes memory responsePayload) {
emit crossChainPackage(bscChainID, channelSendSequenceMap[channelIdLocal], channelIdLocal, encodePayload(ACK_PACKAGE, 0, ackRelayFee, responsePayload));
} catch Error(string memory reason) {
emit crossChainPackage(bscChainID, channelSendSequenceMap[channelIdLocal], channelIdLocal, encodePayload(FAIL_ACK_PACKAGE, 0, ackRelayFee, msgBytes));
Expand Down Expand Up @@ -236,35 +239,23 @@ function encodePayload(uint8 packageType, uint256 syncRelayFee, uint256 ackRelay
function updateParam(string calldata key, bytes calldata value) onlyGov external override {
bytes memory localKey = bytes(key);
bytes memory localValue = value;
require(localKey.length == 1, "expected key length is 1");
// length is 8, used to skip receive sequence
// first byte is channel Id, second byte is relayRewardFromSystemReward
require(localKey.length == 2, "expected key length is 2");
// length is 20, used to add or delete channel
require(localValue.length == 8 || localValue.length == 20, "expected value length is 8 or 20");
require(localValue.length == 20, "expected value length is 20");

uint256 bytes32Key;
assembly {
bytes32Key := mload(add(localKey, 1))
}
uint8 channelId = uint8(bytes32Key);

if (localValue.length == 8) {
uint64 sequence;
assembly {
sequence := mload(add(localValue, 8))
}
require(channelReceiveSequenceMap[channelId]<sequence, "can't retreat sequence");
channelReceiveSequenceMap[channelId] = sequence;
} else {
address handlerContract;
assembly {
handlerContract := mload(add(localValue, 20))
}
require(isContract(handlerContract), "address is not a contract");
channelHandlerContractMap[channelId]=handlerContract;
registeredContractMap[handlerContract] = true;
emit addChannel(channelId, handlerContract);
uint8 channelId = uint8(localKey[0]);
bool fromSystem = uint8(localKey[1]) == 0x00;

address handlerContract;
assembly {
handlerContract := mload(add(localValue, 20))
}
require(isContract(handlerContract), "address is not a contract");
channelHandlerContractMap[channelId]=handlerContract;
registeredContractMap[handlerContract] = true;
isRelayRewardFromSystemReward[channelId] = fromSystem;
emit addChannel(channelId, handlerContract);
emit paramChange(key, value);
}
}
45 changes: 18 additions & 27 deletions contracts/CrossChain.template
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ contract CrossChain is System, ICrossChain, IParamSubscriber{
uint8 constant public ACK_PACKAGE = 0x01;
uint8 constant public FAIL_ACK_PACKAGE = 0x02;

uint16 constant bscChainID = 0x{{bscChainId}};
uint256 constant crossChainKeyPrefix = 0x0000000000000000000000000000000000000000000000000000000001{{bscChainId}}00; // last 6 bytes

mapping(uint8 => address) public channelHandlerContractMap;
Expand Down Expand Up @@ -103,6 +102,10 @@ contract CrossChain is System, ICrossChain, IParamSubscriber{
isRelayRewardFromSystemReward[GOV_CHANNELID] = true;
registeredContractMap[GOV_HUB_ADDR] = true;

channelHandlerContractMap[SLASH_CHANNELID] = SLASH_CONTRACT_ADDR;
isRelayRewardFromSystemReward[SLASH_CHANNELID] = true;
registeredContractMap[SLASH_CONTRACT_ADDR] = true;

alreadyInit=true;
}

Expand Down Expand Up @@ -195,7 +198,7 @@ function encodePayload(uint8 packageType, uint256 syncRelayFee, uint256 ackRelay
if (packageType == SYNC_PACKAGE) {
IRelayerIncentivize(INCENTIVIZE_ADDR).addReward(headerRelayer, msg.sender, syncRelayFee, isRelayRewardFromSystemReward[channelIdLocal]);
address handlerContract = channelHandlerContractMap[channelIdLocal];
try IApplication(handlerContract).handleSyncPackage(channelIdLocal, msgBytes) returns (bytes memory responsePayload) {
try IApplication(handlerContract).handleSynPackage(channelIdLocal, msgBytes) returns (bytes memory responsePayload) {
emit crossChainPackage(bscChainID, channelSendSequenceMap[channelIdLocal], channelIdLocal, encodePayload(ACK_PACKAGE, 0, ackRelayFee, responsePayload));
} catch Error(string memory reason) {
emit crossChainPackage(bscChainID, channelSendSequenceMap[channelIdLocal], channelIdLocal, encodePayload(FAIL_ACK_PACKAGE, 0, ackRelayFee, msgBytes));
Expand Down Expand Up @@ -237,35 +240,23 @@ function encodePayload(uint8 packageType, uint256 syncRelayFee, uint256 ackRelay
function updateParam(string calldata key, bytes calldata value) onlyGov external override {
bytes memory localKey = bytes(key);
bytes memory localValue = value;
require(localKey.length == 1, "expected key length is 1");
// length is 8, used to skip receive sequence
// first byte is channel Id, second byte is relayRewardFromSystemReward
require(localKey.length == 2, "expected key length is 2");
// length is 20, used to add or delete channel
require(localValue.length == 8 || localValue.length == 20, "expected value length is 8 or 20");
require(localValue.length == 20, "expected value length is 20");

uint256 bytes32Key;
assembly {
bytes32Key := mload(add(localKey, 1))
}
uint8 channelId = uint8(bytes32Key);

if (localValue.length == 8) {
uint64 sequence;
assembly {
sequence := mload(add(localValue, 8))
}
require(channelReceiveSequenceMap[channelId]<sequence, "can't retreat sequence");
channelReceiveSequenceMap[channelId] = sequence;
} else {
address handlerContract;
assembly {
handlerContract := mload(add(localValue, 20))
}
require(isContract(handlerContract), "address is not a contract");
channelHandlerContractMap[channelId]=handlerContract;
registeredContractMap[handlerContract] = true;
emit addChannel(channelId, handlerContract);
uint8 channelId = uint8(localKey[0]);
bool fromSystem = uint8(localKey[1]) == 0x00;

address handlerContract;
assembly {
handlerContract := mload(add(localValue, 20))
}
require(isContract(handlerContract), "address is not a contract");
channelHandlerContractMap[channelId]=handlerContract;
registeredContractMap[handlerContract] = true;
isRelayRewardFromSystemReward[channelId] = fromSystem;
emit addChannel(channelId, handlerContract);
emit paramChange(key, value);
}
}
115 changes: 55 additions & 60 deletions contracts/GovHub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,83 @@ import "./Seriality/Memory.sol";
import "./Seriality/BytesLib.sol";
import "./interface/IParamSubscriber.sol";
import "./interface/IApplication.sol";
import "./rlp/RLPDecode.sol";
import "./rlp/CmnPkg.sol";


contract GovHub is System, IApplication{
using RLPDecode for *;

uint8 public constant PARAM_UPDATE_MESSAGE_TYPE = 0;

uint32 public constant CODE_OK = 0;
uint32 public constant ERROR_TARGET_NOT_CONTRACT = 101;
uint32 public constant ERROR_TARGET_CONTRACT_FAIL = 102;

event failReasonWithStr(string message);
event failReasonWithBytes(bytes message);
event paramChange(string key, bytes value);

function init() external onlyNotInit{
alreadyInit = true;
struct ParamChangePackage {
string key;
bytes value;
address target;
}

function handleSyncPackage(uint8 channelId, bytes calldata msgBytes) onlyInit onlyCrossChainContract external override returns(bytes memory responsePayload){
uint8 msgType = getMsgType(msgBytes);
if(msgType == PARAM_UPDATE_MESSAGE_TYPE){
notifyUpdates(msgBytes);
}else{
emit failReasonWithStr("unknown message type");
}
return new bytes(0);
function handleSynPackage(uint8, bytes calldata msgBytes) onlyCrossChainContract external override returns(bytes memory responsePayload){
(ParamChangePackage memory proposal, bool success) = decodeSynPackage(msgBytes);
require(success, "fail to parse cross chain package");
uint32 resCode = notifyUpdates(proposal);
return CmnPkg.encodeCommonAckPackage(resCode);
}

function handleAckPackage(uint8 channelId, bytes calldata msgBytes) external override {
return;
// should not happen
function handleAckPackage(uint8, bytes calldata) external override {
require(false, "receive unexpected ack package");
}

function handleFailAckPackage(uint8 channelId, bytes calldata msgBytes) external override {
return;
// should not happen
function handleFailAckPackage(uint8, bytes calldata) external override {
require(false, "receive unexpected fail ack package");
}

//| Proposal type | key length | bytes of key | value length | value | target addr |
//| 1 byte | 1 byte | N bytes | 1 byte | M bytes| 20 byte |
function notifyUpdates(ParamChangePackage memory proposal) internal returns(uint32) {

function notifyUpdates(bytes memory proposalBytes) internal {
uint msgLength = proposalBytes.length;
// the minimum length is 25
if(msgLength <25){
emit failReasonWithStr("msg length less than 25");
return;
}
uint8 keyLength = BytesToTypes.bytesToUint8(2, proposalBytes);
if(keyLength == 0||msgLength<24+uint16(keyLength)){
emit failReasonWithStr("keyLength mismatch");
return;
if (!isContract(proposal.target)){
emit failReasonWithStr("the target is not a contract");
return ERROR_TARGET_NOT_CONTRACT;
}
string memory key = string(BytesLib.slice(proposalBytes, 2, keyLength));
uint8 valueLength = BytesToTypes.bytesToUint8(3+uint16(keyLength), proposalBytes);
if(valueLength == 0||msgLength!=23+uint16(keyLength)+uint16(valueLength)){
emit failReasonWithStr("valueLength mismatch");
return;
}
bytes memory value = BytesLib.slice(proposalBytes, 3+uint16(keyLength), uint16(valueLength));
address target = BytesToTypes.bytesToAddress(msgLength, proposalBytes);
if (target == address(this)){
updateParam(key, value);
}else{
if (!isContract(target)){
emit failReasonWithStr("the target is not a contract");
return;
}
try IParamSubscriber(target).updateParam(key, value){
}catch Error(string memory reason) {
emit failReasonWithStr(reason);
} catch (bytes memory lowLevelData) {
emit failReasonWithBytes(lowLevelData);
}
try IParamSubscriber(proposal.target).updateParam(proposal.key, proposal.value){
}catch Error(string memory reason) {
emit failReasonWithStr(reason);
return ERROR_TARGET_CONTRACT_FAIL;
} catch (bytes memory lowLevelData) {
emit failReasonWithBytes(lowLevelData);
return ERROR_TARGET_CONTRACT_FAIL;
}
return;
return CODE_OK;
}

function getMsgType(bytes memory msgBytes) internal pure returns(uint8){
uint8 msgType = 0xff;
assembly {
msgType := mload(add(msgBytes, 1))
}
return msgType;
}

/*********************** Param update ********************************/
function updateParam(string memory key, bytes memory value) internal{
//rlp encode & decode function
function decodeSynPackage(bytes memory msgBytes) internal pure returns (ParamChangePackage memory, bool) {
ParamChangePackage memory pkg;

RLPDecode.Iterator memory iter = msgBytes.toRLPItem().iterator();
bool success = false;
uint256 idx=0;
while(iter.hasNext()) {
if ( idx == 0 ) {
pkg.key = string(iter.next().toBytes());
}else if (idx == 1) {
pkg.value = iter.next().toBytes();
}else if (idx == 2){
pkg.target = iter.next().toAddress();
success = true;
} else {
break;
}
idx++;
}
return (pkg, success);
}
}
}
92 changes: 0 additions & 92 deletions contracts/GovHub.template

This file was deleted.

Loading