Skip to content

Commit 4b8b9bf

Browse files
author
Dev Kalra
authored
feat(contract_manager): latency script for entropy v2 (#1494)
* latency script for entropy v2 * add block number difference * correct desc * refactor request randomness * refactor and use chain as arg instead of contract * unnecessary condition * js doc * correct desc * use blockhash
1 parent c7883c8 commit 4b8b9bf

File tree

4 files changed

+149
-21
lines changed

4 files changed

+149
-21
lines changed

contract_manager/scripts/common.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DefaultStore, EvmChain, PrivateKey } from "../src";
1+
import { DefaultStore, EvmChain, EvmEntropyContract, PrivateKey } from "../src";
22
import { existsSync, readFileSync, writeFileSync } from "fs";
33
import { join } from "path";
44
import Web3 from "web3";
@@ -181,3 +181,34 @@ export function getSelectedChains(argv: {
181181
}
182182
return selectedChains;
183183
}
184+
185+
/**
186+
* Finds the entropy contract for a given EVM chain.
187+
* @param {EvmChain} chain The EVM chain to find the entropy contract for.
188+
* @returns The entropy contract for the given EVM chain.
189+
* @throws {Error} an error if the entropy contract is not found for the given EVM chain.
190+
*/
191+
export function findEntropyContract(chain: EvmChain): EvmEntropyContract {
192+
for (const contract of Object.values(DefaultStore.entropy_contracts)) {
193+
if (contract.getChain().getId() === chain.getId()) {
194+
return contract;
195+
}
196+
}
197+
throw new Error(`Entropy contract not found for chain ${chain.getId()}`);
198+
}
199+
200+
/**
201+
* Finds an EVM chain by its name.
202+
* @param {string} chainName The name of the chain to find.
203+
* @returns The EVM chain instance.
204+
* @throws {Error} an error if the chain is not found or is not an EVM chain.
205+
*/
206+
export function findEvmChain(chainName: string): EvmChain {
207+
const chain = DefaultStore.chains[chainName];
208+
if (!chain) {
209+
throw new Error(`Chain ${chainName} not found`);
210+
} else if (!(chain instanceof EvmChain)) {
211+
throw new Error(`Chain ${chainName} is not an EVM chain`);
212+
}
213+
return chain;
214+
}

contract_manager/scripts/latency_entropy.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,32 @@
11
import yargs from "yargs";
22
import { hideBin } from "yargs/helpers";
3-
import { DefaultStore, toPrivateKey } from "../src";
4-
import { COMMON_DEPLOY_OPTIONS } from "./common";
3+
import { toPrivateKey } from "../src";
4+
import {
5+
COMMON_DEPLOY_OPTIONS,
6+
findEntropyContract,
7+
findEvmChain,
8+
} from "./common";
59

610
const parser = yargs(hideBin(process.argv))
711
.usage(
812
"Requests and reveals a random number from an entropy contract while measuing the\n" +
913
"latency between request submission and availablity of the provider revelation from fortuna.\n" +
10-
"Usage: $0 --contract <entropy_contract_id> --private-key <private-key>"
14+
"Usage: $0 --chain <chain-id> --private-key <private-key>"
1115
)
1216
.options({
13-
contract: {
17+
chain: {
1418
type: "string",
1519
demandOption: true,
16-
desc: "Contract to test latency for",
20+
desc: "test latency for the contract on this chain",
1721
},
1822
"private-key": COMMON_DEPLOY_OPTIONS["private-key"],
1923
});
2024

2125
async function main() {
2226
const argv = await parser.argv;
23-
const contract = DefaultStore.entropy_contracts[argv.contract];
24-
if (!contract) {
25-
throw new Error(
26-
`Contract ${argv.contract} not found. Contracts found: ${Object.keys(
27-
DefaultStore.entropy_contracts
28-
)}`
29-
);
30-
}
27+
const chain = findEvmChain(argv.chain);
28+
const contract = findEntropyContract(chain);
29+
3130
const provider = await contract.getDefaultProvider();
3231
const providerInfo = await contract.getProviderInfo(provider);
3332
const userRandomNumber = contract.generateUserRandomNumber();
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import yargs from "yargs";
2+
import { hideBin } from "yargs/helpers";
3+
import { toPrivateKey } from "../src";
4+
import {
5+
COMMON_DEPLOY_OPTIONS,
6+
findEntropyContract,
7+
findEvmChain,
8+
} from "./common";
9+
import Web3 from "web3";
10+
11+
const parser = yargs(hideBin(process.argv))
12+
.usage(
13+
"Requests a random number from an entropy contract and measures the\n" +
14+
"latency between request submission and fulfillment by the Fortuna keeper service.\n" +
15+
"Usage: $0 --chain-id <chain-id> --private-key <private-key>"
16+
)
17+
.options({
18+
chain: {
19+
type: "string",
20+
demandOption: true,
21+
desc: "test latency for the contract on this chain",
22+
},
23+
"private-key": COMMON_DEPLOY_OPTIONS["private-key"],
24+
});
25+
26+
async function main() {
27+
const argv = await parser.argv;
28+
29+
const chain = findEvmChain(argv.chain);
30+
const contract = findEntropyContract(chain);
31+
32+
const provider = await contract.getDefaultProvider();
33+
const userRandomNumber = contract.generateUserRandomNumber();
34+
const privateKey = toPrivateKey(argv.privateKey);
35+
const requestResponse = await contract.requestRandomness(
36+
userRandomNumber,
37+
provider,
38+
privateKey,
39+
true // with callback
40+
);
41+
console.log(`Request tx hash : ${requestResponse.transactionHash}`);
42+
// Read the sequence number for the request from the transaction events.
43+
const sequenceNumber =
44+
requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber;
45+
console.log(`sequence : ${sequenceNumber}`);
46+
47+
const startTime = Date.now();
48+
49+
let fromBlock = requestResponse.blockNumber;
50+
const web3 = new Web3(contract.chain.getRpcUrl());
51+
const entropyContract = contract.getContract();
52+
53+
// eslint-disable-next-line no-constant-condition
54+
while (true) {
55+
const currentBlock = await web3.eth.getBlockNumber();
56+
57+
if (fromBlock > currentBlock) {
58+
continue;
59+
}
60+
61+
const events = await entropyContract.getPastEvents("RevealedWithCallback", {
62+
fromBlock: fromBlock,
63+
toBlock: currentBlock,
64+
});
65+
fromBlock = currentBlock + 1;
66+
67+
const event = events.find(
68+
(event) => event.returnValues.request[1] == sequenceNumber
69+
);
70+
71+
if (event !== undefined) {
72+
console.log(`Random number : ${event.returnValues.randomNumber}`);
73+
const endTime = Date.now();
74+
console.log(`Fortuna Latency : ${endTime - startTime}ms`);
75+
console.log(
76+
`Revealed after : ${
77+
currentBlock - requestResponse.blockNumber
78+
} blocks`
79+
);
80+
break;
81+
}
82+
83+
await new Promise((resolve) => setTimeout(resolve, 300));
84+
}
85+
}
86+
87+
main();

contract_manager/src/contracts/evm.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -592,19 +592,30 @@ export class EvmEntropyContract extends Storable {
592592
async requestRandomness(
593593
userRandomNumber: string,
594594
provider: string,
595-
senderPrivateKey: PrivateKey
595+
senderPrivateKey: PrivateKey,
596+
withCallback?: boolean
596597
) {
597598
const web3 = new Web3(this.chain.getRpcUrl());
598599
const userCommitment = web3.utils.keccak256(userRandomNumber);
599600
const contract = new web3.eth.Contract(EXTENDED_ENTROPY_ABI, this.address);
600601
const fee = await contract.methods.getFee(provider).call();
601602
const { address } = web3.eth.accounts.wallet.add(senderPrivateKey);
602-
const useBlockHash = false;
603-
const transactionObject = contract.methods.request(
604-
provider,
605-
userCommitment,
606-
useBlockHash
607-
);
603+
604+
let transactionObject;
605+
if (withCallback) {
606+
transactionObject = contract.methods.requestWithCallback(
607+
provider,
608+
userCommitment
609+
);
610+
} else {
611+
const useBlockHash = false;
612+
transactionObject = contract.methods.request(
613+
provider,
614+
userCommitment,
615+
useBlockHash
616+
);
617+
}
618+
608619
return this.chain.estiamteAndSendTransaction(transactionObject, {
609620
from: address,
610621
value: fee,

0 commit comments

Comments
 (0)