|
1 | 1 | import { before, describe, it } from 'mocha'; |
2 | 2 | import { printTitle } from '../_utils/formatting'; |
3 | | -import { BeaconStateVerifier, BlockRootsMock } from '../_utils/artifacts'; |
| 3 | +import { artifacts, BeaconStateVerifier, BlockRootsMock } from '../_utils/artifacts'; |
4 | 4 | import * as assert from 'assert'; |
5 | 5 | import { shouldRevert } from '../_utils/testing'; |
| 6 | +import { time } from '@nomicfoundation/hardhat-network-helpers'; |
6 | 7 |
|
7 | 8 | const hre = require('hardhat'); |
8 | 9 | const ethers = hre.ethers; |
@@ -368,5 +369,77 @@ export default function() { |
368 | 369 |
|
369 | 370 | assert.equal(await beaconStateVerifier.verifyWithdrawal(correctProof), true); |
370 | 371 | }); |
| 372 | + |
| 373 | + it(printTitle('BlockRoots', 'Returns the correct block hash'), async () => { |
| 374 | + // Choose genesis time 1000 slots ago |
| 375 | + const block = await ethers.provider.getBlock(); |
| 376 | + const beaconGenesisTime = (BigInt(block.timestamp) / 12n * 12n) - (1000n * 12n); |
| 377 | + const secondsPerSlot = 12n |
| 378 | + |
| 379 | + const BeaconRootsMock = artifacts.require('BeaconRootsMock'); |
| 380 | + const BlockRoots = artifacts.require('BlockRoots'); |
| 381 | + const beaconRootsMock = await BeaconRootsMock.new(); |
| 382 | + const blockRoots = await BlockRoots.new(beaconGenesisTime, secondsPerSlot, 8191n, beaconRootsMock.target); |
| 383 | + |
| 384 | + const root1 = '0x0000000000000000000000000000000000000000000000000000000000000001' |
| 385 | + const root2 = '0x0000000000000000000000000000000000000000000000000000000000000002' |
| 386 | + const root3 = '0x0000000000000000000000000000000000000000000000000000000000000003' |
| 387 | + |
| 388 | + async function setParentBlockRoot(slot, root) { |
| 389 | + await beaconRootsMock.setParentBlockRoot(beaconGenesisTime + (slot * secondsPerSlot), root); |
| 390 | + } |
| 391 | + |
| 392 | + await setParentBlockRoot(501n, root1); |
| 393 | + await setParentBlockRoot(502n, root2); |
| 394 | + // Simulate 2 skipped slots |
| 395 | + await setParentBlockRoot(505n, root3); |
| 396 | + |
| 397 | + assert.equal(await blockRoots.getBlockRoot(500n), root1); |
| 398 | + assert.equal(await blockRoots.getBlockRoot(501n), root2); |
| 399 | + assert.equal(await blockRoots.getBlockRoot(502n), root3); |
| 400 | + assert.equal(await blockRoots.getBlockRoot(503n), root3); |
| 401 | + assert.equal(await blockRoots.getBlockRoot(504n), root3); |
| 402 | + await shouldRevert( |
| 403 | + blockRoots.getBlockRoot(505n), |
| 404 | + "Did not revert on invalid slot", |
| 405 | + "Block root is not available" |
| 406 | + ); |
| 407 | + }); |
| 408 | + |
| 409 | + it(printTitle('BlockRoots', 'Fails to return a block root for a slot that is too old'), async () => { |
| 410 | + const block = await ethers.provider.getBlock(); |
| 411 | + const beaconGenesisTime = (BigInt(block.timestamp) / 12n * 12n); |
| 412 | + const secondsPerSlot = 12n |
| 413 | + |
| 414 | + const BeaconRootsMock = artifacts.require('BeaconRootsMock'); |
| 415 | + const BlockRoots = artifacts.require('BlockRoots'); |
| 416 | + const beaconRootsMock = await BeaconRootsMock.new(); |
| 417 | + const blockRoots = await BlockRoots.new(beaconGenesisTime, secondsPerSlot, 10n, beaconRootsMock.target); |
| 418 | + |
| 419 | + await time.increaseTo(beaconGenesisTime + (secondsPerSlot * 100n)); |
| 420 | + |
| 421 | + /** |
| 422 | + * We've set the genesis time such that we are now at slot 100 |
| 423 | + * And we've set the history buffer length to 10 |
| 424 | + * |
| 425 | + * That means the EVM theoretically has parent block hashes for slots 91 to 100 or in other words, the |
| 426 | + * block hashes for blocks in slots 90 to 99 |
| 427 | + * |
| 428 | + * Therefore, retrieving the block hash for 89 should revert with "Slot too old" but not 90 |
| 429 | + */ |
| 430 | + |
| 431 | + await shouldRevert( |
| 432 | + blockRoots.getBlockRoot(89n), |
| 433 | + "Was able to get old block root", |
| 434 | + "Slot too old" |
| 435 | + ); |
| 436 | + |
| 437 | + // We didn't actually mock the parent block hash so just check that we don't revert with "Slot too old" |
| 438 | + await shouldRevert( |
| 439 | + blockRoots.getBlockRoot(90n), |
| 440 | + "Incorrectly reverted with slot too old", |
| 441 | + "Block root is not available" |
| 442 | + ); |
| 443 | + }); |
371 | 444 | }); |
372 | 445 | } |
0 commit comments