rollup: use time rather than count for interval; add resetBatchWorker method
This commit is contained in:
parent
837b972149
commit
f7dcf0ec5e
|
@ -32,7 +32,8 @@ Our work contract normally triggeres a validation pool when the customer submits
|
|||
|
||||
The `Rollup` contract itself uses the `Availability` contract to assign a batch worker. This worker is responsible for making sure off-chain pools are conducted.
|
||||
|
||||
When ready, the worker submits the current batch on-chain by creating a batch post and a validation pool targeting the batch post.
|
||||
When ready, the worker submits the current batch on-chain by calling `DAO.addPost()` to create a batch post and then calling `Rollup.submitBatch()`, which initiates a validation pool targeting the batch post.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant client as Staking client
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const { rollup, wallet } = require('../../util/contracts');
|
||||
|
||||
let batchWorker;
|
||||
let batchStart;
|
||||
|
||||
const getCurrentBatchWorker = () => batchWorker;
|
||||
|
||||
|
@ -11,6 +12,7 @@ const initializeBatchWorker = async () => {
|
|||
|
||||
rollup.on('BatchWorkerAssigned', async (batchWorker_) => {
|
||||
batchWorker = batchWorker_;
|
||||
batchStart = new Date();
|
||||
console.log('Batch worker assigned:', batchWorker);
|
||||
if (batchWorker === await wallet.getAddress()) {
|
||||
console.log('This instance is the new batch worker');
|
||||
|
@ -22,8 +24,11 @@ const setBatchWorker = (batchWorker_) => {
|
|||
batchWorker = batchWorker_;
|
||||
};
|
||||
|
||||
const getBatchAge = (new Date() - batchStart) / 1000;
|
||||
|
||||
module.exports = {
|
||||
getCurrentBatchWorker,
|
||||
initializeBatchWorker,
|
||||
setBatchWorker,
|
||||
getBatchAge,
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const {
|
||||
ROLLUP_BATCH_SIZE,
|
||||
ROLLUP_AVAILABILITY_STAKE_DURATION,
|
||||
ROLLUP_INTERVAL,
|
||||
} = process.env;
|
||||
|
||||
module.exports = {
|
||||
rollupBatchSize: ROLLUP_BATCH_SIZE || 10,
|
||||
rollupInterval: ROLLUP_INTERVAL,
|
||||
availabilityStakeDuration: ROLLUP_AVAILABILITY_STAKE_DURATION || 600,
|
||||
};
|
||||
|
|
|
@ -2,9 +2,9 @@ const { sendMatrixEvent } = require('../../../matrix-bot');
|
|||
const { wallet } = require('../../../util/contracts');
|
||||
const { matrixPools } = require('../../../util/db');
|
||||
const { addBatchItem, getBatchItems } = require('../batch-items');
|
||||
const { getCurrentBatchWorker } = require('../batch-worker');
|
||||
const { getCurrentBatchWorker, getBatchAge } = require('../batch-worker');
|
||||
const computeMatrixPoolResult = require('./compute-result');
|
||||
const { rollupBatchSize } = require('../config');
|
||||
const { rollupInterval } = require('../config');
|
||||
const submitRollup = require('../submit-rollup');
|
||||
const { stakeRollupAvailability } = require('../utils');
|
||||
|
||||
|
@ -28,9 +28,10 @@ const evaluateMatrixPoolOutcome = async (postId) => {
|
|||
} else if (batchWorker === await wallet.getAddress()) {
|
||||
// If we are the batch worker, we should wait an appropriate amout of time /
|
||||
// number of matrix pools before submitting a batch.
|
||||
const batchAge = getBatchAge();
|
||||
const batchItems = getBatchItems();
|
||||
if (batchItems.length === rollupBatchSize) {
|
||||
console.log(`Batch size = ${batchItems.length}. Submitting batch.`);
|
||||
if (batchAge > rollupInterval && batchItems.length) {
|
||||
console.log(`Batch age = ${batchAge}, size = ${batchItems.length}. Submitting batch.`);
|
||||
submitBatch = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,4 +6,5 @@ MAINNET_PRIVATE_KEY=
|
|||
SEED_PHRASE=
|
||||
ETHERSCAN_API_KEY=
|
||||
WORK1_PRICE="0.001"
|
||||
ONBOARDING_PRICE="0.001"
|
||||
ONBOARDING_PRICE="0.001"
|
||||
ROLLUP_INTERVAL=120
|
|
@ -5,8 +5,6 @@ import "./core/DAO.sol";
|
|||
import "./Availability.sol";
|
||||
|
||||
contract Rollup is Availability {
|
||||
constructor(DAO dao) Availability(dao) {}
|
||||
|
||||
struct BatchItem {
|
||||
address sender;
|
||||
address worker;
|
||||
|
@ -19,10 +17,18 @@ contract Rollup is Availability {
|
|||
uint public itemCount;
|
||||
address public batchWorker;
|
||||
uint batchWorkerStakeIndex;
|
||||
uint public immutable batchInterval;
|
||||
uint public batchStart;
|
||||
uint lastWorkerReset;
|
||||
uint constant minResetInterval = 120;
|
||||
|
||||
event BatchItemAdded(string postId, address sender, uint fee);
|
||||
event BatchWorkerAssigned(address batchWorker);
|
||||
|
||||
constructor(DAO dao, uint batchInterval_) Availability(dao) {
|
||||
batchInterval = batchInterval_;
|
||||
}
|
||||
|
||||
/// Instead of initiating a validation pool, call this method to include
|
||||
/// the stakes and fee in the next batch validation pool
|
||||
function addItem(
|
||||
|
@ -106,9 +112,28 @@ contract Rollup is Availability {
|
|||
// Reset item count so we can start the next batch
|
||||
itemCount = 0;
|
||||
}
|
||||
// Select the next worker
|
||||
// Select the next batch worker
|
||||
batchWorkerStakeIndex = assignWork();
|
||||
batchWorker = stakes[batchWorkerStakeIndex].worker;
|
||||
batchStart = block.timestamp;
|
||||
emit BatchWorkerAssigned(batchWorker);
|
||||
}
|
||||
|
||||
/// If the batch worker fails to submit the batch, a new batch worker may be selected
|
||||
function resetBatchWorker() public {
|
||||
require(
|
||||
block.timestamp - batchStart > batchInterval,
|
||||
"Current batch interval has not yet elapsed"
|
||||
);
|
||||
require(itemCount > 0, "Current batch is empty");
|
||||
require(
|
||||
lastWorkerReset == 0 ||
|
||||
block.timestamp - lastWorkerReset >= minResetInterval,
|
||||
"Mininum reset interval has not elapsed since last batch worker reset"
|
||||
);
|
||||
// TODO: Should the current batch worker's availability stakes be forfeit?
|
||||
// Select a new batch worker
|
||||
batchWorkerStakeIndex = assignWork();
|
||||
batchWorker = stakes[batchWorkerStakeIndex].worker;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
require('dotenv').config();
|
||||
const deployDAOContract = require('./util/deploy-dao-contract');
|
||||
const deployWorkContract = require('./util/deploy-work-contract');
|
||||
const deployRollableWorkContract = require('./util/deploy-rollable-work-contract');
|
||||
const deployCoreContracts = require('./util/deploy-core-contracts');
|
||||
|
||||
const { ROLLUP_INTERVAL } = process.env;
|
||||
|
||||
async function main() {
|
||||
await deployCoreContracts();
|
||||
await deployDAOContract('Rollup');
|
||||
await deployDAOContract('Rollup', [ROLLUP_INTERVAL]);
|
||||
await deployDAOContract('Proposals');
|
||||
await deployWorkContract('Work1');
|
||||
await deployWorkContract('Onboarding');
|
||||
|
|
|
@ -6,8 +6,8 @@ require('dotenv').config();
|
|||
|
||||
const network = process.env.HARDHAT_NETWORK;
|
||||
|
||||
const deployDAOContract = async (name) => {
|
||||
await deployContract(name, [contractAddresses[network].DAO]);
|
||||
const deployDAOContract = async (name, args = []) => {
|
||||
await deployContract(name, [contractAddresses[network].DAO, ...args]);
|
||||
};
|
||||
|
||||
module.exports = deployDAOContract;
|
||||
|
|
Loading…
Reference in New Issue