Blockhash.test.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. const { ethers, network } = require('hardhat');
  2. const { expect } = require('chai');
  3. const { loadFixture, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers');
  4. const { impersonate } = require('../helpers/account');
  5. const HISTORY_STORAGE_ADDRESS = '0x0000F90827F1C53a10cb7A02335B175320002935';
  6. const SYSTEM_ADDRESS = '0xfffffffffffffffffffffffffffffffffffffffe';
  7. const HISTORY_SERVE_WINDOW = 8191;
  8. const BLOCKHASH_SERVE_WINDOW = 256;
  9. async function fixture() {
  10. return {
  11. mock: await ethers.deployContract('$Blockhash'),
  12. systemSigner: await impersonate(SYSTEM_ADDRESS),
  13. latestBlock: await ethers.provider.getBlock('latest'),
  14. };
  15. }
  16. describe('Blockhash', function () {
  17. beforeEach(async function () {
  18. Object.assign(this, await loadFixture(fixture));
  19. });
  20. for (const supported of [true, false]) {
  21. describe(`${supported ? 'supported' : 'unsupported'} chain`, function () {
  22. beforeEach(async function () {
  23. if (supported) {
  24. await this.systemSigner.sendTransaction({ to: HISTORY_STORAGE_ADDRESS, data: this.latestBlock.hash });
  25. } else {
  26. // `setCode` in hardhat-network-helpers doesn't support empty code :/
  27. await network.provider.request({ method: 'hardhat_setCode', params: [HISTORY_STORAGE_ADDRESS, '0x'] });
  28. }
  29. });
  30. it('recent block', async function () {
  31. // fast forward (less than blockhash serve window)
  32. await mineUpTo(this.latestBlock.number + BLOCKHASH_SERVE_WINDOW);
  33. await expect(this.mock.$blockHash(this.latestBlock.number)).to.eventually.equal(this.latestBlock.hash);
  34. });
  35. it('old block', async function () {
  36. // fast forward (more than blockhash serve window)
  37. await mineUpTo(this.latestBlock.number + BLOCKHASH_SERVE_WINDOW + 1);
  38. await expect(this.mock.$blockHash(this.latestBlock.number)).to.eventually.equal(
  39. supported ? this.latestBlock.hash : ethers.ZeroHash,
  40. );
  41. });
  42. it('very old block', async function () {
  43. // fast forward (more than history serve window)
  44. await mineUpTo(this.latestBlock.number + HISTORY_SERVE_WINDOW + 10);
  45. await expect(this.mock.$blockHash(this.latestBlock.number)).to.eventually.equal(ethers.ZeroHash);
  46. });
  47. it('future block', async function () {
  48. // check history access in the future
  49. await expect(this.mock.$blockHash(this.latestBlock.number + 10)).to.eventually.equal(ethers.ZeroHash);
  50. });
  51. });
  52. }
  53. });