Skip to content

Commit

Permalink
Manage submissions wisely
Browse files Browse the repository at this point in the history
  • Loading branch information
webmaster128 committed Aug 24, 2023
1 parent ab9fb96 commit b81fa9e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 21 deletions.
32 changes: 18 additions & 14 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
sleep,
watch,
} from "./deps.ts";
import { BeaconCache } from "./cache.ts";
import { JobsObserver } from "./jobs.ts";
import { Submitter } from "./submitter.ts";
import { queryIsAllowListed, queryIsIncentivized } from "./drand_contract.ts";
Expand Down Expand Up @@ -133,6 +132,8 @@ if (import.meta.main) {

const incentivizedRounds = new Map<number, Promise<boolean>>();

const fastestNodeClient = new FastestNodeClient(drandUrls, drandOptions);

const submitter = new Submitter({
client,
tmClient,
Expand All @@ -145,18 +146,15 @@ if (import.meta.main) {
drandAddress: config.drandAddress,
userAgent,
incentivizedRounds,
drandClient: fastestNodeClient,
});

const fastestNodeClient = new FastestNodeClient(drandUrls, drandOptions);
fastestNodeClient.start();
const cache = new BeaconCache(fastestNodeClient, 200 /* 10 min of beacons */);
const abortController = new AbortController();
for await (const beacon of watch(fastestNodeClient, abortController)) {
const n = beacon.round; // n is the round we just received and process now
const m = n + 1; // m := n+1 refers to the next round in this current loop

cache.add(n, beacon.signature);

console.log(`➘ #${beacon.round} received after ${publishedSince(beacon.round)}ms`);

setTimeout(() => {
Expand All @@ -171,31 +169,37 @@ if (import.meta.main) {
incentivizedRounds.set(m, promise);
}, publishedIn(m) + 100);

const didSubmit = await submitter.handleBeacon(beacon);
const didSubmit = await submitter.handlePublishedBeacon(beacon);

// Check jobs every 1.5s, shifted 1200ms from the drand receiving
const shift = 1200;
setTimeout(() =>
jobs?.check().then(
(rs) => {
if (!rs.length) return;
(rounds) => {
if (!rounds.length) return;
const past = rounds.filter((r) => r <= n);
const future = rounds.filter((r) => r > n);
console.log(
`Past: %o, Future: %o`,
rs.filter((r) => r <= n),
rs.filter((r) => r > n),
past,
future,
);
submitter.submitPastRounds(past);
},
(err) => console.error(err),
), shift);
setTimeout(() =>
jobs?.check().then(
(rs) => {
if (!rs.length) return;
(rounds) => {
if (!rounds.length) return;
const past = rounds.filter((r) => r <= n);
const future = rounds.filter((r) => r > n);
console.log(
`Past: %o, Future: %o`,
rs.filter((r) => r <= n),
rs.filter((r) => r > n),
past,
future,
);
submitter.submitPastRounds(past);
},
(err) => console.error(err),
), shift + 1500);
Expand Down
38 changes: 31 additions & 7 deletions submitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
assertIsDeliverTxSuccess,
calculateFee,
CosmWasmClient,
FastestNodeClient,
isDefined,
logs,
RandomnessBeacon,
Expand All @@ -13,6 +14,7 @@ import {
} from "./deps.ts";
import { makeAddBeaconMessage } from "./drand_contract.ts";
import { ibcPacketsSent } from "./ibc.ts";
import { BeaconCache } from "./cache.ts";

interface Capture {
client: SigningCosmWasmClient;
Expand All @@ -26,6 +28,7 @@ interface Capture {
userAgent: string;
getNextSignData: () => SignerData;
incentivizedRounds: Map<number, Promise<boolean>>;
drandClient: FastestNodeClient;
}

export class Submitter {
Expand All @@ -40,6 +43,8 @@ export class Submitter {
private userAgent: string;
private getNextSignData: () => SignerData;
private incentivizedRounds: Map<number, Promise<boolean>>;
private cache: BeaconCache;
private submitted: Set<number>;

constructor(capture: Capture) {
this.client = capture.client;
Expand All @@ -53,19 +58,41 @@ export class Submitter {
this.userAgent = capture.userAgent;
this.getNextSignData = capture.getNextSignData;
this.incentivizedRounds = capture.incentivizedRounds;
this.cache = new BeaconCache(capture.drandClient, 200 /* 10 min of beacons */);
this.submitted = new Set();
}

public async handleBeacon(beacon: RandomnessBeacon): Promise<boolean> {
public async submitPastRounds(rounds: number[]): Promise<void> {
// TODO: Check if incentivised before submistting
await Promise.all(rounds.map((round) => this.submitRound(round)));
}

public async submitRound(round: number): Promise<void> {
const signature = await this.cache.get(round);
await this.submit({ round, signature });
return;
}

public async handlePublishedBeacon(beacon: RandomnessBeacon): Promise<boolean> {
this.cache.add(beacon.round, beacon.signature);

// We don't have evidence that this round is incentivized. This is no guarantee it did not
// get incentivized in the meantime, but we prefer to skip than risk the gas.
const isIncentivized = await this.incentivizedRounds.get(beacon.round);
if (!isIncentivized) {
if (isIncentivized) {
// Use this log to ensure awaiting the isIncentivized query does not slow us down.
console.log(`♪ #${beacon.round} ready for signing after ${publishedSince(beacon.round)}ms`);
await this.submit(beacon);
return true;
} else {
console.log(`Skipping.`);
return false;
}
}

// Use this log to ensure awaiting the isIncentivized query does not slow us down.
console.log(`♪ #${beacon.round} ready for signing after ${publishedSince(beacon.round)}ms`);
private async submit(beacon: Pick<RandomnessBeacon, "round" | "signature">) {
if (this.submitted.has(beacon.round)) return;
this.submitted.add(beacon.round);

const broadcastTime = Date.now() / 1000;
const msg = makeAddBeaconMessage(this.botAddress, this.drandAddress, beacon);
Expand All @@ -75,7 +102,6 @@ export class Submitter {
const signed = await this.client.sign(this.botAddress, [msg], fee, memo, signData);

// console.log(`♫ #${beacon.round} signed after ${publishedSince(beacon.round)}ms`);

const tx = Uint8Array.from(TxRaw.encode(signed).finish());

const p1 = this.client.broadcastTx(tx);
Expand Down Expand Up @@ -135,7 +161,5 @@ export class Submitter {
)
}`,
);

return true;
}
}

0 comments on commit b81fa9e

Please sign in to comment.