Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 1x 1x 1x 1x 1x 7x 7x 7x 1x 6x 6x 5x 1x 1x 8x 8x 8x 8x 8x 8x 1x 1x 1x 7x 7x 7x 6x 6x 6x 6x 6x 2x 2x 4x 4x 4x 4x 4x 4x 4x 5x | /**
* Copyright (c) 2018-present, Leap DAO (leapdao.org)
*
* This source code is licensed under the Mozilla Public License Version 2.0
* found in the LICENSE file in the root directory of this source tree.
*/
const {
getSlotsByAddr,
sendTransaction,
getCurrentSlotId,
GENESIS,
buildCas,
} = require('../utils');
const { logPeriod } = require('../utils/debug');
const checkEnoughVotes = require('../period/utils/checkEnoughVotes');
const inFlight = {};
/* istanbul ignore next */
const logError = height => err => {
logPeriod('submitPeriod error: %s (height: %d)', err.message, height);
};
const mySlotToSubmitFor = (slots, height, mySlots) => {
const currentSlotId = getCurrentSlotId(slots, height);
logPeriod('mySlots', currentSlotId, mySlots);
return mySlots.find(slot => slot.id === currentSlotId);
};
const getPrevPeriodRoot = (period, bridgeState) => {
const { lastBlocksRoot, lastPeriodRoot } = bridgeState;
if (!lastBlocksRoot) return GENESIS; // not submissions yet = first period to be submitted
if (lastBlocksRoot === period.prevHash) return lastPeriodRoot; // found
return null; // not found
};
module.exports = async (period, slots, height, bridgeState) => {
const { lastBlocksRoot, lastPeriodRoot } = bridgeState;
const periodVotes = bridgeState.currentState.periodVotes || {};
const periodRoot = period.merkleRoot();
let submittedPeriod = { timestamp: '0' };
Iif (inFlight[periodRoot]) {
logPeriod('submittedPeriod in flight', periodRoot);
return submittedPeriod;
}
if (lastBlocksRoot === periodRoot) {
submittedPeriod = await bridgeState.bridgeContract.methods
.periods(lastPeriodRoot)
.call();
logPeriod('submittedPeriod', periodRoot, submittedPeriod);
return submittedPeriod;
}
const mySlots = getSlotsByAddr(slots, bridgeState.account.address);
const mySlotToSubmit = mySlotToSubmitFor(slots, height, mySlots);
if (mySlotToSubmit) {
logPeriod('submitPeriod. Slot %d', mySlotToSubmit.id);
// always try to use the last submitted one
const prevPeriodRoot =
getPrevPeriodRoot(period, bridgeState) || lastPeriodRoot;
Iif (!prevPeriodRoot) {
logPeriod(
'submitPeriod. Not previous period root found. Skipping submission'
);
return submittedPeriod;
}
const { result, votes, needed } = checkEnoughVotes(
periodRoot,
bridgeState.currentState
);
if (!result) {
logPeriod(
`submitPeriod. Not enough period votes collected: ${votes}/${needed}. Waiting..`
);
return submittedPeriod;
}
const cas = buildCas(periodVotes[periodRoot]);
inFlight[periodRoot] = true;
const tx = sendTransaction(
bridgeState.web3,
bridgeState.operatorContract.methods.submitPeriodWithCas(
mySlotToSubmit.id,
prevPeriodRoot,
periodRoot,
`0x${cas.toString(16)}`
),
bridgeState.operatorContract.options.address,
bridgeState.account
).catch((e) => {
logPeriod('submitPeriod error', e);
delete inFlight[periodRoot];
logError(height);
});
tx.then(receipt => {
logPeriod('submitPeriod tx', receipt);
delete inFlight[periodRoot];
Iif (receipt && receipt.status) {
bridgeState.submittedPeriods[periodRoot] = true;
}
});
}
return submittedPeriod;
};
|