-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
165 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,119 @@ | ||
# Blockchain Hive Tests | ||
|
||
The Blockchain Hive Test fixture format tests are included in subdirectory `blockchain_tests_hive`, use Engine API directives instead of the usual BlockchainTest format. | ||
The Blockchain Hive Test fixture format tests are included in the fixtures subdirectory `blockchain_tests_hive`, and use Engine API directives instead of the usual BlockchainTest format. | ||
|
||
These are produced by the `StateTest` and `BlockchainTest` test specs. | ||
|
||
## Structure | ||
## Description | ||
|
||
A single JSON fixture file is composed of a JSON object where each key is a different test vector, with the key string representing the test name. | ||
The Blockchain Hive Test fixture format is used to test block validation and the consensus rules of the Ethereum blockchain, when a block is delivered through the Engine API as a `engine_newPayloadVX` directive. | ||
|
||
It does so by defining a pre-execution state, a series of blocks as `engine_newPayloadVX` directives, and a post-execution state, verifying that, after all the blocks have been processed, appended if valid or rejected if invalid, the result is the expected post-execution state. | ||
|
||
## How Test Fixtures are Consumed via Hive Simulators | ||
A single JSON fixture file is composed of a JSON object where each key-value pair is a different [`Fixture`](#fixture) test object, with the key string representing the test name. | ||
|
||
There are two Hive simulators that execute the test cases defined in the JSON test fixtures against fully instantiated client instances using the @ethereum/execution-apis: | ||
The JSON file path plus the test name are used as the unique test identifier. | ||
|
||
1. The `ethereum/pyspec` simulator executes the test cases against a fully instantiated execution client that executes blocks via the [`engine_newPayloadVX`](https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#engine_newpayloadv1) method. Each block is verified by the client and tested against the `engine_newPayloadVX` response. The post-state section of the test is additionally explicitly verified via `eth_getStorageAt` and `eth_getBalance` alongside an internal nonce checking method. Note, this simulator only works for post-merge forks. | ||
2. The `ethereum/consensus` simulator executes the test cases by importing the RLP-encoded blocks to the execution client upon start-up on the command-line. The pre-state of `block[0]` and the post-state of `block[n]` are verified using the standard [Execution JSON-RPC API](https://ethereum.github.io/execution-apis/api-documentation), for example with `eth_getBlockByNumber`. This simulator works for all forks. | ||
|
||
Both of these methods only support test fixtures in the blockchain test format (but any state test can be expressed as blockchain test consisting of 1 block with 1 transaction). | ||
## Consumption Procedure | ||
|
||
For each [`HiveFixture`](#hivefixture) test object in the JSON fixture file, perform the following steps: | ||
|
||
1. Start a full node using: | ||
- [`network`](#-network) to configure the execution fork schedule according to the [`Fork`](./common_types.md#fork) type definition | ||
- [`pre`](#-pre-alloc) as the starting state allocation of the execution environment for the test and calculate the genesis state root | ||
- [`genesisBlockHeader`](#-genesisblockheader-fixtureheader) as the genesis block header | ||
2. Verify the head of the chain is the genesis block, and the state root matches the one calculated on step 1, otherwise fail the test | ||
3. For each [`FixtureEngineNewPayload`](#fixtureenginenewpayload) in [`engineNewPayloads`](#-enginenewpayloads-listfixtureenginenewpayload): | ||
1. Deliver the payload using the `engine_newPayloadVX` directive, using: | ||
- [`version`](#-version-number) as the version of the directive | ||
- [`executionPayload`](#-executionpayload-fixtureexecutionpayload) as the payload | ||
- [`blob_versioned_hashes`](#-blob_versioned_hashes-listhash--null), if not `null`, as the list of hashes of the versioned blobs that are part of the execution payload | ||
- [`parentBeaconBlockRoot`](#-parentbeaconblockroot-hash--null), if not `null`, as the hash of the parent beacon block root | ||
2. If [`errorCode`](#-errorcode-number) is not `null`: | ||
- Verify the directive returns an error, and the error code matches the one in [`errorCode`](#-errorcode-number), otherwise fail the test | ||
- Proceed to the next payload | ||
3. If [`valid`](#-valid) is `false`, verify that the directive returns `status` field of [PayloadStatusV1](https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#payloadstatusv1) as `INVALID`, otherwise fail the test | ||
4. If [`valid`](#-valid) is `true`, verify that the directive returns `status` field of [PayloadStatusV1](https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#payloadstatusv1) as `VALID`, otherwise fail the test | ||
|
||
## Structures | ||
|
||
### `HiveFixture`: `Mapping` | ||
|
||
#### - `network`: [`Fork`](./common_types.md#fork) | ||
Fork configuration for the test. | ||
#### - `genesisBlockHeader`: [`FixtureHeader`](./blockchain_test.md#fixtureheader) | ||
Genesis block header. | ||
#### - `engineNewPayloads`: `List[`[`FixtureEngineNewPayload`](#fixtureenginenewpayload)`]` | ||
List of `engine_newPayloadVX` directives to be processed after the genesis block. | ||
#### - `engineFcuVersion`: [`Number`](./common_types.md#number) | ||
Version of the `engine_forkchoiceUpdatedVX` directive to use to set the head of the chain. | ||
#### - `pre`: [`Alloc`](./common_types.md#alloc) | ||
Starting account allocation for the test. State root calculated from this allocation must match the one in the genesis block. | ||
#### - `post`: [`Alloc`](./common_types.md#alloc) | ||
Account allocation for verification after all the blocks have been processed. | ||
|
||
### `FixtureEngineNewPayload`: `Mapping` | ||
|
||
#### - `executionPayload`: [`FixtureExecutionPayload`](#fixtureexecutionpayload) | ||
Execution payload. | ||
#### - `blob_versioned_hashes`: `List[`[`Hash`](./common_types.md#hash)`] | null` `(fork: Cancun)` | ||
List of hashes of the versioned blobs that are part of the execution payload. | ||
They can mismatch the hashes of the versioned blobs in the execution payload, for negative-testing reasons. | ||
#### - `parentBeaconBlockRoot`: [`Hash`](./common_types.md#hash)` | null` `(fork: Cancun)` | ||
Hash of the parent beacon block root. | ||
#### - `valid`: `bool` (To be deprecated) | ||
Whether the execution payload is valid or not. Expectation is `VALID` if `true`, `INVALID` if `false`, in the `status` field of [PayloadStatusV1](https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#payloadstatusv1). | ||
#### - `version`: [`Number`](./common_types.md#number) | ||
Version of the `engine_newPayloadVX` directive to use to deliver the payload. | ||
#### - `errorCode`: [`Number`](./common_types.md#number)` | null` | ||
Error code to be returned by the `engine_newPayloadVX` directive. | ||
|
||
|
||
### `FixtureExecutionPayload` | ||
|
||
#### - `parentHash`: [`Hash`](./common_types.md#hash) | ||
Hash of the parent block. | ||
#### - `feeRecipient`: [`Address`](./common_types.md#address) | ||
Address of the account that will receive the rewards for building the block. | ||
#### - `stateRoot`: [`Hash`](./common_types.md#hash) | ||
Root hash of the state trie. | ||
#### - `receiptsRoot`: [`Hash`](./common_types.md#hash) | ||
Root hash of the receipts trie. | ||
#### - `logsBloom`: [`Bloom`](./common_types.md#bloom) | ||
Bloom filter composed of the logs of all the transactions in the block. | ||
#### - `blockNumber`: [`HexNumber`](./common_types.md#hexnumber) | ||
Number of the block. | ||
#### - `gasLimit`: [`HexNumber`](./common_types.md#hexnumber) | ||
Total gas limit of the block. | ||
#### - `gasUsed`: [`HexNumber`](./common_types.md#hexnumber) | ||
Total gas used by all the transactions in the block. | ||
#### - `timestamp`: [`HexNumber`](./common_types.md#hexnumber) | ||
Timestamp of the block. | ||
#### - `extraData`: [`Bytes`](./common_types.md#bytes) | ||
Extra data of the block. | ||
#### - `prevRandao`: [`Hash`](./common_types.md#hash) | ||
PrevRandao of the block. | ||
#### - `blockHash`: [`Hash`](./common_types.md#hash) | ||
Hash of the block. | ||
#### - `transactions`: `List[`[`Bytes`](./common_types.md#bytes)`]` | ||
List of transactions in the block, in serialized format. | ||
#### - `withdrawals`: `List[`[`FixtureWithdrawal`](#fixturewithdrawal)`]` | ||
List of withdrawals in the block. | ||
|
||
#### - `baseFeePerGas`: [`HexNumber`](./common_types.md#hexnumber) `(fork: London)` | ||
Base fee per gas of the block. | ||
#### - `blobGasUsed`: [`HexNumber`](./common_types.md#hexnumber) `(fork: Cancun)` | ||
Total blob gas used by all the transactions in the block. | ||
#### - `excessBlobGas`: [`HexNumber`](./common_types.md#hexnumber) `(fork: Cancun)` | ||
Excess blob gas of the block used to calculate the blob fee per gas for this block. | ||
|
||
### `FixtureWithdrawal` | ||
#### - `index`: [`HexNumber`](./common_types.md#hexnumber) | ||
Index of the withdrawal | ||
#### - `validatorIndex`: [`HexNumber`](./common_types.md#hexnumber) | ||
Withdrawing validator index | ||
#### - `address`: [`Address`](./common_types.md#address) | ||
Address to withdraw to | ||
#### - `amount`: [`HexNumber`](./common_types.md#hexnumber) | ||
Amount of the withdrawal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters