Simplier approach for attempts tracking in signer

This commit is contained in:
Kirill Fedoseev 2019-11-26 16:53:35 +03:00
parent 751c52eac2
commit 2d444a8cd2
7 changed files with 53 additions and 34 deletions

View File

@ -1,13 +1,24 @@
pragma solidity ^0.5.0;
contract SignupStorage {
mapping(bytes32 => uint16) public signupsCount;
mapping(bytes32 => mapping(address => uint16)) public signups;
struct SignupsCounter {
uint16 count;
mapping(address => uint16) id;
}
mapping(bytes32 => SignupsCounter) public signups;
function signup(bytes32 hash) public {
require(signups[hash][msg.sender] == 0, "Already signuped");
require(signups[hash].id[msg.sender] == 0, "Already signuped");
signups[hash][msg.sender] = ++signupsCount[hash];
signups[hash].id[msg.sender] = ++signups[hash].count;
}
function isSignuped(bytes32 hash) public view returns (bool) {
return isSignuped(hash, msg.sender);
}
function isSignuped(bytes32 hash, address validator) public view returns (bool) {
return signups[hash].id[validator] > 0;
}
function getSignupNumber(
@ -15,12 +26,12 @@ contract SignupStorage {
address[] memory validators,
address validator
) view public returns (uint16) {
if (signups[hash][validator] == 0)
if (signups[hash].id[validator] == 0)
return 0;
uint16 id = 1;
for (uint i = 0; i < validators.length; i++) {
uint16 vid = signups[hash][validators[i]];
if (vid > 0 && vid < signups[hash][validator])
uint16 vid = signups[hash].id[validators[i]];
if (vid > 0 && vid < signups[hash].id[validator])
id++;
}
return id;

View File

@ -24,6 +24,7 @@ const sharedDbAbi = [
'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 (uint16)',
'function isSignuped(bytes32 hash) view returns (bool)',
'function setData(bytes32 hash, bytes32 key, bytes data)',
'function signup(bytes32 hash)',
'function addSignature(bytes message, bytes rsv)',

View File

@ -172,7 +172,24 @@ async function signupKeygen(req, res) {
async function signupSign(req, res) {
logger.debug('SignupSign call')
const hash = ethers.utils.id(req.body.third)
const msgHash = req.body.third
logger.debug('Checking previous attempts')
let attempt = 1
let uuid
let hash
while (true) {
uuid = `${msgHash}_${attempt}`
hash = ethers.utils.id(uuid)
const data = await sharedDb.isSignuped(hash)
if (!data) {
break
}
logger.trace(`Attempt ${attempt} is already used`)
attempt += 1
}
logger.debug(`Using attempt ${attempt}`)
const query = sharedDb.interface.functions.signup.encode([hash])
const { txHash } = await sideSendQuery(query)
const receipt = await waitForReceipt(SIDE_RPC_URL, txHash)

View File

@ -27,7 +27,6 @@ const SIGN_OK = 0
const SIGN_NONCE_INTERRUPT = 1
const SIGN_FAILED = 2
let nextAttempt = null
let cancelled
let ready = false
let exchangeQueue
@ -58,13 +57,10 @@ function killSigner() {
}
function restart(req, res) {
if (/^[0-9]+$/.test(req.params.attempt)) {
logger.info(`Manual cancelling current sign attempt, starting ${req.params.attempt} attempt`)
nextAttempt = parseInt(req.params.attempt, 10)
killSigner()
cancelled = true
res.send('Done')
}
logger.info('Manual cancelling current sign attempt')
killSigner()
cancelled = true
res.send('Done')
}
async function confirmFundsTransfer(epoch) {
@ -225,15 +221,14 @@ function getAccountBalance(account, asset) {
return account.balances.find((token) => token.symbol === asset).free
}
async function buildTx(from, account, data, txAttempt) {
async function buildTx(from, account, data) {
const { closeEpoch, newEpoch, nonce } = data
const txOptions = {
from,
accountNumber: account.account_number,
sequence: nonce,
asset: FOREIGN_ASSET,
memo: `Attempt ${txAttempt}`
asset: FOREIGN_ASSET
}
let exchanges
@ -309,9 +304,8 @@ async function consumer(msg) {
}
writeParams(parties, threshold)
let attempt = 1
const { tx, exchanges } = await buildTx(from, account, data, attempt)
const { tx, exchanges } = await buildTx(from, account, data)
while (tx !== null) {
const signResult = await sign(keysFile, tx, publicKey, from)
@ -328,11 +322,7 @@ async function consumer(msg) {
break
}
// signer either failed, or timed out after parties signup
attempt = nextAttempt || attempt + 1
nextAttempt = null
logger.warn(`Sign failed, starting next attempt ${attempt}`)
tx.tx.memo = `Attempt ${attempt}`
logger.warn('Sign failed, starting next attempt')
await delay(1000)
}
logger.info('Acking message')
@ -354,7 +344,7 @@ async function main() {
signQueue.consume(consumer)
}
app.get('/restart/:attempt', restart)
app.get('/restart', restart)
app.get('/start', (req, res) => {
logger.info('Ready to start')
ready = true

View File

@ -11,7 +11,7 @@ const { validators } = require('../config')
const { HOME_BRIDGE_ADDRESS } = process.env
module.exports = (getUsers, newAttempt) => {
module.exports = (getUsers) => {
describe('exchange of tokens in eth => bnc direction with restart', function () {
let info
let users
@ -53,9 +53,9 @@ module.exports = (getUsers, newAttempt) => {
it('should restart signature generation and regenerate signature properly', async function () {
this.timeout(360000)
if (newValidatorNonces[0] > validatorNonces[0] + 2) {
await signerController1.restart(newAttempt)
await signerController1.restart()
} else {
await signerController2.restart(newAttempt)
await signerController2.restart()
}
await waitPromise(
() => getBncSequence(info.foreignBridgeAddress),

View File

@ -72,12 +72,12 @@ describe('bridge tests', function () {
testEthToBnc(() => users)
testBncToEth(() => users)
testEthToBncWithRestart(() => users, 99)
testEthToBncWithRestart(() => users)
testChangeThreshold(3)
testEthToBnc(() => users)
testBncToEth(() => users)
testEthToBncWithRestart(() => users, 2)
testEthToBncWithRestart(() => users)
testEthToBnc(() => users)
})

View File

@ -9,8 +9,8 @@ function createController(validatorId) {
})
return {
async restart(attempt) {
return (await sideClient.get(`/restart/${attempt}`)).data
async restart() {
await sideClient.get('/restart')
}
}
}