rollup is working
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 32s
Details
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 32s
Details
This commit is contained in:
parent
9c95e813a2
commit
f7afd0105f
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"localhost": {
|
||||
"DAO": "0xc7E04c11eD94E375857b885b3e6E1Db30C061348",
|
||||
"Work1": "0x1bEffEB10E9f5714a8e385FfcA84046688677eA8",
|
||||
"Onboarding": "0xFC40076c675693441C6e553FEdDD3A3348db81E4",
|
||||
"Proposals": "0xa1349A27D43d0F71CeDD75904ACc8f8CF8F81582",
|
||||
"Rollup": "0x1361c87D5972a71cBCA34f6EAD928358deaC750D",
|
||||
"Work2": "0x691Bcb6a8378Cec103BE58Dfa037DC57E6FFf4d1",
|
||||
"Reputation": "0xfC979dbae6Cd0f35CC240889663B523B35c5F101",
|
||||
"Forum": "0xaf247e316A081871e713F492279D2360bd162401",
|
||||
"Bench": "0xC8BCE8171e626d07E5095256F703B1df23a67362"
|
||||
"DAO": "0x1d63FDe5B461106729fE1e5e38A02fc68C518Af5",
|
||||
"Work1": "0xB8f0cd092979F273b752FDa060F82BF2745f192e",
|
||||
"Onboarding": "0x8F00038542C87A5eAf18d5938B7723bF2A04A4e4",
|
||||
"Proposals": "0x6c18eb38b7450F8DaE5A5928A40fcA3952493Ee4",
|
||||
"Rollup": "0x57BDFFf79108E5198dec6268A6BFFD8B62ECfA38",
|
||||
"Work2": "0x42b79f8d8408c36aD4347ab72f826684440a7a8F",
|
||||
"Reputation": "0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3",
|
||||
"Forum": "0x050C420Cc4995B41217Eba1B54B82Fd5687e9139",
|
||||
"Bench": "0xfe58B9EB03F75A603de1B286584f5E9532ab8fB5"
|
||||
},
|
||||
"sepolia": {
|
||||
"DAO": "0x8e5bd58B2ca8910C5F9be8de847d6883B15c60d2",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,7 @@ const {
|
|||
appState,
|
||||
proposalEventIds,
|
||||
} = require('../util/db');
|
||||
const { submitRollup, resetBatch } = require('./rollup');
|
||||
|
||||
const {
|
||||
BOT_INSTANCE_ID,
|
||||
|
@ -19,6 +20,8 @@ const handleCommand = async (client, roomId, event) => {
|
|||
const helloRegex = /^!hello\b/i;
|
||||
const targetRegex = /^!target (.*)\b/i;
|
||||
const proposalRegex = /\bprop(|osal) ([0-9]+)\b/i;
|
||||
const submitRollupRegex = /^!submitBatch\b/i;
|
||||
const resetBatchRegex = /^!resetBatch (.*)\b/i;
|
||||
|
||||
const { body } = event.content;
|
||||
|
||||
|
@ -51,6 +54,22 @@ const handleCommand = async (client, roomId, event) => {
|
|||
} catch (e) {
|
||||
// Not found
|
||||
}
|
||||
} else if (submitRollupRegex.test(body)) {
|
||||
console.log('!submitBatch');
|
||||
const { batchPostId, batchItems, authors } = await submitRollup();
|
||||
if (batchItems.length) {
|
||||
await client.replyText(roomId, event, `Submitted batch, post ${batchPostId} with ${batchItems.length} posts by ${authors.length} authors`);
|
||||
} else {
|
||||
await client.replyText(roomId, event, 'No matrix pools have finished since the last batch was submitted');
|
||||
}
|
||||
} else if (resetBatchRegex.test(body)) {
|
||||
const [, instanceId] = resetBatchRegex.exec(body);
|
||||
console.log(`!resetBatch roomId ${roomId} instanceId ${instanceId}`);
|
||||
if (instanceId === BOT_INSTANCE_ID) {
|
||||
console.log('!resetBatch');
|
||||
const batchItems = await resetBatch();
|
||||
await client.replyText(roomId, event, `Reset batch, now contains ${batchItems.length} items`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -17,15 +17,30 @@ const {
|
|||
ROLLUP_AVAILABILITY_STAKE_DURATION,
|
||||
} = process.env;
|
||||
|
||||
const rollupBatchSize = ROLLUP_BATCH_SIZE || 1;
|
||||
const rollupBatchSize = ROLLUP_BATCH_SIZE || 10;
|
||||
const availabilityStakeDuration = ROLLUP_AVAILABILITY_STAKE_DURATION || 600;
|
||||
|
||||
let batchWorker;
|
||||
let batchItems;
|
||||
|
||||
const resetBatch = async () => {
|
||||
batchItems = [];
|
||||
// Read from Rollup.items
|
||||
const itemCount = await rollup.itemCount();
|
||||
const promises = [];
|
||||
for (let i = 0; i < itemCount; i += 1) {
|
||||
promises.push(rollup.items(i));
|
||||
}
|
||||
batchItems = await Promise.all(promises);
|
||||
await applicationData.put('batchItems', batchItems);
|
||||
return batchItems;
|
||||
};
|
||||
|
||||
const stakeRollupAvailability = async () => {
|
||||
const currentRep = await dao.balanceOf(await wallet.getAddress());
|
||||
await dao.stakeAvailability(rollup.target, currentRep, availabilityStakeDuration);
|
||||
if (currentRep) {
|
||||
await dao.stakeAvailability(rollup.target, currentRep, availabilityStakeDuration);
|
||||
}
|
||||
};
|
||||
|
||||
const getBatchPostAuthorWeights = async (batchItems_) => {
|
||||
|
@ -43,25 +58,28 @@ const getBatchPostAuthorWeights = async (batchItems_) => {
|
|||
// TODO: Rewards for policing
|
||||
// TODO: Propagation via references
|
||||
});
|
||||
// Rescale author weights so they sum to 1000000
|
||||
const sumOfWeights = Object.values(weights).reduce((t, v) => t + v, 0);
|
||||
const scaledWeights = weights
|
||||
.map((weight) => Math.floor((weight * 1000000) / sumOfWeights));
|
||||
const sumOfScaledWeights = Object.values(scaledWeights).reduce((t, v) => t + v, 0);
|
||||
scaledWeights[0] += 1000000 - sumOfScaledWeights;
|
||||
const authors = Object.entries(scaledWeights)
|
||||
.map(([authorAddress, weightPPM]) => ({ authorAddress, weightPPM }));
|
||||
return authors;
|
||||
});
|
||||
// Rescale author weights so they sum to 1000000
|
||||
const sumOfWeights = Object.values(weights).reduce((t, v) => t + v, 0);
|
||||
const scaledWeights = Object.values(weights)
|
||||
.map((weight) => Math.floor((weight * 1000000) / sumOfWeights));
|
||||
const sumOfScaledWeights = Object.values(scaledWeights).reduce((t, v) => t + v, 0);
|
||||
scaledWeights[0] += 1000000 - sumOfScaledWeights;
|
||||
const authors = Object.keys(weights)
|
||||
.map((authorAddress, i) => ({ authorAddress, weightPPM: scaledWeights[i] }));
|
||||
return authors;
|
||||
};
|
||||
|
||||
const submitBatchPost = async () => {
|
||||
const submitRollup = async () => {
|
||||
if (!batchItems.length) {
|
||||
return { batchItems: [] };
|
||||
}
|
||||
const authors = await getBatchPostAuthorWeights(batchItems);
|
||||
// TODO: Compute citations as aggregate of the citations of posts in the batch
|
||||
const citations = [];
|
||||
const content = `Batch of ${batchItems.length} items`;
|
||||
const embeddedData = {
|
||||
matrixPools: batchItems.map((x) => x.postId),
|
||||
batchItems,
|
||||
nonce: uuidv4().replace(/-/i, ''),
|
||||
};
|
||||
const sender = await wallet.getAddress();
|
||||
|
@ -80,9 +98,15 @@ const submitBatchPost = async () => {
|
|||
await rollup.submitBatch(batchPostId, batchItems.length, poolDuration);
|
||||
// Send matrix event
|
||||
await sendMatrixEvent('io.dgov.rollup.submit', { batchPostId, batchItems, authors });
|
||||
console.log('Submitted batch', { batchPostId, batchItems, authors });
|
||||
// Clear the batch in preparation for next batch
|
||||
batchItems = [];
|
||||
return batchPostId;
|
||||
await applicationData.put('batchItems', batchItems);
|
||||
return {
|
||||
batchPostId,
|
||||
batchItems,
|
||||
authors,
|
||||
};
|
||||
};
|
||||
|
||||
const evaluateMatrixPoolOutcome = async (postId, { dryRun } = {}) => {
|
||||
|
@ -96,8 +120,8 @@ const evaluateMatrixPoolOutcome = async (postId, { dryRun } = {}) => {
|
|||
.filter((x) => !x.inFavor)
|
||||
.reduce((total, { amount }) => total + amount, 0);
|
||||
const votePasses = stakedFor * winRatio[1] >= (stakedFor + stakedAgainst) * winRatio[0];
|
||||
const totalSupply = await dao.totalSupply();
|
||||
const quorumMet = BigInt(stakedFor + stakedAgainst) * quorum[1] >= totalSupply * quorum[0];
|
||||
const totalSupply = Number(await dao.totalSupply());
|
||||
const quorumMet = (stakedFor + stakedAgainst) * quorum[1] >= totalSupply * quorum[0];
|
||||
const result = {
|
||||
stakedFor, stakedAgainst, totalSupply, votePasses, quorumMet,
|
||||
};
|
||||
|
@ -126,7 +150,7 @@ const evaluateMatrixPoolOutcome = async (postId, { dryRun } = {}) => {
|
|||
}
|
||||
if (submitBatch) {
|
||||
await stakeRollupAvailability();
|
||||
await submitBatchPost();
|
||||
await submitRollup();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -150,6 +174,29 @@ const validateWorkEvidence = async (sender, post) => {
|
|||
return valid;
|
||||
};
|
||||
|
||||
const validatePost = async ({
|
||||
sender, post, postId, roomId, eventId, ...params
|
||||
}) => {
|
||||
const currentRep = Number(await dao.balanceOf(await wallet.getAddress()));
|
||||
const valid = await validateWorkEvidence(sender, post);
|
||||
const stake = { amount: currentRep, account: await wallet.getAddress(), inFavor: valid };
|
||||
sendMatrixEvent('io.dgov.pool.stake', { postId, amount: currentRep, inFavor: valid });
|
||||
console.log('matrixPool', {
|
||||
postId,
|
||||
roomId,
|
||||
eventId,
|
||||
...params,
|
||||
stakes: [stake],
|
||||
});
|
||||
await matrixPools.put(postId, {
|
||||
postId,
|
||||
roomId,
|
||||
eventId,
|
||||
...params,
|
||||
stakes: [stake],
|
||||
});
|
||||
};
|
||||
|
||||
const start = async () => {
|
||||
console.log('registering validation pool decider for rollup');
|
||||
registerDecider(async (pool, post) => {
|
||||
|
@ -159,17 +206,19 @@ const start = async () => {
|
|||
// A rollup post should contain
|
||||
// - a list of off-chain validation pools
|
||||
// - authorship corresponding to the result of those off-chain pools
|
||||
if (!post.embeddedData?.matrixPools) return false;
|
||||
if (!post.embeddedData?.batchItems) return false;
|
||||
|
||||
// Our task here is to check whether the posted result agrees with our own computations
|
||||
let expectedAuthors;
|
||||
try {
|
||||
expectedAuthors = await getBatchPostAuthorWeights(post.embeddedData.matrixPools);
|
||||
expectedAuthors = await getBatchPostAuthorWeights(post.embeddedData.batchItems);
|
||||
} catch (e) {
|
||||
console.error('Error calculating batch post author weights', e);
|
||||
return false;
|
||||
}
|
||||
return authorsMatch(post.authors, expectedAuthors);
|
||||
const valid = authorsMatch(post.authors, expectedAuthors);
|
||||
console.log(`batch post ${pool.postId} is ${valid ? 'valid' : 'invalid'}`);
|
||||
return valid;
|
||||
});
|
||||
|
||||
// Even if we're not the current batch worker, keep track of batch items
|
||||
|
@ -181,15 +230,15 @@ const start = async () => {
|
|||
|
||||
// Check for an assigned batch worker
|
||||
batchWorker = await rollup.batchWorker();
|
||||
console.log('At startup', { batchWorker });
|
||||
console.log('At startup, batch worker:', batchWorker);
|
||||
|
||||
// Stake availability and set an interval to maintain it
|
||||
await stakeRollupAvailability();
|
||||
setInterval(stakeRollupAvailability, availabilityStakeDuration * 1000);
|
||||
|
||||
rollup.on('BatchWorkerAssigned', async (batchWorker_) => {
|
||||
console.log('Batch worker assigned:', batchWorker);
|
||||
batchWorker = batchWorker_;
|
||||
console.log('Batch worker assigned:', batchWorker);
|
||||
if (batchWorker === await wallet.getAddress()) {
|
||||
console.log('This instance is the new batch worker');
|
||||
}
|
||||
|
@ -204,7 +253,11 @@ const start = async () => {
|
|||
const quorum = [1, 3];
|
||||
const winRatio = [1, 2];
|
||||
const params = {
|
||||
sender, fee, duration, quorum, winRatio,
|
||||
sender,
|
||||
fee: Number(fee),
|
||||
duration,
|
||||
quorum,
|
||||
winRatio,
|
||||
};
|
||||
|
||||
let post;
|
||||
|
@ -228,16 +281,8 @@ const start = async () => {
|
|||
...params,
|
||||
});
|
||||
// Register our own stake and send a message
|
||||
const currentRep = await dao.balanceOf(await wallet.getAddress());
|
||||
const valid = await validateWorkEvidence(sender, post);
|
||||
const stake = { amount: currentRep, account: await wallet.getAddress(), inFavor: valid };
|
||||
sendMatrixEvent('io.dgov.pool.stake', { postId, amount: currentRep, inFavor: valid });
|
||||
await matrixPools.put(postId, {
|
||||
postId,
|
||||
roomId,
|
||||
eventId,
|
||||
...params,
|
||||
stakes: [stake],
|
||||
await validatePost({
|
||||
sender, post, postId, roomId, eventId, ...params,
|
||||
});
|
||||
} else {
|
||||
throw e;
|
||||
|
@ -267,12 +312,8 @@ const start = async () => {
|
|||
console.error(`Post ID ${postId} not found`);
|
||||
break;
|
||||
}
|
||||
const currentRep = await dao.balanceOf(await wallet.getAddress());
|
||||
const valid = await validateWorkEvidence(sender, post);
|
||||
const stake = { amount: currentRep, account: await wallet.getAddress(), inFavor: valid };
|
||||
sendMatrixEvent('io.dgov.pool.stake', { postId, amount: currentRep, inFavor: valid });
|
||||
await matrixPools.put(postId, {
|
||||
roomId, eventId, ...params, stakes: [stake],
|
||||
await validatePost({
|
||||
sender, post, postId, roomId, eventId, ...params,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -322,6 +363,8 @@ const start = async () => {
|
|||
}
|
||||
matrixPool.result = result;
|
||||
await matrixPools.put(postId, matrixPool);
|
||||
batchItems.push(postId);
|
||||
await applicationData.put('batchItems', batchItems);
|
||||
break;
|
||||
}
|
||||
case 'io.dgov.rollup.submit': {
|
||||
|
@ -340,6 +383,10 @@ const start = async () => {
|
|||
if (!authorsMatch(authors, expectedAuthors)) {
|
||||
sendMatrixText(`Unexpected result for batch post ${batchPostId}`);
|
||||
}
|
||||
// Reset batchItems in preparation for next batch
|
||||
const nextBatchItems = batchItems.filter((postId) => !batchPostIds.includes(postId));
|
||||
batchItems = nextBatchItems;
|
||||
await applicationData.put('batchItems', batchItems);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -349,4 +396,6 @@ const start = async () => {
|
|||
|
||||
module.exports = {
|
||||
start,
|
||||
submitRollup,
|
||||
resetBatch,
|
||||
};
|
||||
|
|
|
@ -12,7 +12,6 @@ const setTargetRoomId = async (roomId) => {
|
|||
};
|
||||
|
||||
const processOutboundQueue = async ({ type, ...args }) => {
|
||||
console.log('processing outbound queue item', { type, args });
|
||||
if (!targetRoomId) return;
|
||||
switch (type) {
|
||||
case 'MatrixEvent': {
|
||||
|
@ -47,9 +46,10 @@ const startOutboundQueue = async (matrixClient_) => {
|
|||
outboundQueue.resume();
|
||||
};
|
||||
|
||||
const sendMatrixEvent = async (type, content) => new Promise((resolve) => {
|
||||
const sendMatrixEvent = async (eventType, content) => new Promise((resolve) => {
|
||||
outboundQueue.push({
|
||||
eventType: 'MatrixEvent',
|
||||
type: 'MatrixEvent',
|
||||
eventType,
|
||||
content,
|
||||
onSend: ((roomId, eventId) => {
|
||||
resolve({ roomId, eventId });
|
||||
|
@ -59,7 +59,7 @@ const sendMatrixEvent = async (type, content) => new Promise((resolve) => {
|
|||
|
||||
const sendMatrixText = async (text) => new Promise((resolve) => {
|
||||
outboundQueue.push({
|
||||
eventType: 'MatrixText',
|
||||
type: 'MatrixText',
|
||||
text,
|
||||
onSend: ((roomId, eventId) => {
|
||||
resolve({ roomId, eventId });
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"localhost": {
|
||||
"DAO": "0xc7E04c11eD94E375857b885b3e6E1Db30C061348",
|
||||
"Work1": "0x1bEffEB10E9f5714a8e385FfcA84046688677eA8",
|
||||
"Onboarding": "0xFC40076c675693441C6e553FEdDD3A3348db81E4",
|
||||
"Proposals": "0xa1349A27D43d0F71CeDD75904ACc8f8CF8F81582",
|
||||
"Rollup": "0x1361c87D5972a71cBCA34f6EAD928358deaC750D",
|
||||
"Work2": "0x691Bcb6a8378Cec103BE58Dfa037DC57E6FFf4d1",
|
||||
"Reputation": "0xfC979dbae6Cd0f35CC240889663B523B35c5F101",
|
||||
"Forum": "0xaf247e316A081871e713F492279D2360bd162401",
|
||||
"Bench": "0xC8BCE8171e626d07E5095256F703B1df23a67362"
|
||||
"DAO": "0x1d63FDe5B461106729fE1e5e38A02fc68C518Af5",
|
||||
"Work1": "0xB8f0cd092979F273b752FDa060F82BF2745f192e",
|
||||
"Onboarding": "0x8F00038542C87A5eAf18d5938B7723bF2A04A4e4",
|
||||
"Proposals": "0x6c18eb38b7450F8DaE5A5928A40fcA3952493Ee4",
|
||||
"Rollup": "0x57BDFFf79108E5198dec6268A6BFFD8B62ECfA38",
|
||||
"Work2": "0x42b79f8d8408c36aD4347ab72f826684440a7a8F",
|
||||
"Reputation": "0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3",
|
||||
"Forum": "0x050C420Cc4995B41217Eba1B54B82Fd5687e9139",
|
||||
"Bench": "0xfe58B9EB03F75A603de1B286584f5E9532ab8fB5"
|
||||
},
|
||||
"sepolia": {
|
||||
"DAO": "0x8e5bd58B2ca8910C5F9be8de847d6883B15c60d2",
|
||||
|
|
|
@ -56,7 +56,7 @@ contract Rollup is Availability {
|
|||
}
|
||||
// initiate a validation pool for this batch
|
||||
uint fee;
|
||||
for (uint i = 0; i < itemCount; i++) {
|
||||
for (uint i = 0; i < batchSize; i++) {
|
||||
fee += items[i].fee;
|
||||
}
|
||||
poolIndex = dao.initiateValidationPool{value: fee}(
|
||||
|
@ -70,7 +70,7 @@ contract Rollup is Availability {
|
|||
""
|
||||
);
|
||||
// Include all the availability stakes from the batched work
|
||||
for (uint i = 0; i < itemCount; i++) {
|
||||
for (uint i = 0; i < batchSize; i++) {
|
||||
dao.delegatedStakeOnValidationPool(
|
||||
poolIndex,
|
||||
items[i].worker,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"localhost": {
|
||||
"DAO": "0xc7E04c11eD94E375857b885b3e6E1Db30C061348",
|
||||
"Work1": "0x1bEffEB10E9f5714a8e385FfcA84046688677eA8",
|
||||
"Onboarding": "0xFC40076c675693441C6e553FEdDD3A3348db81E4",
|
||||
"Proposals": "0xa1349A27D43d0F71CeDD75904ACc8f8CF8F81582",
|
||||
"Rollup": "0x1361c87D5972a71cBCA34f6EAD928358deaC750D",
|
||||
"Work2": "0x691Bcb6a8378Cec103BE58Dfa037DC57E6FFf4d1",
|
||||
"Reputation": "0xfC979dbae6Cd0f35CC240889663B523B35c5F101",
|
||||
"Forum": "0xaf247e316A081871e713F492279D2360bd162401",
|
||||
"Bench": "0xC8BCE8171e626d07E5095256F703B1df23a67362"
|
||||
"DAO": "0x1d63FDe5B461106729fE1e5e38A02fc68C518Af5",
|
||||
"Work1": "0xB8f0cd092979F273b752FDa060F82BF2745f192e",
|
||||
"Onboarding": "0x8F00038542C87A5eAf18d5938B7723bF2A04A4e4",
|
||||
"Proposals": "0x6c18eb38b7450F8DaE5A5928A40fcA3952493Ee4",
|
||||
"Rollup": "0x57BDFFf79108E5198dec6268A6BFFD8B62ECfA38",
|
||||
"Work2": "0x42b79f8d8408c36aD4347ab72f826684440a7a8F",
|
||||
"Reputation": "0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3",
|
||||
"Forum": "0x050C420Cc4995B41217Eba1B54B82Fd5687e9139",
|
||||
"Bench": "0xfe58B9EB03F75A603de1B286584f5E9532ab8fB5"
|
||||
},
|
||||
"sepolia": {
|
||||
"DAO": "0x8e5bd58B2ca8910C5F9be8de847d6883B15c60d2",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue