chore: apply prettier
This commit is contained in:
@ -19,11 +19,13 @@ tests/
|
||||
## Prerequisites
|
||||
|
||||
1. Install the test framework:
|
||||
|
||||
```bash
|
||||
pip install -e test-framework/
|
||||
```
|
||||
|
||||
2. Set up environment variables in `.env`:
|
||||
|
||||
```
|
||||
ANTHROPIC_API_KEY=your_test_key
|
||||
GITHUB_USERNAME=your_test_username
|
||||
@ -47,12 +49,15 @@ python -m tests.e2e --reset
|
||||
## Test Flow
|
||||
|
||||
1. API Key Validation
|
||||
|
||||
- Validates Anthropic API key
|
||||
|
||||
2. GitHub Validation
|
||||
|
||||
- Validates GitHub credentials
|
||||
|
||||
3. Todo Management
|
||||
|
||||
- Fetches todos for each worker
|
||||
- Generates summaries
|
||||
- Submits results
|
||||
|
@ -1,12 +1,8 @@
|
||||
import "dotenv/config";
|
||||
|
||||
export const TASK_ID =
|
||||
process.env.TASK_ID || "BXbYKFdXZhQgEaMFbeShaisQBYG1FD4MiSf9gg4n6mVn";
|
||||
export const WEBPACKED_FILE_PATH =
|
||||
process.env.WEBPACKED_FILE_PATH || "../dist/main.js";
|
||||
export const TASK_ID = process.env.TASK_ID || "BXbYKFdXZhQgEaMFbeShaisQBYG1FD4MiSf9gg4n6mVn";
|
||||
export const WEBPACKED_FILE_PATH = process.env.WEBPACKED_FILE_PATH || "../dist/main.js";
|
||||
|
||||
const envKeywords = process.env.TEST_KEYWORDS ?? "";
|
||||
|
||||
export const TEST_KEYWORDS = envKeywords
|
||||
? envKeywords.split(",")
|
||||
: ["TEST", "EZ TESTING"];
|
||||
export const TEST_KEYWORDS = envKeywords ? envKeywords.split(",") : ["TEST", "EZ TESTING"];
|
||||
|
@ -1,188 +1,188 @@
|
||||
import { initializeTaskManager, taskRunner } from "@_koii/task-manager";
|
||||
import { setup } from "../src/task/0-setup";
|
||||
import { task } from "../src/task/1-task";
|
||||
import { submission } from "../src/task/2-submission";
|
||||
import { audit } from "../src/task/3-audit";
|
||||
import { distribution } from "../src/task/4-distribution";
|
||||
import { routes } from "../src/task/5-routes";
|
||||
import { namespaceWrapper, _server } from "@_koii/task-manager/namespace-wrapper";
|
||||
import Joi from "joi";
|
||||
import axios from "axios";
|
||||
import { Submitter } from "@_koii/task-manager";
|
||||
beforeAll(async () => {
|
||||
await namespaceWrapper.defaultTaskSetup();
|
||||
initializeTaskManager({
|
||||
setup,
|
||||
task,
|
||||
submission,
|
||||
audit,
|
||||
distribution,
|
||||
routes,
|
||||
});
|
||||
});
|
||||
|
||||
describe("Performing the task", () => {
|
||||
it("should performs the core logic task", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.task(round);
|
||||
const value = await namespaceWrapper.storeGet("value");
|
||||
expect(value).toBeDefined();
|
||||
expect(value).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should make the submission to k2 for dummy round 1", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.submitTask(round);
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
submission_value: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
round: Joi.number().integer().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required()
|
||||
.min(1);
|
||||
const validationResult = schema.validate(taskState?.submissions);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Submission doesn't exist or is incorrect");
|
||||
}
|
||||
});
|
||||
|
||||
it("should make an audit on submission", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.auditTask(round);
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
console.log("TASK STATE", taskState);
|
||||
console.log("audit task", taskState?.submissions_audit_trigger);
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
trigger_by: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
votes: Joi.array().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required();
|
||||
const validationResult = schema.validate(taskState?.submissions_audit_trigger);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Submission audit is incorrect");
|
||||
}
|
||||
});
|
||||
it("should make the distribution submission to k2 for dummy round 1", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.submitDistributionList(round);
|
||||
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
submission_value: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
round: Joi.number().integer().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required()
|
||||
.min(1);
|
||||
console.log("Distribution submission", taskState?.distribution_rewards_submission);
|
||||
const validationResult = schema.validate(taskState?.distribution_rewards_submission);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Distribution submission doesn't exist or is incorrect");
|
||||
}
|
||||
});
|
||||
it("should make an audit on distribution submission", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.auditDistribution(round);
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
console.log("audit task", taskState?.distributions_audit_trigger);
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
trigger_by: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
votes: Joi.array().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required();
|
||||
const validationResult = schema.validate(taskState?.distributions_audit_trigger);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Distribution audit is incorrect");
|
||||
}
|
||||
});
|
||||
|
||||
it("should make sure the submitted distribution list is valid", async () => {
|
||||
const round = 1;
|
||||
const distributionList = await namespaceWrapper.getDistributionList("", round);
|
||||
console.log("Generated distribution List", JSON.parse(distributionList.toString()));
|
||||
const schema = Joi.object().pattern(Joi.string().required(), Joi.number().integer().required()).required();
|
||||
const validationResult = schema.validate(JSON.parse(distributionList.toString()));
|
||||
console.log(validationResult);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Submitted distribution list is not valid");
|
||||
}
|
||||
});
|
||||
|
||||
it("should test the endpoint", async () => {
|
||||
const response = await axios.get("http://localhost:3000");
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.data).toEqual({ message: "Running", status: 200 });
|
||||
});
|
||||
|
||||
it("should generate a empty distribution list when submission is 0", async () => {
|
||||
const submitters: Submitter[] = [];
|
||||
const bounty = Math.floor(Math.random() * 1e15) + 1;
|
||||
const roundNumber = Math.floor(Math.random() * 1e5) + 1;
|
||||
const distributionList = await distribution(submitters, bounty, roundNumber);
|
||||
expect(distributionList).toEqual({});
|
||||
});
|
||||
|
||||
it("should generate a distribution list contains all the submitters", async () => {
|
||||
const simulatedSubmitters = 5;
|
||||
const submitters: Submitter[] = [];
|
||||
// 10k is the rough maximum number of submitters
|
||||
for (let i = 0; i < simulatedSubmitters; i++) {
|
||||
const publicKey = `mockPublicKey${i}`;
|
||||
submitters.push({
|
||||
publicKey,
|
||||
votes: Math.floor(Math.random() * simulatedSubmitters) - 5000,
|
||||
stake: Math.floor(Math.random() * 1e9) + 1,
|
||||
});
|
||||
}
|
||||
const bounty = Math.floor(Math.random() * 1e15) + 1;
|
||||
const roundNumber = 1;
|
||||
const distributionList = await distribution(submitters, bounty, roundNumber);
|
||||
expect(Object.keys(distributionList).length).toBe(submitters.length);
|
||||
expect(Object.keys(distributionList).sort()).toEqual(submitters.map((submitter) => submitter.publicKey).sort());
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
_server.close();
|
||||
});
|
||||
import { initializeTaskManager, taskRunner } from "@_koii/task-manager";
|
||||
import { setup } from "../src/task/0-setup";
|
||||
import { task } from "../src/task/1-task";
|
||||
import { submission } from "../src/task/2-submission";
|
||||
import { audit } from "../src/task/3-audit";
|
||||
import { distribution } from "../src/task/4-distribution";
|
||||
import { routes } from "../src/task/5-routes";
|
||||
import { namespaceWrapper, _server } from "@_koii/task-manager/namespace-wrapper";
|
||||
import Joi from "joi";
|
||||
import axios from "axios";
|
||||
import { Submitter } from "@_koii/task-manager";
|
||||
beforeAll(async () => {
|
||||
await namespaceWrapper.defaultTaskSetup();
|
||||
initializeTaskManager({
|
||||
setup,
|
||||
task,
|
||||
submission,
|
||||
audit,
|
||||
distribution,
|
||||
routes,
|
||||
});
|
||||
});
|
||||
|
||||
describe("Performing the task", () => {
|
||||
it("should performs the core logic task", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.task(round);
|
||||
const value = await namespaceWrapper.storeGet("value");
|
||||
expect(value).toBeDefined();
|
||||
expect(value).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should make the submission to k2 for dummy round 1", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.submitTask(round);
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
submission_value: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
round: Joi.number().integer().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required()
|
||||
.min(1);
|
||||
const validationResult = schema.validate(taskState?.submissions);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Submission doesn't exist or is incorrect");
|
||||
}
|
||||
});
|
||||
|
||||
it("should make an audit on submission", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.auditTask(round);
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
console.log("TASK STATE", taskState);
|
||||
console.log("audit task", taskState?.submissions_audit_trigger);
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
trigger_by: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
votes: Joi.array().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required();
|
||||
const validationResult = schema.validate(taskState?.submissions_audit_trigger);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Submission audit is incorrect");
|
||||
}
|
||||
});
|
||||
it("should make the distribution submission to k2 for dummy round 1", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.submitDistributionList(round);
|
||||
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
submission_value: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
round: Joi.number().integer().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required()
|
||||
.min(1);
|
||||
console.log("Distribution submission", taskState?.distribution_rewards_submission);
|
||||
const validationResult = schema.validate(taskState?.distribution_rewards_submission);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Distribution submission doesn't exist or is incorrect");
|
||||
}
|
||||
});
|
||||
it("should make an audit on distribution submission", async () => {
|
||||
const round = 1;
|
||||
await taskRunner.auditDistribution(round);
|
||||
const taskState = await namespaceWrapper.getTaskState({});
|
||||
console.log("audit task", taskState?.distributions_audit_trigger);
|
||||
const schema = Joi.object()
|
||||
.pattern(
|
||||
Joi.string(),
|
||||
Joi.object().pattern(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
trigger_by: Joi.string().required(),
|
||||
slot: Joi.number().integer().required(),
|
||||
votes: Joi.array().required(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
.required();
|
||||
const validationResult = schema.validate(taskState?.distributions_audit_trigger);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Distribution audit is incorrect");
|
||||
}
|
||||
});
|
||||
|
||||
it("should make sure the submitted distribution list is valid", async () => {
|
||||
const round = 1;
|
||||
const distributionList = await namespaceWrapper.getDistributionList("", round);
|
||||
console.log("Generated distribution List", JSON.parse(distributionList.toString()));
|
||||
const schema = Joi.object().pattern(Joi.string().required(), Joi.number().integer().required()).required();
|
||||
const validationResult = schema.validate(JSON.parse(distributionList.toString()));
|
||||
console.log(validationResult);
|
||||
try {
|
||||
expect(validationResult.error).toBeUndefined();
|
||||
} catch (e) {
|
||||
throw new Error("Submitted distribution list is not valid");
|
||||
}
|
||||
});
|
||||
|
||||
it("should test the endpoint", async () => {
|
||||
const response = await axios.get("http://localhost:3000");
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.data).toEqual({ message: "Running", status: 200 });
|
||||
});
|
||||
|
||||
it("should generate a empty distribution list when submission is 0", async () => {
|
||||
const submitters: Submitter[] = [];
|
||||
const bounty = Math.floor(Math.random() * 1e15) + 1;
|
||||
const roundNumber = Math.floor(Math.random() * 1e5) + 1;
|
||||
const distributionList = await distribution(submitters, bounty, roundNumber);
|
||||
expect(distributionList).toEqual({});
|
||||
});
|
||||
|
||||
it("should generate a distribution list contains all the submitters", async () => {
|
||||
const simulatedSubmitters = 5;
|
||||
const submitters: Submitter[] = [];
|
||||
// 10k is the rough maximum number of submitters
|
||||
for (let i = 0; i < simulatedSubmitters; i++) {
|
||||
const publicKey = `mockPublicKey${i}`;
|
||||
submitters.push({
|
||||
publicKey,
|
||||
votes: Math.floor(Math.random() * simulatedSubmitters) - 5000,
|
||||
stake: Math.floor(Math.random() * 1e9) + 1,
|
||||
});
|
||||
}
|
||||
const bounty = Math.floor(Math.random() * 1e15) + 1;
|
||||
const roundNumber = 1;
|
||||
const distributionList = await distribution(submitters, bounty, roundNumber);
|
||||
expect(Object.keys(distributionList).length).toBe(submitters.length);
|
||||
expect(Object.keys(distributionList).sort()).toEqual(submitters.map((submitter) => submitter.publicKey).sort());
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
_server.close();
|
||||
});
|
||||
|
@ -1,84 +1,84 @@
|
||||
import { taskRunner } from "@_koii/task-manager";
|
||||
|
||||
import "../src/index.js";
|
||||
import { namespaceWrapper } from "@_koii/task-manager/namespace-wrapper";
|
||||
import { Keypair } from "@_koii/web3.js";
|
||||
|
||||
const numRounds = parseInt(process.argv[2]) || 1;
|
||||
const roundDelay = parseInt(process.argv[3]) || 5000;
|
||||
const functionDelay = parseInt(process.argv[4]) || 1000;
|
||||
|
||||
let TASK_TIMES: number[] = [];
|
||||
let SUBMISSION_TIMES: number[] = [];
|
||||
let AUDIT_TIMES: number[] = [];
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function executeTasks() {
|
||||
const keypair = Keypair.generate();
|
||||
await namespaceWrapper.stakeOnChain(keypair.publicKey, keypair, keypair.publicKey, 10000);
|
||||
for (let round = 0; round < numRounds; round++) {
|
||||
const taskStartTime = Date.now();
|
||||
await taskRunner.task(round);
|
||||
const taskEndTime = Date.now();
|
||||
TASK_TIMES.push(taskEndTime - taskStartTime);
|
||||
await sleep(functionDelay);
|
||||
|
||||
const taskSubmissionStartTime = Date.now();
|
||||
await taskRunner.submitTask(round);
|
||||
const taskSubmissionEndTime = Date.now();
|
||||
SUBMISSION_TIMES.push(taskSubmissionEndTime - taskSubmissionStartTime);
|
||||
await sleep(functionDelay);
|
||||
|
||||
const auditStartTime = Date.now();
|
||||
await taskRunner.auditTask(round);
|
||||
const auditEndTime = Date.now();
|
||||
AUDIT_TIMES.push(auditEndTime - auditStartTime);
|
||||
await sleep(functionDelay);
|
||||
|
||||
await taskRunner.selectAndGenerateDistributionList(round);
|
||||
await sleep(functionDelay);
|
||||
|
||||
await taskRunner.auditDistribution(round);
|
||||
|
||||
if (round < numRounds - 1) {
|
||||
await sleep(roundDelay);
|
||||
}
|
||||
}
|
||||
console.log("TIME METRICS BELOW");
|
||||
function metrics(name: string, times: number[]) {
|
||||
const average = (arr: number[]) => arr.reduce((a, b) => a + b, 0) / arr.length;
|
||||
const formatTime = (ms: number) => (ms / 1000).toFixed(4);
|
||||
const formatSlot = (ms: number) => Math.ceil(ms / 408);
|
||||
const min = Math.min(...times);
|
||||
const max = Math.max(...times);
|
||||
const avg = average(times);
|
||||
const timeMin = formatTime(min);
|
||||
const timeMax = formatTime(max);
|
||||
const timeAvg = formatTime(avg);
|
||||
const slotMin = formatSlot(min);
|
||||
const slotMax = formatSlot(max);
|
||||
const slotAvg = formatSlot(avg);
|
||||
|
||||
return {
|
||||
Metric: `SIMULATED ${name} WINDOW`,
|
||||
"Avg Time (s)": timeAvg,
|
||||
"Avg Slots": slotAvg,
|
||||
"Min Time (s)": timeMin,
|
||||
"Min Slots": slotMin,
|
||||
"Max Time (s)": timeMax,
|
||||
"Max Slots": slotMax,
|
||||
};
|
||||
}
|
||||
const timeMetrics = metrics("TASK", TASK_TIMES);
|
||||
const submissionMetrics = metrics("SUBMISSION", SUBMISSION_TIMES);
|
||||
const auditMetrics = metrics("AUDIT", AUDIT_TIMES);
|
||||
|
||||
console.table([timeMetrics, submissionMetrics, auditMetrics]);
|
||||
|
||||
console.log("All tasks executed. Test completed.");
|
||||
process.exit(0);
|
||||
}
|
||||
setTimeout(executeTasks, 1500);
|
||||
import { taskRunner } from "@_koii/task-manager";
|
||||
|
||||
import "../src/index.js";
|
||||
import { namespaceWrapper } from "@_koii/task-manager/namespace-wrapper";
|
||||
import { Keypair } from "@_koii/web3.js";
|
||||
|
||||
const numRounds = parseInt(process.argv[2]) || 1;
|
||||
const roundDelay = parseInt(process.argv[3]) || 5000;
|
||||
const functionDelay = parseInt(process.argv[4]) || 1000;
|
||||
|
||||
let TASK_TIMES: number[] = [];
|
||||
let SUBMISSION_TIMES: number[] = [];
|
||||
let AUDIT_TIMES: number[] = [];
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function executeTasks() {
|
||||
const keypair = Keypair.generate();
|
||||
await namespaceWrapper.stakeOnChain(keypair.publicKey, keypair, keypair.publicKey, 10000);
|
||||
for (let round = 0; round < numRounds; round++) {
|
||||
const taskStartTime = Date.now();
|
||||
await taskRunner.task(round);
|
||||
const taskEndTime = Date.now();
|
||||
TASK_TIMES.push(taskEndTime - taskStartTime);
|
||||
await sleep(functionDelay);
|
||||
|
||||
const taskSubmissionStartTime = Date.now();
|
||||
await taskRunner.submitTask(round);
|
||||
const taskSubmissionEndTime = Date.now();
|
||||
SUBMISSION_TIMES.push(taskSubmissionEndTime - taskSubmissionStartTime);
|
||||
await sleep(functionDelay);
|
||||
|
||||
const auditStartTime = Date.now();
|
||||
await taskRunner.auditTask(round);
|
||||
const auditEndTime = Date.now();
|
||||
AUDIT_TIMES.push(auditEndTime - auditStartTime);
|
||||
await sleep(functionDelay);
|
||||
|
||||
await taskRunner.selectAndGenerateDistributionList(round);
|
||||
await sleep(functionDelay);
|
||||
|
||||
await taskRunner.auditDistribution(round);
|
||||
|
||||
if (round < numRounds - 1) {
|
||||
await sleep(roundDelay);
|
||||
}
|
||||
}
|
||||
console.log("TIME METRICS BELOW");
|
||||
function metrics(name: string, times: number[]) {
|
||||
const average = (arr: number[]) => arr.reduce((a, b) => a + b, 0) / arr.length;
|
||||
const formatTime = (ms: number) => (ms / 1000).toFixed(4);
|
||||
const formatSlot = (ms: number) => Math.ceil(ms / 408);
|
||||
const min = Math.min(...times);
|
||||
const max = Math.max(...times);
|
||||
const avg = average(times);
|
||||
const timeMin = formatTime(min);
|
||||
const timeMax = formatTime(max);
|
||||
const timeAvg = formatTime(avg);
|
||||
const slotMin = formatSlot(min);
|
||||
const slotMax = formatSlot(max);
|
||||
const slotAvg = formatSlot(avg);
|
||||
|
||||
return {
|
||||
Metric: `SIMULATED ${name} WINDOW`,
|
||||
"Avg Time (s)": timeAvg,
|
||||
"Avg Slots": slotAvg,
|
||||
"Min Time (s)": timeMin,
|
||||
"Min Slots": slotMin,
|
||||
"Max Time (s)": timeMax,
|
||||
"Max Slots": slotMax,
|
||||
};
|
||||
}
|
||||
const timeMetrics = metrics("TASK", TASK_TIMES);
|
||||
const submissionMetrics = metrics("SUBMISSION", SUBMISSION_TIMES);
|
||||
const auditMetrics = metrics("AUDIT", AUDIT_TIMES);
|
||||
|
||||
console.table([timeMetrics, submissionMetrics, auditMetrics]);
|
||||
|
||||
console.log("All tasks executed. Test completed.");
|
||||
process.exit(0);
|
||||
}
|
||||
setTimeout(executeTasks, 1500);
|
||||
|
@ -4,7 +4,7 @@
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// body: JSON.stringify({
|
||||
// body: JSON.stringify({
|
||||
// text: `[TASK] Error summarizing issue:\n ${JSON.stringify({
|
||||
// status: "error",
|
||||
// data: {
|
||||
@ -16,4 +16,4 @@
|
||||
// console.log("[TASK] slackResponse: ", slackResponse);
|
||||
// }
|
||||
|
||||
// testSlackWebhook();
|
||||
// testSlackWebhook();
|
||||
|
File diff suppressed because it is too large
Load Diff
364
worker/tests/wasm/bincode_js.d.ts
vendored
364
worker/tests/wasm/bincode_js.d.ts
vendored
@ -1,225 +1,225 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {any} val
|
||||
* @returns {any}
|
||||
*/
|
||||
* @param {any} val
|
||||
* @returns {any}
|
||||
*/
|
||||
export function bincode_js_deserialize(val: any): any;
|
||||
/**
|
||||
* @param {any} val
|
||||
* @returns {any}
|
||||
*/
|
||||
* @param {any} val
|
||||
* @returns {any}
|
||||
*/
|
||||
export function borsh_bpf_js_deserialize(val: any): any;
|
||||
/**
|
||||
* Initialize Javascript logging and panic handler
|
||||
*/
|
||||
* Initialize Javascript logging and panic handler
|
||||
*/
|
||||
export function solana_program_init(): void;
|
||||
/**
|
||||
* A hash; the 32-byte output of a hashing algorithm.
|
||||
*
|
||||
* This struct is used most often in `solana-sdk` and related crates to contain
|
||||
* a [SHA-256] hash, but may instead contain a [blake3] hash, as created by the
|
||||
* [`blake3`] module (and used in [`Message::hash`]).
|
||||
*
|
||||
* [SHA-256]: https://en.wikipedia.org/wiki/SHA-2
|
||||
* [blake3]: https://github.com/BLAKE3-team/BLAKE3
|
||||
* [`blake3`]: crate::blake3
|
||||
* [`Message::hash`]: crate::message::Message::hash
|
||||
*/
|
||||
* A hash; the 32-byte output of a hashing algorithm.
|
||||
*
|
||||
* This struct is used most often in `solana-sdk` and related crates to contain
|
||||
* a [SHA-256] hash, but may instead contain a [blake3] hash, as created by the
|
||||
* [`blake3`] module (and used in [`Message::hash`]).
|
||||
*
|
||||
* [SHA-256]: https://en.wikipedia.org/wiki/SHA-2
|
||||
* [blake3]: https://github.com/BLAKE3-team/BLAKE3
|
||||
* [`blake3`]: crate::blake3
|
||||
* [`Message::hash`]: crate::message::Message::hash
|
||||
*/
|
||||
export class Hash {
|
||||
free(): void;
|
||||
/**
|
||||
* Create a new Hash object
|
||||
*
|
||||
* * `value` - optional hash as a base58 encoded string, `Uint8Array`, `[number]`
|
||||
* @param {any} value
|
||||
*/
|
||||
/**
|
||||
* Create a new Hash object
|
||||
*
|
||||
* * `value` - optional hash as a base58 encoded string, `Uint8Array`, `[number]`
|
||||
* @param {any} value
|
||||
*/
|
||||
constructor(value: any);
|
||||
/**
|
||||
* Return the base58 string representation of the hash
|
||||
* @returns {string}
|
||||
*/
|
||||
/**
|
||||
* Return the base58 string representation of the hash
|
||||
* @returns {string}
|
||||
*/
|
||||
toString(): string;
|
||||
/**
|
||||
* Checks if two `Hash`s are equal
|
||||
* @param {Hash} other
|
||||
* @returns {boolean}
|
||||
*/
|
||||
/**
|
||||
* Checks if two `Hash`s are equal
|
||||
* @param {Hash} other
|
||||
* @returns {boolean}
|
||||
*/
|
||||
equals(other: Hash): boolean;
|
||||
/**
|
||||
* Return the `Uint8Array` representation of the hash
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
/**
|
||||
* Return the `Uint8Array` representation of the hash
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
toBytes(): Uint8Array;
|
||||
}
|
||||
/**
|
||||
* A directive for a single invocation of a Solana program.
|
||||
*
|
||||
* An instruction specifies which program it is calling, which accounts it may
|
||||
* read or modify, and additional data that serves as input to the program. One
|
||||
* or more instructions are included in transactions submitted by Solana
|
||||
* clients. Instructions are also used to describe [cross-program
|
||||
* invocations][cpi].
|
||||
*
|
||||
* [cpi]: https://docs.solana.com/developing/programming-model/calling-between-programs
|
||||
*
|
||||
* During execution, a program will receive a list of account data as one of
|
||||
* its arguments, in the same order as specified during `Instruction`
|
||||
* construction.
|
||||
*
|
||||
* While Solana is agnostic to the format of the instruction data, it has
|
||||
* built-in support for serialization via [`borsh`] and [`bincode`].
|
||||
*
|
||||
* [`borsh`]: https://docs.rs/borsh/latest/borsh/
|
||||
* [`bincode`]: https://docs.rs/bincode/latest/bincode/
|
||||
*
|
||||
* # Specifying account metadata
|
||||
*
|
||||
* When constructing an [`Instruction`], a list of all accounts that may be
|
||||
* read or written during the execution of that instruction must be supplied as
|
||||
* [`AccountMeta`] values.
|
||||
*
|
||||
* Any account whose data may be mutated by the program during execution must
|
||||
* be specified as writable. During execution, writing to an account that was
|
||||
* not specified as writable will cause the transaction to fail. Writing to an
|
||||
* account that is not owned by the program will cause the transaction to fail.
|
||||
*
|
||||
* Any account whose lamport balance may be mutated by the program during
|
||||
* execution must be specified as writable. During execution, mutating the
|
||||
* lamports of an account that was not specified as writable will cause the
|
||||
* transaction to fail. While _subtracting_ lamports from an account not owned
|
||||
* by the program will cause the transaction to fail, _adding_ lamports to any
|
||||
* account is allowed, as long is it is mutable.
|
||||
*
|
||||
* Accounts that are not read or written by the program may still be specified
|
||||
* in an `Instruction`'s account list. These will affect scheduling of program
|
||||
* execution by the runtime, but will otherwise be ignored.
|
||||
*
|
||||
* When building a transaction, the Solana runtime coalesces all accounts used
|
||||
* by all instructions in that transaction, along with accounts and permissions
|
||||
* required by the runtime, into a single account list. Some accounts and
|
||||
* account permissions required by the runtime to process a transaction are
|
||||
* _not_ required to be included in an `Instruction`s account list. These
|
||||
* include:
|
||||
*
|
||||
* - The program ID — it is a separate field of `Instruction`
|
||||
* - The transaction's fee-paying account — it is added during [`Message`]
|
||||
* construction. A program may still require the fee payer as part of the
|
||||
* account list if it directly references it.
|
||||
*
|
||||
* [`Message`]: crate::message::Message
|
||||
*
|
||||
* Programs may require signatures from some accounts, in which case they
|
||||
* should be specified as signers during `Instruction` construction. The
|
||||
* program must still validate during execution that the account is a signer.
|
||||
*/
|
||||
* A directive for a single invocation of a Solana program.
|
||||
*
|
||||
* An instruction specifies which program it is calling, which accounts it may
|
||||
* read or modify, and additional data that serves as input to the program. One
|
||||
* or more instructions are included in transactions submitted by Solana
|
||||
* clients. Instructions are also used to describe [cross-program
|
||||
* invocations][cpi].
|
||||
*
|
||||
* [cpi]: https://docs.solana.com/developing/programming-model/calling-between-programs
|
||||
*
|
||||
* During execution, a program will receive a list of account data as one of
|
||||
* its arguments, in the same order as specified during `Instruction`
|
||||
* construction.
|
||||
*
|
||||
* While Solana is agnostic to the format of the instruction data, it has
|
||||
* built-in support for serialization via [`borsh`] and [`bincode`].
|
||||
*
|
||||
* [`borsh`]: https://docs.rs/borsh/latest/borsh/
|
||||
* [`bincode`]: https://docs.rs/bincode/latest/bincode/
|
||||
*
|
||||
* # Specifying account metadata
|
||||
*
|
||||
* When constructing an [`Instruction`], a list of all accounts that may be
|
||||
* read or written during the execution of that instruction must be supplied as
|
||||
* [`AccountMeta`] values.
|
||||
*
|
||||
* Any account whose data may be mutated by the program during execution must
|
||||
* be specified as writable. During execution, writing to an account that was
|
||||
* not specified as writable will cause the transaction to fail. Writing to an
|
||||
* account that is not owned by the program will cause the transaction to fail.
|
||||
*
|
||||
* Any account whose lamport balance may be mutated by the program during
|
||||
* execution must be specified as writable. During execution, mutating the
|
||||
* lamports of an account that was not specified as writable will cause the
|
||||
* transaction to fail. While _subtracting_ lamports from an account not owned
|
||||
* by the program will cause the transaction to fail, _adding_ lamports to any
|
||||
* account is allowed, as long is it is mutable.
|
||||
*
|
||||
* Accounts that are not read or written by the program may still be specified
|
||||
* in an `Instruction`'s account list. These will affect scheduling of program
|
||||
* execution by the runtime, but will otherwise be ignored.
|
||||
*
|
||||
* When building a transaction, the Solana runtime coalesces all accounts used
|
||||
* by all instructions in that transaction, along with accounts and permissions
|
||||
* required by the runtime, into a single account list. Some accounts and
|
||||
* account permissions required by the runtime to process a transaction are
|
||||
* _not_ required to be included in an `Instruction`s account list. These
|
||||
* include:
|
||||
*
|
||||
* - The program ID — it is a separate field of `Instruction`
|
||||
* - The transaction's fee-paying account — it is added during [`Message`]
|
||||
* construction. A program may still require the fee payer as part of the
|
||||
* account list if it directly references it.
|
||||
*
|
||||
* [`Message`]: crate::message::Message
|
||||
*
|
||||
* Programs may require signatures from some accounts, in which case they
|
||||
* should be specified as signers during `Instruction` construction. The
|
||||
* program must still validate during execution that the account is a signer.
|
||||
*/
|
||||
export class Instruction {
|
||||
free(): void;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
*/
|
||||
export class Instructions {
|
||||
free(): void;
|
||||
/**
|
||||
*/
|
||||
/**
|
||||
*/
|
||||
constructor();
|
||||
/**
|
||||
* @param {Instruction} instruction
|
||||
*/
|
||||
/**
|
||||
* @param {Instruction} instruction
|
||||
*/
|
||||
push(instruction: Instruction): void;
|
||||
}
|
||||
/**
|
||||
* A Solana transaction message (legacy).
|
||||
*
|
||||
* See the [`message`] module documentation for further description.
|
||||
*
|
||||
* [`message`]: crate::message
|
||||
*
|
||||
* Some constructors accept an optional `payer`, the account responsible for
|
||||
* paying the cost of executing a transaction. In most cases, callers should
|
||||
* specify the payer explicitly in these constructors. In some cases though,
|
||||
* the caller is not _required_ to specify the payer, but is still allowed to:
|
||||
* in the `Message` structure, the first account is always the fee-payer, so if
|
||||
* the caller has knowledge that the first account of the constructed
|
||||
* transaction's `Message` is both a signer and the expected fee-payer, then
|
||||
* redundantly specifying the fee-payer is not strictly required.
|
||||
*/
|
||||
* A Solana transaction message (legacy).
|
||||
*
|
||||
* See the [`message`] module documentation for further description.
|
||||
*
|
||||
* [`message`]: crate::message
|
||||
*
|
||||
* Some constructors accept an optional `payer`, the account responsible for
|
||||
* paying the cost of executing a transaction. In most cases, callers should
|
||||
* specify the payer explicitly in these constructors. In some cases though,
|
||||
* the caller is not _required_ to specify the payer, but is still allowed to:
|
||||
* in the `Message` structure, the first account is always the fee-payer, so if
|
||||
* the caller has knowledge that the first account of the constructed
|
||||
* transaction's `Message` is both a signer and the expected fee-payer, then
|
||||
* redundantly specifying the fee-payer is not strictly required.
|
||||
*/
|
||||
export class Message {
|
||||
free(): void;
|
||||
/**
|
||||
* The id of a recent ledger entry.
|
||||
*/
|
||||
/**
|
||||
* The id of a recent ledger entry.
|
||||
*/
|
||||
recent_blockhash: Hash;
|
||||
}
|
||||
/**
|
||||
* The address of a [Solana account][acc].
|
||||
*
|
||||
* Some account addresses are [ed25519] public keys, with corresponding secret
|
||||
* keys that are managed off-chain. Often, though, account addresses do not
|
||||
* have corresponding secret keys — as with [_program derived
|
||||
* addresses_][pdas] — or the secret key is not relevant to the operation
|
||||
* of a program, and may have even been disposed of. As running Solana programs
|
||||
* can not safely create or manage secret keys, the full [`Keypair`] is not
|
||||
* defined in `solana-program` but in `solana-sdk`.
|
||||
*
|
||||
* [acc]: https://docs.solana.com/developing/programming-model/accounts
|
||||
* [ed25519]: https://ed25519.cr.yp.to/
|
||||
* [pdas]: https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses
|
||||
* [`Keypair`]: https://docs.rs/solana-sdk/latest/solana_sdk/signer/keypair/struct.Keypair.html
|
||||
*/
|
||||
* The address of a [Solana account][acc].
|
||||
*
|
||||
* Some account addresses are [ed25519] public keys, with corresponding secret
|
||||
* keys that are managed off-chain. Often, though, account addresses do not
|
||||
* have corresponding secret keys — as with [_program derived
|
||||
* addresses_][pdas] — or the secret key is not relevant to the operation
|
||||
* of a program, and may have even been disposed of. As running Solana programs
|
||||
* can not safely create or manage secret keys, the full [`Keypair`] is not
|
||||
* defined in `solana-program` but in `solana-sdk`.
|
||||
*
|
||||
* [acc]: https://docs.solana.com/developing/programming-model/accounts
|
||||
* [ed25519]: https://ed25519.cr.yp.to/
|
||||
* [pdas]: https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses
|
||||
* [`Keypair`]: https://docs.rs/solana-sdk/latest/solana_sdk/signer/keypair/struct.Keypair.html
|
||||
*/
|
||||
export class Pubkey {
|
||||
free(): void;
|
||||
/**
|
||||
* Create a new Pubkey object
|
||||
*
|
||||
* * `value` - optional public key as a base58 encoded string, `Uint8Array`, `[number]`
|
||||
* @param {any} value
|
||||
*/
|
||||
/**
|
||||
* Create a new Pubkey object
|
||||
*
|
||||
* * `value` - optional public key as a base58 encoded string, `Uint8Array`, `[number]`
|
||||
* @param {any} value
|
||||
*/
|
||||
constructor(value: any);
|
||||
/**
|
||||
* Return the base58 string representation of the public key
|
||||
* @returns {string}
|
||||
*/
|
||||
/**
|
||||
* Return the base58 string representation of the public key
|
||||
* @returns {string}
|
||||
*/
|
||||
toString(): string;
|
||||
/**
|
||||
* Check if a `Pubkey` is on the ed25519 curve.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
/**
|
||||
* Check if a `Pubkey` is on the ed25519 curve.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isOnCurve(): boolean;
|
||||
/**
|
||||
* Checks if two `Pubkey`s are equal
|
||||
* @param {Pubkey} other
|
||||
* @returns {boolean}
|
||||
*/
|
||||
/**
|
||||
* Checks if two `Pubkey`s are equal
|
||||
* @param {Pubkey} other
|
||||
* @returns {boolean}
|
||||
*/
|
||||
equals(other: Pubkey): boolean;
|
||||
/**
|
||||
* Return the `Uint8Array` representation of the public key
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
/**
|
||||
* Return the `Uint8Array` representation of the public key
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
toBytes(): Uint8Array;
|
||||
/**
|
||||
* Derive a Pubkey from another Pubkey, string seed, and a program id
|
||||
* @param {Pubkey} base
|
||||
* @param {string} seed
|
||||
* @param {Pubkey} owner
|
||||
* @returns {Pubkey}
|
||||
*/
|
||||
/**
|
||||
* Derive a Pubkey from another Pubkey, string seed, and a program id
|
||||
* @param {Pubkey} base
|
||||
* @param {string} seed
|
||||
* @param {Pubkey} owner
|
||||
* @returns {Pubkey}
|
||||
*/
|
||||
static createWithSeed(base: Pubkey, seed: string, owner: Pubkey): Pubkey;
|
||||
/**
|
||||
* Derive a program address from seeds and a program id
|
||||
* @param {any[]} seeds
|
||||
* @param {Pubkey} program_id
|
||||
* @returns {Pubkey}
|
||||
*/
|
||||
/**
|
||||
* Derive a program address from seeds and a program id
|
||||
* @param {any[]} seeds
|
||||
* @param {Pubkey} program_id
|
||||
* @returns {Pubkey}
|
||||
*/
|
||||
static createProgramAddress(seeds: any[], program_id: Pubkey): Pubkey;
|
||||
/**
|
||||
* Find a valid program address
|
||||
*
|
||||
* Returns:
|
||||
* * `[PubKey, number]` - the program address and bump seed
|
||||
* @param {any[]} seeds
|
||||
* @param {Pubkey} program_id
|
||||
* @returns {any}
|
||||
*/
|
||||
/**
|
||||
* Find a valid program address
|
||||
*
|
||||
* Returns:
|
||||
* * `[PubKey, number]` - the program address and bump seed
|
||||
* @param {any[]} seeds
|
||||
* @param {Pubkey} program_id
|
||||
* @returns {any}
|
||||
*/
|
||||
static findProgramAddress(seeds: any[], program_id: Pubkey): any;
|
||||
}
|
||||
|
30
worker/tests/wasm/bincode_js_bg.wasm.d.ts
vendored
30
worker/tests/wasm/bincode_js_bg.wasm.d.ts
vendored
@ -8,13 +8,37 @@ export function __wbg_get_message_recent_blockhash(a: number): number;
|
||||
export function __wbg_set_message_recent_blockhash(a: number, b: number): void;
|
||||
export function solana_program_init(): void;
|
||||
export function systeminstruction_createAccount(a: number, b: number, c: number, d: number, e: number): number;
|
||||
export function systeminstruction_createAccountWithSeed(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number): number;
|
||||
export function systeminstruction_createAccountWithSeed(
|
||||
a: number,
|
||||
b: number,
|
||||
c: number,
|
||||
d: number,
|
||||
e: number,
|
||||
f: number,
|
||||
g: number,
|
||||
h: number,
|
||||
): number;
|
||||
export function systeminstruction_assign(a: number, b: number): number;
|
||||
export function systeminstruction_assignWithSeed(a: number, b: number, c: number, d: number, e: number): number;
|
||||
export function systeminstruction_transfer(a: number, b: number, c: number): number;
|
||||
export function systeminstruction_transferWithSeed(a: number, b: number, c: number, d: number, e: number, f: number, g: number): number;
|
||||
export function systeminstruction_transferWithSeed(
|
||||
a: number,
|
||||
b: number,
|
||||
c: number,
|
||||
d: number,
|
||||
e: number,
|
||||
f: number,
|
||||
g: number,
|
||||
): number;
|
||||
export function systeminstruction_allocate(a: number, b: number): number;
|
||||
export function systeminstruction_allocateWithSeed(a: number, b: number, c: number, d: number, e: number, f: number): number;
|
||||
export function systeminstruction_allocateWithSeed(
|
||||
a: number,
|
||||
b: number,
|
||||
c: number,
|
||||
d: number,
|
||||
e: number,
|
||||
f: number,
|
||||
): number;
|
||||
export function systeminstruction_createNonceAccount(a: number, b: number, c: number, d: number): number;
|
||||
export function systeminstruction_advanceNonceAccount(a: number, b: number): number;
|
||||
export function systeminstruction_withdrawNonceAccount(a: number, b: number, c: number, d: number): number;
|
||||
|
@ -1,31 +1,31 @@
|
||||
import path from 'path'
|
||||
import Dotenv from 'dotenv-webpack'
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
export default {
|
||||
mode: "development",
|
||||
entry: "./src/index.ts",
|
||||
output: {
|
||||
filename: "main.js",
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
libraryTarget: "commonjs2",
|
||||
},
|
||||
target: "node",
|
||||
resolve: {
|
||||
extensions: [".ts", ".js"],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: "ts-loader",
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
devtool: "source-map",
|
||||
plugins: [new Dotenv()],
|
||||
};
|
||||
import path from "path";
|
||||
import Dotenv from "dotenv-webpack";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
export default {
|
||||
mode: "development",
|
||||
entry: "./src/index.ts",
|
||||
output: {
|
||||
filename: "main.js",
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
libraryTarget: "commonjs2",
|
||||
},
|
||||
target: "node",
|
||||
resolve: {
|
||||
extensions: [".ts", ".js"],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: "ts-loader",
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
devtool: "source-map",
|
||||
plugins: [new Dotenv()],
|
||||
};
|
||||
|
Reference in New Issue
Block a user