mirror of
https://github.com/ethereum/consensus-specs.git
synced 2026-02-02 07:05:04 -05:00
* Refactor setup.py * Update doc with the new file path * Rearrange spec_builders * Update doc
7.7 KiB
7.7 KiB
How to add a new feature proposal in consensus-specs
Table of Contents
A. Make it executable for linter checks
1. Create a folder under ./specs/_features
For example, if it's an EIP-9999 CL spec, you can create a ./specs/_features/eip9999 folder.
2. Choose the "previous fork" to extend: usually, use the scheduled or the latest mainnet fork version.
For example, if the latest fork is Capella, use ./specs/capella content as your "previous fork".
3. Write down your proposed beacon-chain.md change
- You can either use Beacon Chain Spec Template, or make a copy of the latest fork content and then edit it.
- Tips:
- We use
doctoctool to generate the table of content.cd consensus-specs doctoc specs - The differences between "Constants", "Configurations", and "Presets":
- Constants: The constant that should never be changed.
- Configurations: The settings that we may change for different networks.
- Presets: The settings that we may change for testing.
- Readability and simplicity are more important than efficiency and optimization.
- Use simple Python rather than the fancy Python dark magic.
- We use
4. Add fork.md
You can refer to the previous fork's fork.md file.
5. Make it executable
- Update Pyspec
constants.pywith the new feature name. - Update helpers for
setup.pyfor building the spec:- Update
pysetup/constants.pywith the new feature name as Pyspecconstants.pydefined. - Update
pysetup/spec_builders/__init__.py. Implement a new<FEATURE_NAME>SpecBuilderinpysetup/spec_builders/<FEATURE_NAME>.pywith the new feature name. e.g.,EIP9999SpecBuilder. Append it to thespec_builderslist. - Update
pysetup/md_doc_paths.py: add the path of the new markdown files inget_md_doc_pathsfunction if needed.
- Update
B: Make it executable for pytest and test generator
1. [Optional] Add light-client/* docs if you updated the content of BeaconBlock
- You can refer to the previous fork's
light-client/*file. - Add the path of the new markdown files in
pysetup/md_doc_paths.py'sget_md_doc_pathsfunction.
2. Add the mainnet and minimal presets and update the configs
- Add presets:
presets/mainnet/<new-feature-name>.yamlandpresets/minimal/<new-feature-name>.yaml - Update configs:
configs/mainnet.yamlandconfigs/minimal.yaml
3. Update context.py
- Update
spec_targetsby adding<NEW_FEATURE>
from eth2spec.eip9999 import mainnet as spec_eip9999_mainnet, minimal as spec_eip9999_minimal
...
spec_targets: Dict[PresetBaseName, Dict[SpecForkName, Spec]] = {
MINIMAL: {
...
EIP9999: spec_eip9999_minimal,
},
MAINNET: {
...
EIP9999: spec_eip9999_mainnet
},
}
4. Update constants.py
- Add
<NEW_FEATURE>toALL_PHASESandTESTGEN_FORKS
5. Update genesis.py:
We use create_genesis_state to create the default state in tests.
- Update
create_genesis_stateby addingfork_versionsetting:
def create_genesis_state(spec, validator_balances, activation_threshold):
...
if spec.fork == ALTAIR:
current_version = spec.config.ALTAIR_FORK_VERSION
...
elif spec.fork == EIP9999:
# Add the previous fork version of given fork
previous_version = spec.config.<PREVIOUS_FORK_VERSION>
current_version = spec.config.EIP9999_FORK_VERSION
- If the given feature changes
BeaconStatefields, you have to set the initial values by adding:
def create_genesis_state(spec, validator_balances, activation_threshold):
...
if is_post_eip9999(spec):
state.<NEW_FIELD> = <value>
return state
- If the given feature changes
ExecutionPayloadfields, you have to set the initial values by updatingget_sample_genesis_execution_payload_headerhelper.
6. To add fork transition tests, update fork_transition.py
def do_fork(state, spec, post_spec, fork_epoch, with_block=True, sync_aggregate=None, operation_dict=None):
...
if post_spec.fork == ALTAIR:
state = post_spec.upgrade_to_altair(state)
...
elif post_spec.fork == EIP9999:
state = post_spec.upgrade_to_eip9999(state)
...
if post_spec.fork == ALTAIR:
assert state.fork.previous_version == post_spec.config.GENESIS_FORK_VERSION
assert state.fork.current_version == post_spec.config.ALTAIR_FORK_VERSION
...
elif post_spec.fork == EIP9999:
assert state.fork.previous_version == post_spec.config.<PREVIOUS_FORK_VERSION>
assert state.fork.current_version == post_spec.config.EIP9999_FORK_VERSION
...
7. Update CI configurations
- Update GitHub Actions config
- Update
pyspec-tests.strategy.matrix.versionlist by adding new feature to it
- Update
- Update CircleCI config
- Add new job to the
workflows.test_spec.jobs
- Add new job to the
Others
Bonus
- Add
validator.mdif honest validator behavior changes with the new feature.
Need help?
You can tag spec elves for cleaning up your PR. 🧚