Skip to content

Commit

Permalink
Call queryIsIncentivized right before beacon comes in
Browse files Browse the repository at this point in the history
  • Loading branch information
webmaster128 committed Jul 30, 2023
1 parent 65bf2cc commit 2b0437d
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
7 changes: 7 additions & 0 deletions drand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,10 @@ export function timeOfRound(round: number): number {
export function publishedSince(round: number): number {
return Date.now() - timeOfRound(round);
}

/**
* Time between now and publishing in milliseconds
*/
export function publishedIn(round: number): number {
return -publishedSince(round);
}
1 change: 1 addition & 0 deletions drand_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export async function queryIsIncentivized(
const { incentivized } = await client.queryContractSmart(contractAddress, {
is_incentivized: { rounds, sender: botAddress },
});
// console.log(`#${rounds[0]} incentivized query returned at ${publishedSince(rounds[0])}ms`)
assert(Array.isArray(incentivized));
return incentivized;
}
20 changes: 12 additions & 8 deletions loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
SignerData,
SigningCosmWasmClient,
} from "./deps.ts";
import { makeAddBeaconMessage, queryIsIncentivized } from "./drand_contract.ts";
import { makeAddBeaconMessage } from "./drand_contract.ts";
import { ibcPacketsSent } from "./ibc.ts";

interface Capture {
Expand All @@ -23,6 +23,7 @@ interface Capture {
gasPrice: string;
userAgent: string;
getNextSignData: () => SignerData;
incentivizedRounds: Map<number, Promise<boolean>>;
}

export async function loop(
Expand All @@ -36,29 +37,32 @@ export async function loop(
gasPrice,
userAgent,
getNextSignData,
incentivizedRounds,
}: Capture,
beacon: RandomnessBeacon,
): Promise<boolean> {
console.log(`➘ #${beacon.round} received after ${publishedSince(beacon.round)}ms`);

const isIncentivized = await queryIsIncentivized(
client,
drandAddress,
[beacon.round],
botAddress,
);

// 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 incentivizedRounds.get(beacon.round);
if (!isIncentivized) {
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`);

const broadcastTime = Date.now() / 1000;
const msg = makeAddBeaconMessage(botAddress, drandAddress, beacon);
const fee = calculateFee(gasLimitAddBeacon, gasPrice);
const memo = `Add round: ${beacon.round} (${userAgent})`;
const signData = getNextSignData(); // Do this the manual way to save one query
const signed = await client.sign(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 = client.broadcastTx(tx);
Expand Down
21 changes: 19 additions & 2 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { drandOptions, drandUrls } from "./drand.ts";
import { drandOptions, drandUrls, publishedIn } from "./drand.ts";
import { group } from "./group.ts";
import {
assert,
Expand All @@ -16,7 +16,7 @@ import {
} from "./deps.ts";
import { BeaconCache } from "./cache.ts";
import { loop } from "./loop.ts";
import { queryIsAllowListed } from "./drand_contract.ts";
import { queryIsAllowListed, queryIsIncentivized } from "./drand_contract.ts";

// Constants
const gasLimitRegister = 200_000;
Expand Down Expand Up @@ -123,13 +123,29 @@ if (import.meta.main) {
// Initialize local sign data
await resetSignData();

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

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)) {
cache.add(beacon.round, beacon.signature);

setTimeout(() => {
// This is called 100ms after publishing time (might be some ms later)
// From here we have ~300ms until the beacon comes in which should be
// enough for the query to finish. In case the query is not yet done,
// we can wait for the promise to be resolved.
// console.log(`Now : ${new Date().toISOString()}\nPublish time: ${new Date(timeOfRound(round)).toISOString()}`);
const round = beacon.round + 1;
const promise = queryIsIncentivized(client, config.contract, [round], botAddress).then(
(incentivized) => !!incentivized[0],
(_err) => false,
);
incentivizedRounds.set(round, promise);
}, publishedIn(beacon.round + 1) + 100);

const didSubmit = await loop({
client,
broadcaster2,
Expand All @@ -140,6 +156,7 @@ if (import.meta.main) {
botAddress,
drandAddress: config.contract,
userAgent,
incentivizedRounds,
}, beacon);

if (didSubmit) {
Expand Down

0 comments on commit 2b0437d

Please sign in to comment.