latency_entropy_with_callback.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import yargs from "yargs";
  2. import { hideBin } from "yargs/helpers";
  3. import {
  4. DefaultStore,
  5. EvmEntropyContract,
  6. PrivateKey,
  7. toPrivateKey,
  8. } from "../src";
  9. import {
  10. COMMON_DEPLOY_OPTIONS,
  11. findEntropyContract,
  12. findEvmChain,
  13. } from "./common";
  14. import Web3 from "web3";
  15. const parser = yargs(hideBin(process.argv))
  16. .usage(
  17. "Requests a random number from an entropy contract and measures the\n" +
  18. "latency between request submission and fulfillment by the Fortuna keeper service.\n" +
  19. "Usage: $0 --private-key <private-key> --chain <chain-id> | --all-chains <testnet|mainnet>"
  20. )
  21. .options({
  22. chain: {
  23. type: "string",
  24. desc: "test latency for the contract on this chain",
  25. conflicts: "all-chains",
  26. },
  27. "all-chains": {
  28. type: "string",
  29. conflicts: "chain",
  30. choices: ["testnet", "mainnet"],
  31. desc: "test latency for all entropy contracts deployed either on mainnet or testnet",
  32. },
  33. "private-key": COMMON_DEPLOY_OPTIONS["private-key"],
  34. });
  35. async function testLatency(
  36. contract: EvmEntropyContract,
  37. privateKey: PrivateKey
  38. ) {
  39. const provider = await contract.getDefaultProvider();
  40. const userRandomNumber = contract.generateUserRandomNumber();
  41. const requestResponse = await contract.requestRandomness(
  42. userRandomNumber,
  43. provider,
  44. privateKey,
  45. true // with callback
  46. );
  47. console.log(`Request tx hash : ${requestResponse.transactionHash}`);
  48. // Read the sequence number for the request from the transaction events.
  49. const sequenceNumber =
  50. requestResponse.events.RequestedWithCallback.returnValues.sequenceNumber;
  51. console.log(`sequence : ${sequenceNumber}`);
  52. const startTime = Date.now();
  53. const fromBlock = requestResponse.blockNumber;
  54. const web3 = new Web3(contract.chain.getRpcUrl());
  55. const entropyContract = contract.getContract();
  56. // eslint-disable-next-line no-constant-condition
  57. while (true) {
  58. await new Promise((resolve) => setTimeout(resolve, 1000));
  59. const currentBlock = await web3.eth.getBlockNumber();
  60. if (fromBlock > currentBlock) {
  61. continue;
  62. }
  63. const events = await entropyContract.getPastEvents("RevealedWithCallback", {
  64. fromBlock: fromBlock,
  65. toBlock: currentBlock,
  66. });
  67. const event = events.find(
  68. (event) => event.returnValues.request[1] == sequenceNumber
  69. );
  70. if (event !== undefined) {
  71. console.log(`Random number : ${event.returnValues.randomNumber}`);
  72. const endTime = Date.now();
  73. console.log(`Fortuna Latency : ${endTime - startTime}ms`);
  74. console.log(
  75. `Revealed after : ${
  76. currentBlock - requestResponse.blockNumber
  77. } blocks`
  78. );
  79. break;
  80. }
  81. if (Date.now() - startTime > 60000) {
  82. console.log("Timeout: 60s passed without the callback being called.");
  83. break;
  84. }
  85. }
  86. }
  87. async function main() {
  88. const argv = await parser.argv;
  89. if (!argv.chain && !argv["all-chains"]) {
  90. throw new Error("Must specify either --chain or --all-chains");
  91. }
  92. const privateKey = toPrivateKey(argv.privateKey);
  93. if (argv["all-chains"]) {
  94. for (const contract of Object.values(DefaultStore.entropy_contracts)) {
  95. if (
  96. contract.getChain().isMainnet() ===
  97. (argv["all-chains"] === "mainnet")
  98. ) {
  99. console.log(`Testing latency for ${contract.getId()}...`);
  100. await testLatency(contract, privateKey);
  101. }
  102. }
  103. } else if (argv.chain) {
  104. const chain = findEvmChain(argv.chain);
  105. const contract = findEntropyContract(chain);
  106. await testLatency(contract, privateKey);
  107. }
  108. }
  109. main();