Contract support of closing epoch process on binance side
This commit is contained in:
parent
1de3b2d75a
commit
38e96b5552
|
@ -15,3 +15,5 @@ MIN_TX_LIMIT=10000000000000000
|
||||||
MAX_TX_LIMIT=100000000000000000000
|
MAX_TX_LIMIT=100000000000000000000
|
||||||
|
|
||||||
BLOCKS_RANGE_SIZE=10
|
BLOCKS_RANGE_SIZE=10
|
||||||
|
|
||||||
|
CLOSE_EPOCH_FLAG=true
|
||||||
|
|
|
@ -16,3 +16,5 @@ MIN_TX_LIMIT=10000000000000000
|
||||||
MAX_TX_LIMIT=100000000000000000000
|
MAX_TX_LIMIT=100000000000000000000
|
||||||
|
|
||||||
BLOCKS_RANGE_SIZE=25
|
BLOCKS_RANGE_SIZE=25
|
||||||
|
|
||||||
|
CLOSE_EPOCH_FLAG=true
|
||||||
|
|
|
@ -5,6 +5,8 @@ import './openzeppelin-solidity/contracts/token/ERC20/IERC20.sol';
|
||||||
contract Bridge {
|
contract Bridge {
|
||||||
event ExchangeRequest(uint value, uint nonce);
|
event ExchangeRequest(uint value, uint nonce);
|
||||||
event EpochEnd(uint indexed epoch);
|
event EpochEnd(uint indexed epoch);
|
||||||
|
event EpochClose(uint indexed epoch);
|
||||||
|
event ForceSign();
|
||||||
event NewEpoch(uint indexed oldEpoch, uint indexed newEpoch);
|
event NewEpoch(uint indexed oldEpoch, uint indexed newEpoch);
|
||||||
event NewEpochCancelled(uint indexed epoch);
|
event NewEpochCancelled(uint indexed epoch);
|
||||||
event NewFundsTransfer(uint indexed oldEpoch, uint indexed newEpoch);
|
event NewFundsTransfer(uint indexed oldEpoch, uint indexed newEpoch);
|
||||||
|
@ -19,10 +21,12 @@ contract Bridge {
|
||||||
uint nonce;
|
uint nonce;
|
||||||
uint x;
|
uint x;
|
||||||
uint y;
|
uint y;
|
||||||
|
bool closeEpoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Status {
|
enum Status {
|
||||||
READY, // bridge is in ready to perform operations
|
READY, // bridge is in ready to perform operations
|
||||||
|
CLOSING_EPOCH, // generating transaction for blocking binance side of the bridge
|
||||||
VOTING, // voting for changing in next epoch, but still ready
|
VOTING, // voting for changing in next epoch, but still ready
|
||||||
KEYGEN, //keygen, can be cancelled
|
KEYGEN, //keygen, can be cancelled
|
||||||
FUNDS_TRANSFER // funds transfer, cannot be cancelled
|
FUNDS_TRANSFER // funds transfer, cannot be cancelled
|
||||||
|
@ -31,11 +35,13 @@ contract Bridge {
|
||||||
enum Vote {
|
enum Vote {
|
||||||
CONFIRM_KEYGEN,
|
CONFIRM_KEYGEN,
|
||||||
CONFIRM_FUNDS_TRANSFER,
|
CONFIRM_FUNDS_TRANSFER,
|
||||||
|
CONFIRM_CLOSE_EPOCH,
|
||||||
START_VOTING,
|
START_VOTING,
|
||||||
ADD_VALIDATOR,
|
ADD_VALIDATOR,
|
||||||
REMOVE_VALIDATOR,
|
REMOVE_VALIDATOR,
|
||||||
CHANGE_THRESHOLD,
|
CHANGE_THRESHOLD,
|
||||||
CHANGE_RANGE_SIZE,
|
CHANGE_RANGE_SIZE,
|
||||||
|
CHANGE_CLOSE_EPOCH,
|
||||||
START_KEYGEN,
|
START_KEYGEN,
|
||||||
CANCEL_KEYGEN,
|
CANCEL_KEYGEN,
|
||||||
TRANSFER
|
TRANSFER
|
||||||
|
@ -57,7 +63,7 @@ contract Bridge {
|
||||||
uint minTxLimit;
|
uint minTxLimit;
|
||||||
uint maxTxLimit;
|
uint maxTxLimit;
|
||||||
|
|
||||||
constructor(uint threshold, address[] memory validators, address _tokenContract, uint[2] memory limits, uint rangeSize) public {
|
constructor(uint threshold, address[] memory validators, address _tokenContract, uint[2] memory limits, uint rangeSize, bool closeEpoch) public {
|
||||||
require(validators.length > 0);
|
require(validators.length > 0);
|
||||||
require(threshold <= validators.length);
|
require(threshold <= validators.length);
|
||||||
|
|
||||||
|
@ -72,10 +78,11 @@ contract Bridge {
|
||||||
threshold : threshold,
|
threshold : threshold,
|
||||||
rangeSize : rangeSize,
|
rangeSize : rangeSize,
|
||||||
startBlock : 0,
|
startBlock : 0,
|
||||||
endBlock : uint(-1),
|
endBlock : uint(- 1),
|
||||||
nonce : uint(-1),
|
nonce : uint(- 1),
|
||||||
x : 0,
|
x : 0,
|
||||||
y : 0
|
y : 0,
|
||||||
|
closeEpoch : closeEpoch
|
||||||
});
|
});
|
||||||
|
|
||||||
minTxLimit = limits[0];
|
minTxLimit = limits[0];
|
||||||
|
@ -91,8 +98,13 @@ contract Bridge {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier readyOrVoting {
|
modifier closingEpoch {
|
||||||
require(status == Status.READY || status == Status.VOTING, "Not in ready or voting state");
|
require(status == Status.CLOSING_EPOCH, "Not in closing epoch state");
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier readyOrClosing {
|
||||||
|
require(status == Status.READY || status == Status.CLOSING_EPOCH, "Not in ready or closing epoch state");
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +113,11 @@ contract Bridge {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modifier readyOrVoting {
|
||||||
|
require(status == Status.READY || status == Status.VOTING, "Not in ready or voting state");
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
modifier keygen {
|
modifier keygen {
|
||||||
require(status == Status.KEYGEN, "Not in keygen state");
|
require(status == Status.KEYGEN, "Not in keygen state");
|
||||||
_;
|
_;
|
||||||
|
@ -129,7 +146,7 @@ contract Bridge {
|
||||||
emit ExchangeRequest(value, getNonce());
|
emit ExchangeRequest(value, getNonce());
|
||||||
}
|
}
|
||||||
|
|
||||||
function transfer(bytes32 hash, address to, uint value) public readyOrVoting currentValidator {
|
function transfer(bytes32 hash, address to, uint value) public readyOrClosing currentValidator {
|
||||||
if (tryVote(Vote.TRANSFER, hash, to, value)) {
|
if (tryVote(Vote.TRANSFER, hash, to, value)) {
|
||||||
tokenContract.transfer(to, value);
|
tokenContract.transfer(to, value);
|
||||||
}
|
}
|
||||||
|
@ -161,12 +178,19 @@ contract Bridge {
|
||||||
if (tryConfirm(Vote.CONFIRM_FUNDS_TRANSFER)) {
|
if (tryConfirm(Vote.CONFIRM_FUNDS_TRANSFER)) {
|
||||||
status = Status.READY;
|
status = Status.READY;
|
||||||
states[nextEpoch].startBlock = block.number;
|
states[nextEpoch].startBlock = block.number;
|
||||||
states[nextEpoch].nonce = uint(-1);
|
states[nextEpoch].nonce = uint(- 1);
|
||||||
epoch = nextEpoch;
|
epoch = nextEpoch;
|
||||||
emit EpochStart(epoch, getX(), getY());
|
emit EpochStart(epoch, getX(), getY());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function confirmCloseEpoch() public closingEpoch currentValidator {
|
||||||
|
if (tryConfirm(Vote.CONFIRM_CLOSE_EPOCH)) {
|
||||||
|
status = Status.VOTING;
|
||||||
|
emit EpochEnd(epoch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getParties() view public returns (uint) {
|
function getParties() view public returns (uint) {
|
||||||
return getParties(epoch);
|
return getParties(epoch);
|
||||||
}
|
}
|
||||||
|
@ -227,6 +251,18 @@ contract Bridge {
|
||||||
return states[epoch].y;
|
return states[epoch].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCloseEpoch() view public returns (bool) {
|
||||||
|
return getCloseEpoch(epoch);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNextCloseEpoch() view public returns (bool) {
|
||||||
|
return getCloseEpoch(nextEpoch);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCloseEpoch(uint _epoch) view public returns (bool) {
|
||||||
|
return states[_epoch].closeEpoch;
|
||||||
|
}
|
||||||
|
|
||||||
function getPartyId() view public returns (uint) {
|
function getPartyId() view public returns (uint) {
|
||||||
address[] memory validators = getValidators();
|
address[] memory validators = getValidators();
|
||||||
for (uint i = 0; i < getParties(); i++) {
|
for (uint i = 0; i < getParties(); i++) {
|
||||||
|
@ -256,15 +292,23 @@ contract Bridge {
|
||||||
function startVoting() public readyOrVoting currentValidator {
|
function startVoting() public readyOrVoting currentValidator {
|
||||||
if (tryVote(Vote.START_VOTING, epoch)) {
|
if (tryVote(Vote.START_VOTING, epoch)) {
|
||||||
nextEpoch++;
|
nextEpoch++;
|
||||||
status = Status.VOTING;
|
|
||||||
states[nextEpoch].endBlock = block.number;
|
states[nextEpoch].endBlock = block.number;
|
||||||
states[nextEpoch].threshold = getThreshold();
|
states[nextEpoch].threshold = getThreshold();
|
||||||
states[nextEpoch].validators = getValidators();
|
states[nextEpoch].validators = getValidators();
|
||||||
states[nextEpoch].rangeSize = getRangeSize();
|
states[nextEpoch].rangeSize = getRangeSize();
|
||||||
|
states[nextEpoch].closeEpoch = getCloseEpoch();
|
||||||
|
|
||||||
|
if (status == Status.READY && getCloseEpoch()) {
|
||||||
|
status = Status.CLOSING_EPOCH;
|
||||||
|
emit ForceSign();
|
||||||
|
emit EpochClose(epoch);
|
||||||
|
} else {
|
||||||
|
status = Status.VOTING;
|
||||||
|
emit ForceSign();
|
||||||
emit EpochEnd(epoch);
|
emit EpochEnd(epoch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function voteAddValidator(address validator) public voting currentValidator {
|
function voteAddValidator(address validator) public voting currentValidator {
|
||||||
require(getNextPartyId(validator) == 0, "Already a validator");
|
require(getNextPartyId(validator) == 0, "Already a validator");
|
||||||
|
@ -307,6 +351,12 @@ contract Bridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function voteChangeCloseEpoch(bool closeEpoch) public voting currentValidator {
|
||||||
|
if (tryVote(Vote.CHANGE_CLOSE_EPOCH, closeEpoch ? 1 : 0)) {
|
||||||
|
states[nextEpoch].closeEpoch = closeEpoch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function voteStartKeygen() public voting currentValidator {
|
function voteStartKeygen() public voting currentValidator {
|
||||||
require(getNextThreshold() <= getNextParties(), "Invalid threshold number");
|
require(getNextThreshold() <= getNextParties(), "Invalid threshold number");
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ const addresses = Object.entries(process.env)
|
||||||
.map(([, value]) => value)
|
.map(([, value]) => value)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
THRESHOLD, HOME_TOKEN_ADDRESS, MIN_TX_LIMIT, MAX_TX_LIMIT, BLOCKS_RANGE_SIZE
|
THRESHOLD, HOME_TOKEN_ADDRESS, MIN_TX_LIMIT, MAX_TX_LIMIT, BLOCKS_RANGE_SIZE, CLOSE_EPOCH_FLAG
|
||||||
} = process.env
|
} = process.env
|
||||||
|
|
||||||
module.exports = (deployer) => {
|
module.exports = (deployer) => {
|
||||||
|
@ -15,6 +15,7 @@ module.exports = (deployer) => {
|
||||||
addresses,
|
addresses,
|
||||||
HOME_TOKEN_ADDRESS,
|
HOME_TOKEN_ADDRESS,
|
||||||
[MIN_TX_LIMIT, MAX_TX_LIMIT],
|
[MIN_TX_LIMIT, MAX_TX_LIMIT],
|
||||||
BLOCKS_RANGE_SIZE
|
BLOCKS_RANGE_SIZE,
|
||||||
|
CLOSE_EPOCH_FLAG === 'true'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue