Used more convinient uintX types for numbers in contracts

This commit is contained in:
Kirill Fedoseev 2019-11-25 15:04:03 +03:00
parent 5efe01db65
commit 93563cfa8a
14 changed files with 187 additions and 229 deletions

View File

@ -3,26 +3,26 @@ pragma solidity ^0.5.0;
import './openzeppelin-solidity/contracts/token/ERC20/IERC20.sol';
contract BasicBridge {
uint constant UPPER_BOUND = uint(-1);
uint32 constant UPPER_BOUND = 0xffffffff;
event EpochEnd(uint indexed epoch);
event EpochClose(uint indexed epoch);
event EpochEnd(uint16 indexed epoch);
event EpochClose(uint16 indexed epoch);
event ForceSign();
event NewEpoch(uint indexed oldEpoch, uint indexed newEpoch);
event NewEpochCancelled(uint indexed epoch);
event NewFundsTransfer(uint indexed oldEpoch, uint indexed newEpoch);
event EpochStart(uint indexed epoch, uint x, uint y);
event NewEpoch(uint16 indexed oldEpoch, uint16 indexed newEpoch);
event NewEpochCancelled(uint16 indexed epoch);
event NewFundsTransfer(uint16 indexed oldEpoch, uint16 indexed newEpoch);
event EpochStart(uint16 indexed epoch, uint x, uint y);
struct State {
address[] validators;
uint threshold;
uint rangeSize;
uint startBlock;
uint endBlock;
uint nonce;
uint32 startBlock;
uint32 endBlock;
uint32 nonce;
uint16 threshold;
uint16 rangeSize;
bool closeEpoch;
uint x;
uint y;
bool closeEpoch;
}
enum Status {
@ -33,15 +33,15 @@ contract BasicBridge {
FUNDS_TRANSFER // funds transfer, cannot be cancelled
}
mapping(uint => State) states;
mapping(uint16 => State) public states;
Status public status;
uint public epoch;
uint public nextEpoch;
uint16 public epoch;
uint16 public nextEpoch;
uint minTxLimit;
uint maxTxLimit;
uint96 minTxLimit;
uint96 maxTxLimit;
IERC20 public tokenContract;
@ -55,21 +55,11 @@ contract BasicBridge {
_;
}
modifier readyOrClosing {
require(status == Status.READY || status == Status.CLOSING_EPOCH, "Not in ready or closing epoch state");
_;
}
modifier voting {
require(status == Status.VOTING, "Not in voting state");
_;
}
modifier readyOrVoting {
require(status == Status.READY || status == Status.VOTING, "Not in ready or voting state");
_;
}
modifier keygen {
require(status == Status.KEYGEN, "Not in keygen state");
_;
@ -80,60 +70,55 @@ contract BasicBridge {
_;
}
modifier currentValidator {
require(getPartyId() != 0, "Not a current validator");
_;
}
function getParties() view public returns (uint) {
function getParties() view public returns (uint16) {
return getParties(epoch);
}
function getNextParties() view public returns (uint) {
function getNextParties() view public returns (uint16) {
return getParties(nextEpoch);
}
function getParties(uint _epoch) view public returns (uint) {
return states[_epoch].validators.length;
function getParties(uint16 _epoch) view public returns (uint16) {
return uint16(states[_epoch].validators.length);
}
function getThreshold() view public returns (uint) {
function getThreshold() view public returns (uint16) {
return getThreshold(epoch);
}
function getNextThreshold() view public returns (uint) {
function getNextThreshold() view public returns (uint16) {
return getThreshold(nextEpoch);
}
function getThreshold(uint _epoch) view public returns (uint) {
function getThreshold(uint16 _epoch) view public returns (uint16) {
return states[_epoch].threshold;
}
function getStartBlock() view public returns (uint) {
function getStartBlock() view public returns (uint32) {
return getStartBlock(epoch);
}
function getStartBlock(uint _epoch) view public returns (uint) {
function getStartBlock(uint16 _epoch) view public returns (uint32) {
return states[_epoch].startBlock;
}
function getRangeSize() view public returns (uint) {
function getRangeSize() view public returns (uint16) {
return getRangeSize(epoch);
}
function getNextRangeSize() view public returns (uint) {
function getNextRangeSize() view public returns (uint16) {
return getRangeSize(nextEpoch);
}
function getRangeSize(uint _epoch) view public returns (uint) {
function getRangeSize(uint16 _epoch) view public returns (uint16) {
return states[_epoch].rangeSize;
}
function getNonce() view public returns (uint) {
function getNonce() view public returns (uint32) {
return getNonce(epoch);
}
function getNonce(uint _epoch) view public returns (uint) {
function getNonce(uint16 _epoch) view public returns (uint32) {
return states[_epoch].nonce;
}
@ -153,24 +138,24 @@ contract BasicBridge {
return getCloseEpoch(nextEpoch);
}
function getCloseEpoch(uint _epoch) view public returns (bool) {
function getCloseEpoch(uint16 _epoch) view public returns (bool) {
return states[_epoch].closeEpoch;
}
function getPartyId() view public returns (uint) {
function getPartyId() view public returns (uint16) {
address[] memory validators = getValidators();
for (uint i = 0; i < getParties(); i++) {
if (validators[i] == msg.sender)
return i + 1;
return uint16(i + 1);
}
return 0;
}
function getNextPartyId(address a) view public returns (uint) {
function getNextPartyId(address a) view public returns (uint16) {
address[] memory validators = getNextValidators();
for (uint i = 0; i < getNextParties(); i++) {
if (validators[i] == a)
return i + 1;
return uint16(i + 1);
}
return 0;
}
@ -183,7 +168,7 @@ contract BasicBridge {
return getValidators(nextEpoch);
}
function getValidators(uint _epoch) view public returns (address[] memory) {
function getValidators(uint16 _epoch) view public returns (address[] memory) {
return states[_epoch].validators;
}
}

View File

@ -4,16 +4,16 @@ import './openzeppelin-solidity/contracts/token/ERC20/IERC20.sol';
import "./MessageHandler.sol";
contract Bridge is MessageHandler {
event ExchangeRequest(uint value, uint nonce);
event ExchangeRequest(uint96 value, uint32 nonce);
mapping(bytes32 => bool) usedExchangeRanges;
constructor(
uint threshold,
uint16 threshold,
address[] memory validators,
address _tokenContract,
uint[2] memory limits,
uint rangeSize,
uint96[2] memory limits,
uint16 rangeSize,
bool closeEpoch
) public {
require(validators.length > 0);
@ -43,10 +43,10 @@ contract Bridge is MessageHandler {
emit NewEpoch(0, 1);
}
function exchange(uint value) public ready {
function exchange(uint96 value) public ready {
require(value >= minTxLimit && value >= 10 ** 10 && value <= maxTxLimit);
uint txRange = (block.number - getStartBlock()) / getRangeSize();
uint32 txRange = (uint32(block.number) - getStartBlock()) / uint32(getRangeSize());
if (!usedExchangeRanges[keccak256(abi.encodePacked(txRange, epoch))]) {
usedExchangeRanges[keccak256(abi.encodePacked(txRange, epoch))] = true;
states[epoch].nonce++;

View File

@ -24,7 +24,7 @@ contract Government is BasicBridge {
states[nextEpoch].nonce = UPPER_BOUND;
if (nextEpoch == 1) {
status = Status.READY;
states[nextEpoch].startBlock = block.number;
states[nextEpoch].startBlock = uint32(block.number);
epoch = nextEpoch;
emit EpochStart(epoch, x, y);
}
@ -38,7 +38,7 @@ contract Government is BasicBridge {
require(epoch > 0, "First epoch does not need funds transfer");
status = Status.READY;
states[nextEpoch].startBlock = block.number;
states[nextEpoch].startBlock = uint32(block.number);
epoch = nextEpoch;
emit EpochStart(epoch, getX(), getY());
}
@ -49,7 +49,7 @@ contract Government is BasicBridge {
}
function _startVoting() internal ready {
states[epoch].endBlock = block.number;
states[epoch].endBlock = uint32(block.number);
nextEpoch++;
states[nextEpoch].threshold = getThreshold();
states[nextEpoch].validators = getValidators();
@ -76,23 +76,24 @@ contract Government is BasicBridge {
function _removeValidator(address validator) internal voting {
require(getNextPartyId(validator) != 0, "Already not a validator");
for (uint i = 0; i < getNextParties() - 1; i++) {
uint16 lastPartyId = getNextParties() - 1;
for (uint i = 0; i < lastPartyId; i++) {
if (states[nextEpoch].validators[i] == validator) {
states[nextEpoch].validators[i] = getNextValidators()[getNextParties() - 1];
states[nextEpoch].validators[i] = getNextValidators()[lastPartyId];
break;
}
}
delete states[nextEpoch].validators[getNextParties() - 1];
delete states[nextEpoch].validators[lastPartyId];
states[nextEpoch].validators.length--;
}
function _changeThreshold(uint threshold) internal voting {
function _changeThreshold(uint16 threshold) internal voting {
require(threshold > 0, "Invalid threshold value");
states[nextEpoch].threshold = threshold;
}
function _changeRangeSize(uint rangeSize) internal voting {
function _changeRangeSize(uint16 rangeSize) internal voting {
require(rangeSize > 0, "Invalid range size");
states[nextEpoch].rangeSize = rangeSize;
@ -116,7 +117,7 @@ contract Government is BasicBridge {
emit NewEpochCancelled(nextEpoch);
}
function _transfer(address to, uint value) internal {
function _transfer(address to, uint96 value) internal {
if (tokenContract.balanceOf(address(this)) >= value) {
tokenContract.transfer(to, value);
} else {

View File

@ -3,37 +3,37 @@ pragma solidity ^0.5.0;
contract MessageDecoder {
// [0] - action type
// [1..32] - epoch
// [33..] - payload
function _decodeNumber(bytes memory message) pure internal returns (uint a) {
// [1,2] - epoch
// [3..] - payload
function _decodeUint16(bytes memory message) pure internal returns (uint16 a) {
assembly {
a := mload(add(message, 65))
a := mload(add(message, 5))
}
}
function _decodeBoolean(bytes memory message) pure internal returns (bool a) {
assembly {
a := and(mload(add(message, 34)), 1)
a := and(mload(add(message, 4)), 1)
}
}
function _decodeAddress(bytes memory message) pure internal returns (address a) {
assembly {
a := mload(add(message, 53))
a := mload(add(message, 23))
}
}
function _decodeKeygen(bytes memory message) pure internal returns (uint a, uint b) {
assembly {
a := mload(add(message, 65))
b := mload(add(message, 97))
a := mload(add(message, 35))
b := mload(add(message, 67))
}
}
function _decodeTransfer(bytes memory message) pure internal returns (address a, uint b) {
function _decodeTransfer(bytes memory message) pure internal returns (address a, uint96 b) {
assembly {
a := mload(add(message, 85))
b := mload(add(message, 117))
a := mload(add(message, 55))
b := mload(add(message, 67))
}
}
}

View File

@ -9,7 +9,7 @@ contract MessageHandler is Government, MessageDecoder {
mapping(bytes32 => bool) public handledMessages;
function applyMessage(bytes memory message, bytes memory signatures) public {
(bytes32 msgHash, uint msgEpoch) = checkSignedMessage(message, signatures);
(bytes32 msgHash, uint16 msgEpoch) = checkSignedMessage(message, signatures);
handledMessages[msgHash] = true;
Action msgAction = Action(uint8(message[0]));
@ -23,77 +23,78 @@ contract MessageHandler is Government, MessageDecoder {
}
if (msgAction == Action.CONFIRM_KEYGEN) {
require(message.length == 97, "Incorrect message length");
// [3,34] - x, [35,66] - y
require(message.length == 67, "Incorrect message length");
(uint x, uint y) = _decodeKeygen(message);
_confirmKeygen(x, y);
} else if (msgAction == Action.CONFIRM_FUNDS_TRANSFER) {
require(message.length == 33, "Incorrect message length");
require(message.length == 3, "Incorrect message length");
_confirmFundsTransfer();
} else if (msgAction == Action.CONFIRM_CLOSE_EPOCH) {
require(message.length == 33, "Incorrect message length");
require(message.length == 3, "Incorrect message length");
_confirmCloseEpoch();
} else if (msgAction == Action.VOTE_START_VOTING) {
require(message.length == 33, "Incorrect message length");
require(message.length == 3, "Incorrect message length");
_startVoting();
} else if (msgAction == Action.VOTE_ADD_VALIDATOR) {
require(message.length == 53, "Incorrect message length");
// [3,22] - address, [23,31] - extra data
require(message.length == 32, "Incorrect message length");
address validator = _decodeAddress(message);
_addValidator(validator);
} else if (msgAction == Action.VOTE_REMOVE_VALIDATOR) {
require(message.length == 53, "Incorrect message length");
// [3,22] - address, [23,31] - extra data
require(message.length == 32, "Incorrect message length");
address validator = _decodeAddress(message);
_removeValidator(validator);
} else if (msgAction == Action.VOTE_CHANGE_THRESHOLD) {
require(message.length == 65, "Incorrect message length");
uint threshold = _decodeNumber(message);
// [3,4] - threshold, [5,31] - extra data
require(message.length == 32, "Incorrect message length");
uint16 threshold = _decodeUint16(message);
_changeThreshold(threshold);
} else if (msgAction == Action.VOTE_CHANGE_RANGE_SIZE) {
require(message.length == 65, "Incorrect message length");
uint rangeSize = _decodeNumber(message);
// [3,4] - rangeSize, [5,31] - extra data
require(message.length == 32, "Incorrect message length");
uint16 rangeSize = _decodeUint16(message);
_changeRangeSize(rangeSize);
} else if (msgAction == Action.VOTE_CHANGE_CLOSE_EPOCH) {
require(message.length == 34, "Incorrect message length");
// [3] - closeEpoch, [4,31] - extra data
require(message.length == 32, "Incorrect message length");
bool closeEpoch = _decodeBoolean(message);
_changeCloseEpoch(closeEpoch);
} else if (msgAction == Action.VOTE_START_KEYGEN) {
require(message.length == 33, "Incorrect message length");
require(message.length == 3, "Incorrect message length");
_startKeygen();
} else if (msgAction == Action.VOTE_CANCEL_KEYGEN) {
require(message.length == 33, "Incorrect message length");
require(message.length == 3, "Incorrect message length");
_cancelKeygen();
} else if (msgAction == Action.TRANSFER) {
require(message.length == 117, "Incorrect message length");
(address to, uint value) = _decodeTransfer(message);
// [3,34] - txHash, [35,54] - address, [55,66] - value
require(message.length == 67, "Incorrect message length");
(address to, uint96 value) = _decodeTransfer(message);
_transfer(to, value);
} else {
revert("Unknown message action");
}
}
function checkSignedMessage(bytes memory message, bytes memory signatures) view public returns (bytes32, uint) {
function checkSignedMessage(bytes memory message, bytes memory signatures) view public returns (bytes32, uint16) {
require(signatures.length % SIGNATURE_SIZE == 0, "Incorrect signatures length");
bytes32 msgHash;
if (message.length == 33) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n33", message));
} else if (message.length == 34) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n34", message));
} else if (message.length == 53) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n53", message));
} else if (message.length == 65) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n65", message));
} else if (message.length == 97) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n97", message));
} else if (message.length == 117) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n117", message));
if (message.length == 3) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n3", message));
} else if (message.length == 32) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
} else if (message.length == 67) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n67", message));
} else {
revert("Incorrect message length");
}
require(!handledMessages[msgHash], "Tx was already handled");
uint msgEpoch;
uint16 msgEpoch;
assembly {
msgEpoch := mload(add(message, 33))
msgEpoch := mload(add(message, 3))
}
require(msgEpoch <= nextEpoch, "Invalid epoch number");

View File

@ -15,18 +15,12 @@ contract SignedMessageStorage {
require(rsv.length == 65, "Incorrect signature length");
bytes32 msgHash;
if (message.length == 33) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n33", message));
} else if (message.length == 34) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n34", message));
} else if (message.length == 53) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n53", message));
} else if (message.length == 65) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n65", message));
} else if (message.length == 97) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n97", message));
} else if (message.length == 117) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n117", message));
if (message.length == 3) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n3", message));
} else if (message.length == 32) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", message));
} else if (message.length == 67) {
msgHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n67", message));
} else {
revert("Incorrect message length");
}

View File

@ -1,8 +1,8 @@
pragma solidity ^0.5.0;
contract SignupStorage {
mapping(bytes32 => uint) public signupsCount;
mapping(bytes32 => mapping(address => uint)) public signups;
mapping(bytes32 => uint16) public signupsCount;
mapping(bytes32 => mapping(address => uint16)) public signups;
function signup(bytes32 hash) public {
require(signups[hash][msg.sender] == 0, "Already signuped");
@ -14,12 +14,12 @@ contract SignupStorage {
bytes32 hash,
address[] memory validators,
address validator
) view public returns (uint) {
) view public returns (uint16) {
if (signups[hash][validator] == 0)
return 0;
uint id = 1;
uint16 id = 1;
for (uint i = 0; i < validators.length; i++) {
uint vid = signups[hash][validators[i]];
uint16 vid = signups[hash][validators[i]];
if (vid > 0 && vid < signups[hash][validator])
id++;
}
@ -29,7 +29,7 @@ contract SignupStorage {
function getSignupAddress(
bytes32 hash,
address[] memory validators,
uint signupNumber
uint16 signupNumber
) view public returns (address) {
for (uint i = 0; i < validators.length; i++) {
if (getSignupNumber(hash, validators, validators[i]) == signupNumber) {

View File

@ -7,8 +7,8 @@ const SIDE_MAX_FETCH_RANGE_SIZE = parseInt(process.env.SIDE_MAX_FETCH_RANGE_SIZE
const bridgeAbi = [
'function applyMessage(bytes message, bytes signatures)',
'function getThreshold(uint epoch) view returns (uint)',
'function getValidators(uint epoch) view returns (address[])'
'function getThreshold(uint16 epoch) view returns (uint16)',
'function getValidators(uint16 epoch) view returns (address[])'
]
const sharedDbAbi = [
'event NewMessage(bytes32 msgHash)',
@ -31,7 +31,7 @@ async function delay(ms) {
async function handleNewMessage(event) {
const { msgHash } = event.values
const message = await sharedDb.signedMessages(msgHash)
const epoch = parseInt(message.slice(4, 68), 16)
const epoch = parseInt(message.slice(4, 8), 16)
const [threshold, validators] = await Promise.all([
bridge.getThreshold(epoch),
bridge.getValidators(epoch)
@ -49,7 +49,8 @@ async function handleNewMessage(event) {
gasLimit: 1000000,
nonce
})
await tx.wait()
const receipt = await tx.wait()
console.log(`Used gas: ${receipt.gasUsed.toNumber()}`)
nonce += 1
break
}
@ -89,7 +90,7 @@ async function loop() {
for (let i = 0; i < bridgeEvents.length; i += 1) {
const event = sharedDb.interface.parseLog(bridgeEvents[i])
console.log('Consumed event', event, bridgeEvents[i])
console.log('Consumed event', event)
await handleNewMessage(event)
}

View File

@ -15,17 +15,17 @@ const HOME_MAX_FETCH_RANGE_SIZE = parseInt(process.env.HOME_MAX_FETCH_RANGE_SIZE
const provider = new ethers.providers.JsonRpcProvider(HOME_RPC_URL)
const bridgeAbi = [
'event ExchangeRequest(uint value, uint nonce)',
'event EpochEnd(uint indexed epoch)',
'event NewEpoch(uint indexed oldEpoch, uint indexed newEpoch)',
'event NewEpochCancelled(uint indexed epoch)',
'event NewFundsTransfer(uint indexed oldEpoch, uint indexed newEpoch)',
'event EpochStart(uint indexed epoch, uint x, uint y)',
'event EpochClose(uint indexed epoch)',
'event ExchangeRequest(uint96 value, uint32 nonce)',
'event EpochEnd(uint16 indexed epoch)',
'event NewEpoch(uint16 indexed oldEpoch, uint16 indexed newEpoch)',
'event NewEpochCancelled(uint16 indexed epoch)',
'event NewFundsTransfer(uint16 indexed oldEpoch, uint16 indexed newEpoch)',
'event EpochStart(uint16 indexed epoch, uint256 x, uint256 y)',
'event EpochClose(uint16 indexed epoch)',
'event ForceSign()',
'function getThreshold(uint epoch) view returns (uint)',
'function getParties(uint epoch) view returns (uint)',
'function getRangeSize() view returns (uint)',
'function getThreshold(uint16 epoch) view returns (uint16)',
'function getParties(uint16 epoch) view returns (uint16)',
'function getRangeSize() view returns (uint16)',
'function getValidators() view returns (address[])'
]
const bridge = new ethers.Contract(HOME_BRIDGE_ADDRESS, bridgeAbi, provider)
@ -91,18 +91,18 @@ async function resetFutureMessages(queue) {
}
async function sendKeygen(event) {
const newEpoch = event.values.newEpoch.toNumber()
const { newEpoch } = event.values
keygenQueue.send({
epoch: newEpoch,
blockNumber,
threshold: (await bridge.getThreshold(newEpoch)).toNumber(),
parties: (await bridge.getParties(newEpoch)).toNumber()
threshold: await bridge.getThreshold(newEpoch),
parties: await bridge.getParties(newEpoch)
})
logger.debug('Sent keygen start event')
}
function sendKeygenCancellation(event) {
const eventEpoch = event.values.epoch.toNumber()
const eventEpoch = event.values.epoch
cancelKeygenQueue.send({
epoch: eventEpoch,
blockNumber
@ -111,15 +111,14 @@ function sendKeygenCancellation(event) {
}
async function sendSignFundsTransfer(event) {
const newEpoch = event.values.newEpoch.toNumber()
const oldEpoch = event.values.oldEpoch.toNumber()
const { newEpoch, oldEpoch } = event.values
signQueue.send({
epoch: oldEpoch,
blockNumber,
newEpoch,
nonce: foreignNonce[oldEpoch],
threshold: (await bridge.getThreshold(oldEpoch)).toNumber(),
parties: (await bridge.getParties(oldEpoch)).toNumber()
threshold: await bridge.getThreshold(oldEpoch),
parties: await bridge.getParties(oldEpoch)
})
logger.debug('Sent sign funds transfer event')
foreignNonce[oldEpoch] += 1
@ -150,7 +149,7 @@ async function sendSign(event, transactionHash) {
y: publicKey.substr(68, 64)
}),
value: (new BN(event.values.value)).dividedBy(10 ** 18).toFixed(8, 3),
nonce: event.values.nonce.toNumber()
nonce: event.values.nonce
}
exchangeQueue.send(msgToQueue)
@ -166,18 +165,18 @@ async function sendStartSign() {
epoch,
blockNumber,
nonce: foreignNonce[epoch],
threshold: (await bridge.getThreshold(epoch)).toNumber(),
parties: (await bridge.getParties(epoch)).toNumber()
threshold: await bridge.getThreshold(epoch),
parties: await bridge.getParties(epoch)
})
foreignNonce[epoch] += 1
redisTx.incr(`foreignNonce${epoch}`)
}
async function processEpochStart(event) {
epoch = event.values.epoch.toNumber()
epoch = event.values.epoch
epochStart = blockNumber
logger.info(`Epoch ${epoch} started`)
rangeSize = (await bridge.getRangeSize()).toNumber()
rangeSize = await bridge.getRangeSize()
isCurrentValidator = (await bridge.getValidators()).includes(validatorAddress)
if (isCurrentValidator) {
logger.info(`${validatorAddress} is a current validator`)
@ -194,8 +193,8 @@ async function sendEpochClose() {
closeEpoch: epoch,
blockNumber,
nonce: foreignNonce[epoch],
threshold: (await bridge.getThreshold(epoch)).toNumber(),
parties: (await bridge.getParties(epoch)).toNumber()
threshold: await bridge.getThreshold(epoch),
parties: await bridge.getParties(epoch)
})
foreignNonce[epoch] += 1
redisTx.incr(`foreignNonce${epoch}`)
@ -220,7 +219,7 @@ async function initialize() {
topics: bridge.filters.EpochStart().topics
})).map((log) => bridge.interface.parseLog(log))
epoch = events.length ? events[events.length - 1].values.epoch.toNumber() : 0
epoch = events.length ? events[events.length - 1].values.epoch : 0
logger.info(`Current epoch ${epoch}`)
epochStart = events.length ? events[events.length - 1].blockNumber : 1
const saved = (parseInt(await redis.get('homeBlock'), 10) + 1) || parseInt(HOME_START_BLOCK, 10)
@ -237,7 +236,7 @@ async function initialize() {
blockNumber = saved
foreignNonce[epoch] = parseInt(await redis.get(`foreignNonce${epoch}`), 10) || 0
}
rangeSize = (await bridge.getRangeSize()).toNumber()
rangeSize = await bridge.getRangeSize()
logger.debug(`Range size ${rangeSize}`)
logger.debug('Checking if current validator')
isCurrentValidator = (await bridge.getValidators()).includes(validatorAddress)

View File

@ -2,38 +2,28 @@ const tokenAbi = [
'function balanceOf(address account) view returns (uint256)'
]
const bridgeAbi = [
'function getX() view returns (uint)',
'function getY() view returns (uint)',
'function epoch() view returns (uint)',
'function getRangeSize() view returns (uint)',
'function getNextRangeSize() view returns (uint)',
'function getStartBlock() view returns (uint)',
'function getNonce() view returns (uint)',
'function nextEpoch() view returns (uint)',
'function getThreshold() view returns (uint)',
'function getNextThreshold() view returns (uint)',
'function getX() view returns (uint256)',
'function getY() view returns (uint256)',
'function epoch() view returns (uint16)',
'function getRangeSize() view returns (uint16)',
'function getNextRangeSize() view returns (uint16)',
'function getStartBlock() view returns (uint32)',
'function getNonce() view returns (uint16)',
'function nextEpoch() view returns (uint16)',
'function getThreshold() view returns (uint16)',
'function getNextThreshold() view returns (uint16)',
'function getValidators() view returns (address[])',
'function getNextValidators() view returns (address[])',
'function getCloseEpoch() view returns (bool)',
'function getNextCloseEpoch() view returns (bool)',
'function status() view returns (uint)',
'function votesCount(bytes32) view returns (uint)',
'function getNextPartyId(address a) view returns (uint)',
'function confirmKeygen(uint x, uint y)',
'function confirmFundsTransfer()',
'function confirmCloseEpoch()',
'function startVoting()',
'function voteStartKeygen()',
'function voteCancelKeygen()',
'function voteAddValidator(address validator)',
'function voteRemoveValidator(address validator)',
'function voteChangeThreshold(uint threshold)',
'function voteChangeCloseEpoch(bool closeEpoch)'
'function status() view returns (uint8)',
'function votesCount(bytes32) view returns (uint16)',
'function getNextPartyId(address a) view returns (uint16)'
]
const sharedDbAbi = [
'function getSignupAddress(bytes32 hash, address[] validators, uint signupNumber) view returns (address)',
'function getSignupAddress(bytes32 hash, address[] validators, uint16 signupNumber) view returns (address)',
'function getData(address from, bytes32 hash, bytes32 key) view returns (bytes)',
'function getSignupNumber(bytes32 hash, address[] validators, address validator) view returns (uint)',
'function getSignupNumber(bytes32 hash, address[] validators, address validator) view returns (uint16)',
'function setData(bytes32 hash, bytes32 key, bytes data)',
'function signup(bytes32 hash)',
'function addSignature(bytes message, bytes rsv)',

View File

@ -6,7 +6,7 @@ const ethers = require('ethers')
const { tokenAbi, bridgeAbi, sharedDbAbi } = require('./contractsAbi')
const {
Ok, Err, decodeStatus, boundX
Ok, Err, decodeStatus
} = require('./utils')
const encode = require('./encode')
const decode = require('./decode')
@ -128,8 +128,8 @@ async function set(req, res) {
async function signupKeygen(req, res) {
logger.debug('SignupKeygen call')
const epoch = (await bridge.nextEpoch()).toNumber()
const partyId = (await bridge.getNextPartyId(validatorAddress)).toNumber()
const epoch = await bridge.nextEpoch()
const partyId = await bridge.getNextPartyId(validatorAddress)
if (partyId === 0) {
res.send(Err({ message: 'Not a validator' }))
@ -161,7 +161,7 @@ async function signupSign(req, res) {
}
const validators = await bridge.getValidators()
const id = (await sharedDb.getSignupNumber(hash, validators, validatorAddress)).toNumber()
const id = await sharedDb.getSignupNumber(hash, validators, validatorAddress)
res.send(Ok({
uuid: hash,
@ -176,9 +176,9 @@ function encodeParam(param) {
if (param.startsWith('0x')) {
return Buffer.from(param.slice(2), 'hex')
}
return Buffer.from(padZeros(param, 64), 'hex')
return Buffer.from(param, 'hex')
case 'number':
return Buffer.from(padZeros(new BN(param).toString(16), 64), 'hex')
return Buffer.from(padZeros(param.toString(16), 4), 'hex')
case 'boolean':
return Buffer.from([param ? 1 : 0])
default:
@ -204,7 +204,7 @@ async function processMessage(message) {
async function confirmKeygen(req, res) {
logger.debug('Confirm keygen call')
const { x, y, epoch } = req.body
const message = buildMessage(Action.CONFIRM_KEYGEN, epoch, x, y)
const message = buildMessage(Action.CONFIRM_KEYGEN, epoch, padZeros(x, 64), padZeros(y, 64))
await processMessage(message)
res.send()
logger.debug('Confirm keygen end')
@ -230,7 +230,7 @@ async function confirmCloseEpoch(req, res) {
async function voteStartVoting(req, res) {
logger.info('Voting for starting new epoch voting process')
const epoch = boundX(await bridge.epoch())
const epoch = await bridge.epoch()
const message = buildMessage(Action.VOTE_START_VOTING, epoch)
await processMessage(message)
res.send('Voted\n')
@ -239,7 +239,7 @@ async function voteStartVoting(req, res) {
async function voteStartKeygen(req, res) {
logger.info('Voting for starting new epoch keygen')
const epoch = boundX(await bridge.epoch())
const epoch = await bridge.epoch()
const message = buildMessage(Action.VOTE_START_KEYGEN, epoch)
await processMessage(message)
res.send('Voted\n')
@ -248,7 +248,7 @@ async function voteStartKeygen(req, res) {
async function voteCancelKeygen(req, res) {
logger.info('Voting for cancelling new epoch keygen')
const epoch = boundX(await bridge.nextEpoch())
const epoch = await bridge.nextEpoch()
const message = buildMessage(Action.VOTE_CANCEL_KEYGEN, epoch)
await processMessage(message)
res.send('Voted\n')
@ -258,8 +258,8 @@ async function voteCancelKeygen(req, res) {
async function voteAddValidator(req, res) {
if (ethers.utils.isHexString(req.params.validator, 20)) {
logger.info('Voting for adding new validator')
const epoch = boundX(await bridge.epoch())
const message = buildMessage(Action.VOTE_ADD_VALIDATOR, epoch, req.params.validator)
const epoch = await bridge.epoch()
const message = buildMessage(Action.VOTE_ADD_VALIDATOR, epoch, req.params.validator, padZeros('', 18))
await processMessage(message)
res.send('Voted\n')
logger.info('Voted successfully')
@ -269,12 +269,8 @@ async function voteAddValidator(req, res) {
async function voteChangeThreshold(req, res) {
if (/^[0-9]+$/.test(req.params.threshold)) {
logger.info('Voting for changing threshold')
const epoch = boundX(await bridge.epoch())
const message = buildMessage(
Action.VOTE_CHANGE_THRESHOLD,
epoch,
parseInt(req.params.threshold, 10)
)
const epoch = await bridge.epoch()
const message = buildMessage(Action.VOTE_CHANGE_THRESHOLD, epoch, parseInt(req.params.threshold, 10), padZeros('', 54))
await processMessage(message)
res.send('Voted\n')
logger.info('Voted successfully')
@ -284,8 +280,8 @@ async function voteChangeThreshold(req, res) {
async function voteChangeCloseEpoch(req, res) {
if (req.params.closeEpoch === 'true' || req.params.closeEpoch === 'false') {
logger.info('Voting for changing close epoch')
const epoch = boundX(await bridge.epoch())
const message = buildMessage(Action.VOTE_CHANGE_CLOSE_EPOCH, epoch, req.params.closeEpoch === 'true')
const epoch = await bridge.epoch()
const message = buildMessage(Action.VOTE_CHANGE_CLOSE_EPOCH, epoch, req.params.closeEpoch === 'true', padZeros('', 56))
await processMessage(message)
res.send('Voted\n')
logger.info('Voted successfully')
@ -295,8 +291,8 @@ async function voteChangeCloseEpoch(req, res) {
async function voteRemoveValidator(req, res) {
if (ethers.utils.isHexString(req.params.validator, 20)) {
logger.info('Voting for removing validator')
const epoch = boundX(await bridge.epoch())
const message = buildMessage(Action.VOTE_REMOVE_VALIDATOR, epoch, req.params.validator)
const epoch = await bridge.epoch()
const message = buildMessage(Action.VOTE_REMOVE_VALIDATOR, epoch, req.params.validator, padZeros('', 18))
await processMessage(message)
res.send('Voted\n')
logger.info('Voted successfully')
@ -310,7 +306,7 @@ async function transfer(req, res) {
} = req.body
if (ethers.utils.isHexString(to, 20)) {
logger.info(`Calling transfer to ${to}, 0x${value} tokens`)
const message = buildMessage(Action.TRANSFER, epoch, hash, to, value)
const message = buildMessage(Action.TRANSFER, epoch, hash, to, padZeros(value, 24))
logger.info(`Message for sign: ${message.toString('hex')}`)
await processMessage(message)
}
@ -339,19 +335,19 @@ async function info(req, res) {
] = await Promise.all([
bridge.getX().then((value) => new BN(value).toString(16)),
bridge.getY().then((value) => new BN(value).toString(16)),
bridge.epoch().then(boundX),
bridge.getRangeSize().then(boundX),
bridge.getNextRangeSize().then(boundX),
bridge.epoch(),
bridge.getRangeSize(),
bridge.getNextRangeSize(),
bridge.getCloseEpoch(),
bridge.getNextCloseEpoch(),
bridge.getStartBlock().then(boundX),
bridge.getNonce().then(boundX),
bridge.nextEpoch().then(boundX),
bridge.getThreshold().then(boundX),
bridge.getNextThreshold().then(boundX),
bridge.getStartBlock(),
bridge.getNonce(),
bridge.nextEpoch(),
bridge.getThreshold(),
bridge.getNextThreshold(),
bridge.getValidators(),
bridge.getNextValidators(),
bridge.status().then(boundX),
bridge.status(),
token.balanceOf(HOME_BRIDGE_ADDRESS)
.then((value) => parseFloat(new BN(value).dividedBy(10 ** 18).toFixed(8, 3)))
])

View File

@ -23,17 +23,8 @@ function decodeStatus(status) {
}
}
function boundX(x) {
try {
return x.toNumber()
} catch (e) {
return -1
}
}
module.exports = {
Ok,
Err,
decodeStatus,
boundX
decodeStatus
}

View File

@ -9,7 +9,7 @@ const tokenAbi = [
'function approve(address to, uint256 value)'
]
const bridgeAbi = [
'function exchange(uint value)'
'function exchange(uint96 value)'
]
const PRIVATE_KEY = process.env.PRIVATE_KEY || HOME_PRIVATE_KEY

View File

@ -9,7 +9,7 @@ const abiToken = [
'function allowance(address owner, address spender) view returns (uint)'
]
const abiBridge = [
'function exchange(uint value)'
'function exchange(uint96 value)'
]
const provider = new ethers.providers.JsonRpcProvider(HOME_RPC_URL)