-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proof of concept: deterministic tasking using SHA256(StationID) ^ SHA256(Task) #287
Conversation
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Analysis of committee sizes before and after this change: Conclusion The proposed design has acceptable performance and significantly improves the quality of committees. To have enough confidence that a majority of each committee is honest, we need each committee to have at least 40-50 participants. The current algorithm does not meet that requirement for at least 10% of committees. The proposed algorithm seems to meet this requirement in all committees. |
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
Signed-off-by: Miroslav Bajtoš <oss@bajtos.net>
@@ -31,6 +32,7 @@ export type RecordTelemetryFn = ( | |||
export type FraudAssesment = | |||
| 'OK' | |||
| 'INVALID_TASK' | |||
| 'TASK_NOT_ALLOWED' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conceptually, what's the difference between invalid_task
and task_not_allowed
? The first includes the second I think, but maybe we can rename it to be more precise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question! In the current code:
- INVALID_TASK means the task does not match any of the 1000 tasks defined for the round.
- TASK_NOT_ALLOWED means the task is valid for the round, but this node is not allowed to perform it.
I'd like to keep the distinction. INVALID_TASK is typically used for measurements that are committed to the wrong round. Typically, all measurements in the first batch published after a new round starts are measurements for tasks from the previous round because spark-api & checker nodes haven't noticed the new round yet.
I agree to find more descriptive names 👍🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it! What about
TASK_NOT_FOUND
TASK_WRONG_NODE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about this?
TASK_NOT_IN_ROUND
TASK_NOT_FOR_NODE
On the second thought, TASK_WRONG_NODE
works too 👍🏻
logger.log('EVALUATE ROUND %s: using randomness %s', roundIndex, randomness) | ||
|
||
const started = Date.now() | ||
const taskWithKeys = await Promise.all(sparkRoundDetails.retrievalTasks.map(async (task) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const taskWithKeys = await Promise.all(sparkRoundDetails.retrievalTasks.map(async (task) => { | |
const tasksWithKeys = await Promise.all(sparkRoundDetails.retrievalTasks.map(async (task) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about keyedTasks
?
return { ...task, key } | ||
})) | ||
|
||
const seeker = new closest.Seeker([...taskWithKeys], (targetKey, t) => t.key ^ targetKey) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const seeker = new closest.Seeker([...taskWithKeys], (targetKey, t) => t.key ^ targetKey) | |
const seeker = new closest.Seeker([...tasksWithKeys], (targetKey, t) => t.key ^ targetKey) |
/* eslint-disable-next-line camelcase */ | ||
for (const { stationId, participantAddress, inet_group } of measurements) { | ||
if (stations.has(stationId)) continue | ||
/* eslint-disable-next-line camelcase */ | ||
stations.set(stationId, { participantAddress, inet_group }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/* eslint-disable-next-line camelcase */ | |
for (const { stationId, participantAddress, inet_group } of measurements) { | |
if (stations.has(stationId)) continue | |
/* eslint-disable-next-line camelcase */ | |
stations.set(stationId, { participantAddress, inet_group }) | |
for (const { stationId, participantAddress, inet_group: inetGroup } of measurements) { | |
if (stations.has(stationId)) continue | |
/* eslint-disable-next-line camelcase */ | |
stations.set(stationId, { participantAddress, inetGroup }) |
I think it's better to rename props as soon as you use them
Closing in favour of #296 |
See https://www.notion.so/spacemeridian/Spark-Tasking-v3-745b0e1020bb4000ac77acafee09e683
The step of building the list of per-station tasks takes 3124ms to complete, increasing the duration of the evaluation by 50% to 9641ms.
Links: