latency_entropy_with_callback.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. let 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. const currentBlock = await web3.eth.getBlockNumber();
  59. if (fromBlock > currentBlock) {
  60. continue;
  61. }
  62. const events = await entropyContract.getPastEvents("RevealedWithCallback", {
  63. fromBlock: fromBlock,
  64. toBlock: currentBlock,
  65. });
  66. fromBlock = currentBlock + 1;
  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. await new Promise((resolve) => setTimeout(resolve, 300));
  82. }
  83. }
  84. async function main() {
  85. const argv = await parser.argv;
  86. if (!argv.chain && !argv["all-chains"]) {
  87. throw new Error("Must specify either --chain or --all-chains");
  88. }
  89. const privateKey = toPrivateKey(argv.privateKey);
  90. if (argv["all-chains"]) {
  91. for (const contract of Object.values(DefaultStore.entropy_contracts)) {
  92. if (
  93. contract.getChain().isMainnet() ===
  94. (argv["all-chains"] === "mainnet")
  95. ) {
  96. console.log(`Testing latency for ${contract.getId()}...`);
  97. await testLatency(contract, privateKey);
  98. }
  99. }
  100. } else if (argv.chain) {
  101. const chain = findEvmChain(argv.chain);
  102. const contract = findEntropyContract(chain);
  103. await testLatency(contract, privateKey);
  104. }
  105. }
  106. main();