|
2 | 2 | pragma solidity ^0.8.4; |
3 | 3 |
|
4 | 4 | import "./utils/SoladyTest.sol"; |
5 | | -import {BlockHashLib, ShortHeader} from "../src/utils/BlockHashLib.sol"; |
| 5 | +import {BlockHashLib} from "../src/utils/BlockHashLib.sol"; |
| 6 | +import {LibRLP} from "../src/utils/LibRLP.sol"; |
6 | 7 |
|
7 | 8 | contract BlockHashLibTest is SoladyTest { |
| 9 | + using LibRLP for *; |
| 10 | + |
| 11 | + struct BlockHeader { |
| 12 | + bytes32 parentHash; |
| 13 | + bytes32 ommersHash; |
| 14 | + bytes20 beneficiary; |
| 15 | + bytes32 stateRoot; |
| 16 | + bytes32 transactionsRoot; |
| 17 | + bytes32 receiptsRoot; |
| 18 | + bytes32[8] logsBloom; |
| 19 | + bytes32 difficultyOrPrevrandao; |
| 20 | + uint256 number; |
| 21 | + uint256 gasLimit; |
| 22 | + uint256 gasUsed; |
| 23 | + uint256 timestamp; |
| 24 | + bytes extraData; |
| 25 | + bytes32 mixHash; |
| 26 | + bytes8 nonce; |
| 27 | + } |
| 28 | + |
8 | 29 | uint256 internal startingBlock; |
9 | 30 |
|
10 | 31 | address internal constant SYSTEM_ADDRESS = 0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE; |
@@ -67,54 +88,90 @@ contract BlockHashLibTest is SoladyTest { |
67 | 88 | } |
68 | 89 | } |
69 | 90 |
|
70 | | - function beforeTestSetup(bytes4 selector) public pure returns (bytes[] memory cd) { |
71 | | - if (selector == this.testToShortHeader.selector) { |
72 | | - cd = new bytes[](1); |
73 | | - cd[0] = abi.encodeWithSelector(this.checkToShortHeader.selector, _ETH_BLOCK_23270177); |
| 91 | + function testVerifyBlock() public { |
| 92 | + vm.roll(23270177 + 1); |
| 93 | + vm.setBlockhash(23270177, _ETH_BLOCK_HASH_23270177); |
| 94 | + assertEq(this.verifyBlock(_ETH_BLOCK_23270177, 23270177), _ETH_BLOCK_HASH_23270177); |
| 95 | + } |
| 96 | + |
| 97 | + function verifyBlock(bytes calldata blockHeader, uint256 blockNumber) |
| 98 | + public |
| 99 | + view |
| 100 | + returns (bytes32) |
| 101 | + { |
| 102 | + return BlockHashLib.verifyBlock(blockHeader, blockNumber); |
| 103 | + } |
| 104 | + |
| 105 | + function _randomBlockHeader() internal returns (BlockHeader memory b, bytes memory encoded) { |
| 106 | + if (_randomChance(2)) { |
| 107 | + b.parentHash = bytes32(_random()); |
| 108 | + b.ommersHash = bytes32(_random()); |
| 109 | + b.beneficiary = bytes20(bytes32(_random())); |
| 110 | + b.stateRoot = bytes32(_random()); |
| 111 | + b.transactionsRoot = bytes32(_random()); |
| 112 | + b.receiptsRoot = bytes32(_random()); |
74 | 113 | } |
75 | | - if (selector == this.testVerifyBlockHash.selector) { |
76 | | - cd = new bytes[](1); |
77 | | - cd[0] = abi.encodeWithSelector(this.checkVerifyBlockHash.selector, _ETH_BLOCK_23270177); |
| 114 | + if (_randomChance(2)) { |
| 115 | + for (uint256 i; i < 8; ++i) { |
| 116 | + b.logsBloom[i] = bytes32(_random()); |
| 117 | + } |
| 118 | + } |
| 119 | + if (_randomChance(2)) { |
| 120 | + b.difficultyOrPrevrandao = bytes32(_random()); |
| 121 | + b.number = _random(); |
| 122 | + b.gasLimit = _random(); |
| 123 | + b.gasUsed = _random(); |
| 124 | + b.timestamp = _random(); |
| 125 | + b.extraData = _truncateBytes(_randomBytes(), 32); |
| 126 | + b.mixHash = bytes32(_random()); |
| 127 | + b.nonce = bytes8(bytes32(_random())); |
78 | 128 | } |
79 | | - } |
80 | 129 |
|
81 | | - function checkToShortHeader(bytes calldata h) public { |
82 | | - ShortHeader memory expected = ShortHeader({ |
83 | | - parentHash: 0x1581f4448b16694d5a728161cd65f8c80b88f5352a6f5bd2d2315b970582958d, |
84 | | - stateRoot: 0x10d2afa5dabcf2dbfe3aa82b758427938e07880bd6fef3c82c404d0dd7c3f0f3, |
85 | | - transactionsRoot: 0xf81230c715a462c827898bf2e337982907a7af90e5be20f911785bda05dab93c, |
86 | | - receiptsRoot: 0x740f11bc75cf25e40d78d892d2e03083eaa573e5b4c26913fcc1b833db854c94, |
87 | | - logsBloom: [ |
88 | | - bytes32(0x85f734fb06ea8fe377abbcb2e27f9ac99751ba817dc327327db101fd76f964ed), // lol |
89 | | - 0x0b7ca161f148fc165b9e5b575dc7473f17f4b8ebbf4a7b02b3e1e642197f27b2, |
90 | | - 0xaf54680834449abaf833619ac7d18afb50b19d5f6944dca0dc952edfdd983757, |
91 | | - 0x3783c339ee6a36353ce6e536eaaf29fcd569c426091d4e24568dc353347f98c7, |
92 | | - 0x4fb6f8c91d68d358467c437563f66566377fe6c3f9e8301dbeb5fc7e7adee7a8, |
93 | | - 0x5ef5f8fa905cedbaf26601e21ba91646cac4034601e51d889d49739ee6990943, |
94 | | - 0xa6a41927660f68e1f50b9f9209ee29551a7dae478d88e0547eefc83334ea770b, |
95 | | - 0xb6fbac620fc47479c2c59389622bf32f55e36a75e56a5fc47c38bf8ef211fc0e |
96 | | - ] |
97 | | - }); |
98 | | - |
99 | | - ShortHeader memory actual = BlockHashLib.toShortHeader(h); |
100 | | - assertEq(actual.parentHash, expected.parentHash, "parentHash"); |
101 | | - assertEq(actual.stateRoot, expected.stateRoot, "stateRoot"); |
102 | | - assertEq(actual.transactionsRoot, expected.transactionsRoot, "transactionsRoot"); |
103 | | - assertEq(actual.receiptsRoot, expected.receiptsRoot, "receiptsRoot"); |
104 | | - assertEq( |
105 | | - keccak256(abi.encodePacked(actual.logsBloom)), |
106 | | - keccak256(abi.encodePacked(expected.logsBloom)), |
107 | | - "logsBloom" |
108 | | - ); |
| 130 | + LibRLP.List memory l; |
| 131 | + l.p(abi.encodePacked(b.parentHash)); |
| 132 | + l.p(abi.encodePacked(b.ommersHash)); |
| 133 | + l.p(abi.encodePacked(b.beneficiary)); |
| 134 | + l.p(abi.encodePacked(b.stateRoot)); |
| 135 | + l.p(abi.encodePacked(b.transactionsRoot)); |
| 136 | + l.p(abi.encodePacked(b.receiptsRoot)); |
| 137 | + l.p(abi.encodePacked(b.logsBloom)); |
| 138 | + l.p(abi.encodePacked(b.difficultyOrPrevrandao)); |
| 139 | + l.p(b.number); |
| 140 | + l.p(b.gasLimit); |
| 141 | + l.p(b.gasUsed); |
| 142 | + l.p(b.timestamp); |
| 143 | + l.p(b.extraData); |
| 144 | + l.p(abi.encodePacked(b.mixHash)); |
| 145 | + l.p(abi.encodePacked(b.nonce)); |
| 146 | + encoded = l.encode(); |
109 | 147 | } |
110 | 148 |
|
111 | | - function checkVerifyBlockHash(bytes calldata h) public { |
112 | | - vm.roll(23270177 + 1); |
113 | | - vm.setBlockhash(23270177, _ETH_BLOCK_HASH_23270177); |
114 | | - assertEq(BlockHashLib.verifyBlockHash(h, 23270177), _ETH_BLOCK_HASH_23270177); |
| 149 | + function testToShortHeader(bytes32) public { |
| 150 | + (BlockHeader memory b, bytes memory encoded) = _randomBlockHeader(); |
| 151 | + BlockHashLib.ShortHeader memory s = |
| 152 | + this.toShortHeader(_truncateBytes(_randomBytes(), 128), encoded); |
| 153 | + assertEq(s.parentHash, b.parentHash); |
| 154 | + assertEq(s.stateRoot, b.stateRoot); |
| 155 | + assertEq(s.transactionsRoot, b.transactionsRoot); |
| 156 | + assertEq(s.receiptsRoot, b.receiptsRoot); |
| 157 | + for (uint256 i; i < 8; ++i) { |
| 158 | + assertEq(s.logsBloom[i], b.logsBloom[i]); |
| 159 | + } |
115 | 160 | } |
116 | 161 |
|
117 | | - function testToShortHeader() public view {} |
| 162 | + function toShortHeader(bytes calldata, bytes calldata encodedHeader) |
| 163 | + public |
| 164 | + view |
| 165 | + returns (BlockHashLib.ShortHeader memory result) |
| 166 | + { |
| 167 | + _misalignFreeMemoryPointer(); |
| 168 | + _brutalizeMemory(); |
| 169 | + result = BlockHashLib.toShortHeader(encodedHeader); |
| 170 | + _checkMemory(); |
| 171 | + } |
118 | 172 |
|
119 | | - function testVerifyBlockHash() public view {} |
| 173 | + function testRandomBlockHeader(bytes32) public { |
| 174 | + (, bytes memory encoded) = _randomBlockHeader(); |
| 175 | + assertEq(uint8(bytes1(encoded[0])), 0xf9); |
| 176 | + } |
120 | 177 | } |
0 commit comments