mirror of
https://github.com/ethereum/consensus-specs.git
synced 2026-02-02 19:44:55 -05:00
Merge branch 'dev' into JustinDrake-patch-13
This commit is contained in:
@@ -1246,7 +1246,7 @@ def state_transition(state: BeaconState, block: BeaconBlock, validate_state_root
|
||||
|
||||
```python
|
||||
def process_slots(state: BeaconState, slot: Slot) -> None:
|
||||
assert state.slot < slot
|
||||
assert state.slot <= slot
|
||||
while state.slot < slot:
|
||||
process_slot(state)
|
||||
# Process epoch on the first slot of the next epoch
|
||||
@@ -1705,7 +1705,7 @@ def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSla
|
||||
slashed_any = False
|
||||
attesting_indices_1 = attestation_1.custody_bit_0_indices + attestation_1.custody_bit_1_indices
|
||||
attesting_indices_2 = attestation_2.custody_bit_0_indices + attestation_2.custody_bit_1_indices
|
||||
for index in set(attesting_indices_1).intersection(attesting_indices_2):
|
||||
for index in sorted(set(attesting_indices_1).intersection(attesting_indices_2)):
|
||||
if is_slashable_validator(state.validator_registry[index], get_current_epoch(state)):
|
||||
slash_validator(state, index)
|
||||
slashed_any = True
|
||||
@@ -1772,7 +1772,8 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
|
||||
amount = deposit.data.amount
|
||||
validator_pubkeys = [v.pubkey for v in state.validator_registry]
|
||||
if pubkey not in validator_pubkeys:
|
||||
# Verify the deposit signature (proof of possession)
|
||||
# Verify the deposit signature (proof of possession).
|
||||
# Invalid signatures are allowed by the deposit contract, and hence included on-chain, but must not be processed.
|
||||
# Note: deposits are valid across forks, hence the deposit domain is retrieved directly from `bls_domain`
|
||||
if not bls_verify(
|
||||
pubkey, signing_root(deposit.data), deposit.data.signature, bls_domain(DOMAIN_DEPOSIT)
|
||||
|
||||
@@ -38,6 +38,16 @@
|
||||
- [`get_chunk_bits_root`](#get_chunk_bits_root)
|
||||
- [`get_randao_epoch_for_custody_period`](#get_randao_epoch_for_custody_period)
|
||||
- [`get_validators_custody_reveal_period`](#get_validators_custody_reveal_period)
|
||||
- [`replace_empty_or_append`](#replace_empty_or_append)
|
||||
- [Per-block processing](#per-block-processing)
|
||||
- [Operations](#operations)
|
||||
- [Custody key reveals](#custody-key-reveals)
|
||||
- [Early derived secret reveals](#early-derived-secret-reveals)
|
||||
- [Chunk challenges](#chunk-challenges)
|
||||
- [Bit challenges](#bit-challenges)
|
||||
- [Custody responses](#custody-responses)
|
||||
- [Per-epoch processing](#per-epoch-processing)
|
||||
- [Handling of custody-related deadlines](#handling-of-custody-related-deadlines)
|
||||
|
||||
<!-- /TOC -->
|
||||
|
||||
@@ -289,7 +299,7 @@ def get_randao_epoch_for_custody_period(period: int, validator_index: ValidatorI
|
||||
|
||||
### `get_validators_custody_reveal_period`
|
||||
|
||||
```python
|
||||
```python
|
||||
def get_validators_custody_reveal_period(state: BeaconState,
|
||||
validator_index: ValidatorIndex,
|
||||
epoch: Epoch=None) -> int:
|
||||
@@ -370,7 +380,7 @@ def process_custody_key_reveal(state: BeaconState,
|
||||
increase_balance(state, proposer_index, base_reward(state, index) // MINOR_REWARD_QUOTIENT)
|
||||
```
|
||||
|
||||
##### Early derived secret reveals
|
||||
#### Early derived secret reveals
|
||||
|
||||
Verify that `len(block.body.early_derived_secret_reveals) <= MAX_EARLY_DERIVED_SECRET_REVEALS`.
|
||||
|
||||
@@ -692,25 +702,3 @@ Append this to `process_final_updates(state)`:
|
||||
if validator.exit_epoch != FAR_FUTURE_EPOCH and validator.withdrawable_epoch == FAR_FUTURE_EPOCH:
|
||||
validator.withdrawable_epoch = validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
|
||||
```
|
||||
|
||||
In `process_penalties_and_exits`, change the definition of `eligible` to the following (note that it is not a pure function because `state` is declared in the surrounding scope):
|
||||
|
||||
```python
|
||||
def eligible(state: BeaconState, index: ValidatorIndex) -> bool:
|
||||
validator = state.validator_registry[index]
|
||||
# Cannot exit if there are still open chunk challenges
|
||||
if len([record for record in state.custody_chunk_challenge_records if record.responder_index == index]) > 0:
|
||||
return False
|
||||
# Cannot exit if there are still open bit challenges
|
||||
if len([record for record in state.custody_bit_challenge_records if record.responder_index == index]) > 0:
|
||||
return False
|
||||
# Cannot exit if you have not revealed all of your custody keys
|
||||
elif validator.next_custody_reveal_period <= get_validators_custody_reveal_period(state, index, validator.exit_epoch):
|
||||
return False
|
||||
# Cannot exit if you already have
|
||||
elif validator.withdrawable_epoch < FAR_FUTURE_EPOCH:
|
||||
return False
|
||||
# Return minimum time
|
||||
else:
|
||||
return current_epoch >= validator.exit_epoch + MIN_VALIDATOR_WITHDRAWAL_EPOCHS
|
||||
```
|
||||
|
||||
@@ -215,7 +215,7 @@ def get_shard_header(block: ShardBlock) -> ShardBlockHeader:
|
||||
def verify_shard_attestation_signature(state: BeaconState,
|
||||
attestation: ShardAttestation) -> None:
|
||||
data = attestation.data
|
||||
persistent_committee = get_persistent_committee(state, data.crosslink.shard, data.slot)
|
||||
persistent_committee = get_persistent_committee(state, data.shard, data.slot)
|
||||
assert verify_bitfield(attestation.aggregation_bitfield, len(persistent_committee))
|
||||
pubkeys = []
|
||||
for i, index in enumerate(persistent_committee):
|
||||
@@ -225,7 +225,7 @@ def verify_shard_attestation_signature(state: BeaconState,
|
||||
pubkeys.append(validator.pubkey)
|
||||
assert bls_verify(
|
||||
pubkey=bls_aggregate_pubkeys(pubkeys),
|
||||
message_hash=data.crosslink.shard_block_root,
|
||||
message_hash=data.shard_block_root,
|
||||
signature=attestation.aggregate_signature,
|
||||
domain=get_domain(state, slot_to_epoch(data.slot), DOMAIN_SHARD_ATTESTER)
|
||||
)
|
||||
@@ -280,22 +280,22 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock],
|
||||
return True
|
||||
|
||||
# Check slot number
|
||||
assert block.slot >= PHASE_1_GENESIS_SLOT
|
||||
assert candidate.slot >= PHASE_1_GENESIS_SLOT
|
||||
assert unix_time >= beacon_state.genesis_time + (block.slot - GENESIS_SLOT) * SECONDS_PER_SLOT
|
||||
|
||||
# Check shard number
|
||||
assert block.shard <= SHARD_COUNT
|
||||
assert candidate.shard <= SHARD_COUNT
|
||||
|
||||
# Check beacon block
|
||||
beacon_block = beacon_blocks[block.slot]
|
||||
assert block.beacon_block_root == signing_root(beacon_block)
|
||||
assert beacon_block.slot <= block.slot:
|
||||
beacon_block = beacon_blocks[candidate.slot]
|
||||
assert candidate.beacon_block_root == signing_root(beacon_block)
|
||||
assert beacon_block.slot <= candidate.slot:
|
||||
|
||||
# Check state root
|
||||
assert block.state_root == ZERO_HASH # [to be removed in phase 2]
|
||||
assert candidate.state_root == ZERO_HASH # [to be removed in phase 2]
|
||||
|
||||
# Check parent block
|
||||
if block.slot == PHASE_1_GENESIS_SLOT:
|
||||
if candidate.slot == PHASE_1_GENESIS_SLOT:
|
||||
assert candidate.parent_root == ZERO_HASH
|
||||
else:
|
||||
parent_block = next(
|
||||
@@ -303,26 +303,26 @@ def is_valid_shard_block(beacon_blocks: List[BeaconBlock],
|
||||
signing_root(block) == candidate.parent_root
|
||||
, None)
|
||||
assert parent_block != None
|
||||
assert parent_block.shard == block.shard
|
||||
assert parent_block.slot < block.slot
|
||||
assert parent_block.shard == candidate.shard
|
||||
assert parent_block.slot < candidate.slot
|
||||
assert signing_root(beacon_blocks[parent_block.slot]) == parent_block.beacon_chain_root
|
||||
|
||||
# Check attestations
|
||||
assert len(block.attestations) <= MAX_SHARD_ATTESTIONS
|
||||
for _, attestation in enumerate(block.attestations):
|
||||
assert max(GENESIS_SHARD_SLOT, block.slot - SLOTS_PER_EPOCH) <= attestation.data.slot
|
||||
assert attestation.data.slot <= block.slot - MIN_ATTESTATION_INCLUSION_DELAY
|
||||
assert attestation.data.crosslink.shard == block.shard
|
||||
assert len(candidate.attestations) <= MAX_SHARD_ATTESTIONS
|
||||
for _, attestation in enumerate(candidate.attestations):
|
||||
assert max(GENESIS_SHARD_SLOT, candidate.slot - SLOTS_PER_EPOCH) <= attestation.data.slot
|
||||
assert attestation.data.slot <= candidate.slot - MIN_ATTESTATION_INCLUSION_DELAY
|
||||
assert attestation.data.crosslink.shard == candidate.shard
|
||||
verify_shard_attestation_signature(beacon_state, attestation)
|
||||
|
||||
# Check signature
|
||||
proposer_index = get_shard_proposer_index(beacon_state, block.shard, block.slot)
|
||||
proposer_index = get_shard_proposer_index(beacon_state, candidate.shard, candidate.slot)
|
||||
assert proposer_index is not None
|
||||
assert bls_verify(
|
||||
pubkey=validators[proposer_index].pubkey,
|
||||
message_hash=signing_root(block),
|
||||
signature=block.signature,
|
||||
domain=get_domain(beacon_state, slot_to_epoch(block.slot), DOMAIN_SHARD_PROPOSER)
|
||||
signature=candidate.signature,
|
||||
domain=get_domain(beacon_state, slot_to_epoch(candidate.slot), DOMAIN_SHARD_PROPOSER)
|
||||
)
|
||||
|
||||
return True
|
||||
@@ -339,18 +339,18 @@ Let:
|
||||
```python
|
||||
def is_valid_shard_attestation(valid_shard_blocks: List[ShardBlock],
|
||||
beacon_state: BeaconState,
|
||||
candidate: Attestation) -> bool:
|
||||
candidate: ShardAttestation) -> bool:
|
||||
# Check shard block
|
||||
shard_block = next(
|
||||
block for block in valid_shard_blocks if
|
||||
signing_root(block) == candidate.attestation.data.crosslink.shard_block_root
|
||||
signing_root(block) == candidate.data.shard_block_root
|
||||
, None)
|
||||
assert shard_block != None
|
||||
assert shard_block.slot == attestation.data.slot
|
||||
assert shard_block.shard == attestation.data.crosslink.shard
|
||||
assert shard_block.slot == candidate.data.slot
|
||||
assert shard_block.shard == candidate.data.shard
|
||||
|
||||
# Check signature
|
||||
verify_shard_attestation_signature(beacon_state, attestation)
|
||||
verify_shard_attestation_signature(beacon_state, candidate)
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
@@ -186,6 +186,18 @@ To prevent parsing of hundreds of different YAML files to test a specific test t
|
||||
... <--- more test types
|
||||
```
|
||||
|
||||
## Common test-case properties
|
||||
|
||||
Some test-case formats share some common key-value pair patterns, and these are documented here:
|
||||
|
||||
```
|
||||
bls_setting: int -- optional, can have 3 different values:
|
||||
0: (default, applies if key-value pair is absent). Free to choose either BLS ON or OFF.
|
||||
Tests are generated with valid BLS data in this case,
|
||||
but there is no change of outcome when running the test if BLS is ON or OFF.
|
||||
1: known as "BLS required" - if the test validity is strictly dependent on BLS being ON
|
||||
2: known as "BLS ignored" - if the test validity is strictly dependent on BLS being OFF
|
||||
```
|
||||
|
||||
## Note for implementers
|
||||
|
||||
|
||||
29
specs/test_formats/epoch_processing/README.md
Normal file
29
specs/test_formats/epoch_processing/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Epoch processing tests
|
||||
|
||||
The different epoch sub-transitions are tested individually with test handlers.
|
||||
The format is similar to block-processing state-transition tests.
|
||||
There is no "change" factor however, the transitions are pure functions with just the pre-state as input.
|
||||
Hence, the format is shared between each test-handler. (See test condition documentation on how to run the tests.)
|
||||
|
||||
## Test case format
|
||||
|
||||
```yaml
|
||||
description: string -- description of test case, purely for debugging purposes
|
||||
bls_setting: int -- see general test-format spec.
|
||||
pre: BeaconState -- state before running the sub-transition
|
||||
post: BeaconState -- state after applying the epoch sub-transition.
|
||||
```
|
||||
|
||||
## Condition
|
||||
|
||||
A handler of the `epoch_processing` test-runner should process these cases,
|
||||
calling the corresponding processing implementation.
|
||||
|
||||
Sub-transitions:
|
||||
|
||||
| *`sub-transition-name`* | *`processing call`* |
|
||||
|-------------------------|-----------------------------------|
|
||||
| `crosslinks` | `process_crosslinks(state)` |
|
||||
| `registry_updates` | `process_registry_updates(state)` |
|
||||
|
||||
The resulting state should match the expected `post` state.
|
||||
@@ -2,9 +2,34 @@
|
||||
|
||||
The different kinds of operations ("transactions") are tested individually with test handlers.
|
||||
|
||||
The tested operation kinds are:
|
||||
- [`deposits`](./deposits.md)
|
||||
- More tests are work-in-progress.
|
||||
## Test case format
|
||||
|
||||
```yaml
|
||||
description: string -- description of test case, purely for debugging purposes
|
||||
bls_setting: int -- see general test-format spec.
|
||||
pre: BeaconState -- state before applying the operation
|
||||
<operation-name>: <operation-object> -- the YAML encoded operation, e.g. a "ProposerSlashing", or "Deposit".
|
||||
post: BeaconState -- state after applying the operation. No value if operation processing is aborted.
|
||||
```
|
||||
|
||||
## Condition
|
||||
|
||||
A handler of the `operations` test-runner should process these cases,
|
||||
calling the corresponding processing implementation.
|
||||
|
||||
Operations:
|
||||
|
||||
| *`operation-name`* | *`operation-object`* | *`input name`* | *`processing call`* |
|
||||
|-------------------------|----------------------|----------------------|--------------------------------------------------------|
|
||||
| `attestation` | `Attestation` | `attestation` | `process_attestation(state, attestation)` |
|
||||
| `attester_slashing` | `AttesterSlashing` | `attester_slashing` | `process_attester_slashing(state, attester_slashing)` |
|
||||
| `block_header` | `Block` | `block` | `process_block_header(state, block)` |
|
||||
| `deposit` | `Deposit` | `deposit` | `process_deposit(state, deposit)` |
|
||||
| `proposer_slashing` | `ProposerSlashing` | `proposer_slashing` | `process_proposer_slashing(state, proposer_slashing)` |
|
||||
| `transfer` | `Transfer` | `transfer` | `process_transfer(state, transfer)` |
|
||||
| `voluntary_exit` | `VoluntaryExit` | `voluntary_exit` | `process_voluntary_exit(state, voluntary_exit)` |
|
||||
|
||||
Note that `block_header` is not strictly an operation (and is a full `Block`), but processed in the same manner, and hence included here.
|
||||
|
||||
The resulting state should match the expected `post` state, or if the `post` state is left blank,
|
||||
the handler should reject the input operation as invalid.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Test format: Deposit operations
|
||||
|
||||
A deposit is a form of an operation (or "transaction"), modifying the state.
|
||||
|
||||
## Test case format
|
||||
|
||||
```yaml
|
||||
description: string -- description of test case, purely for debugging purposes
|
||||
pre: BeaconState -- state before applying the deposit
|
||||
deposit: Deposit -- the deposit
|
||||
post: BeaconState -- state after applying the deposit. No value if deposit processing is aborted.
|
||||
```
|
||||
|
||||
## Condition
|
||||
|
||||
A `deposits` handler of the `operations` should process these cases,
|
||||
calling the implementation of the `process_deposit(state, deposit)` functionality described in the spec.
|
||||
The resulting state should match the expected `post` state, or if the `post` state is left blank, the handler should reject the inputs as invalid.
|
||||
7
specs/test_formats/sanity/README.md
Normal file
7
specs/test_formats/sanity/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Sanity tests
|
||||
|
||||
The aim of the sanity tests is to set a base-line on what really needs to pass, i.e. the essentials.
|
||||
|
||||
There are two handlers, documented individually:
|
||||
- [`slots`](./slots.md): transitions of one or more slots (and epoch transitions within)
|
||||
- [`blocks`](./blocks.md): transitions triggered by one or more blocks
|
||||
18
specs/test_formats/sanity/blocks.md
Normal file
18
specs/test_formats/sanity/blocks.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Sanity blocks testing
|
||||
|
||||
Sanity tests to cover a series of one or more blocks being processed, aiming to cover common changes.
|
||||
|
||||
## Test case format
|
||||
|
||||
```yaml
|
||||
description: string -- description of test case, purely for debugging purposes
|
||||
bls_setting: int -- see general test-format spec.
|
||||
pre: BeaconState -- state before running through the transitions triggered by the blocks.
|
||||
blocks: [BeaconBlock] -- blocks to process, in given order, following the main transition function (i.e. process slot and epoch transitions in between blocks as normal)
|
||||
post: BeaconState -- state after applying all the transitions triggered by the blocks.
|
||||
```
|
||||
|
||||
## Condition
|
||||
|
||||
The resulting state should match the expected `post` state, or if the `post` state is left blank,
|
||||
the handler should reject the series of blocks as invalid.
|
||||
23
specs/test_formats/sanity/slots.md
Normal file
23
specs/test_formats/sanity/slots.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Sanity slots testing
|
||||
|
||||
Sanity tests to cover a series of one or more empty-slot transitions being processed, aiming to cover common changes.
|
||||
|
||||
## Test case format
|
||||
|
||||
```yaml
|
||||
description: string -- description of test case, purely for debugging purposes
|
||||
bls_setting: int -- see general test-format spec.
|
||||
pre: BeaconState -- state before running through the transitions.
|
||||
slots: N -- amount of slots to process, N being a positive numer.
|
||||
post: BeaconState -- state after applying all the transitions.
|
||||
```
|
||||
|
||||
The transition with pure time, no blocks, is known as `state_transition_to(state, slot)` in the spec.
|
||||
This runs state-caching (pure slot transition) and epoch processing (every E slots).
|
||||
|
||||
To process the data, call `state_transition_to(pre, pre.slot + N)`. And see if `pre` mutated into the equivalent of `post`.
|
||||
|
||||
|
||||
## Condition
|
||||
|
||||
The resulting state should match the expected `post` state.
|
||||
@@ -9,11 +9,11 @@ This test-format ensures these direct serializations are covered.
|
||||
## Test case format
|
||||
|
||||
```yaml
|
||||
type_name: string -- string, object name, formatted as in spec. E.g. "BeaconBlock"
|
||||
value: dynamic -- the YAML-encoded value, of the type specified by type_name.
|
||||
serialized: bytes -- string, SSZ-serialized data, hex encoded, with prefix 0x
|
||||
root: bytes32 -- string, hash-tree-root of the value, hex encoded, with prefix 0x
|
||||
signing_root: bytes32 -- string, signing-root of the value, hex encoded, with prefix 0x. Optional, present if type contains ``signature`` field
|
||||
SomeObjectName: -- key, object name, formatted as in spec. E.g. "BeaconBlock".
|
||||
value: dynamic -- the YAML-encoded value, of the type specified by type_name.
|
||||
serialized: bytes -- string, SSZ-serialized data, hex encoded, with prefix 0x
|
||||
root: bytes32 -- string, hash-tree-root of the value, hex encoded, with prefix 0x
|
||||
signing_root: bytes32 -- string, signing-root of the value, hex encoded, with prefix 0x. Optional, present if type contains ``signature`` field
|
||||
```
|
||||
|
||||
## Condition
|
||||
|
||||
@@ -224,7 +224,7 @@ epoch_signature = bls_sign(
|
||||
|
||||
`block.eth1_data` is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed, `state.latest_eth1_data` is updated, and validator deposits up to this root can be processed. The deposit root can be calculated by calling the `get_deposit_root()` function of the deposit contract using the post-state of the block hash.
|
||||
|
||||
* Let `D` be the set of `Eth1DataVote` objects `vote` in `state.eth1_data_votes` where:
|
||||
* Let `D` be the list of `Eth1DataVote` objects `vote` in `state.eth1_data_votes` where:
|
||||
* `vote.eth1_data.block_hash` is the hash of an Eth 1.0 block that is (i) part of the canonical chain, (ii) >= `ETH1_FOLLOW_DISTANCE` blocks behind the head, and (iii) newer than `state.latest_eth1_data.block_hash`.
|
||||
* `vote.eth1_data.deposit_count` is the deposit count of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`.
|
||||
* `vote.eth1_data.deposit_root` is the deposit root of the Eth 1.0 deposit contract at the block defined by `vote.eth1_data.block_hash`.
|
||||
@@ -233,7 +233,7 @@ epoch_signature = bls_sign(
|
||||
* Let `deposit_root` and `deposit_count` be the deposit root and deposit count of the Eth 1.0 deposit contract in the post-state of the block referenced by `block_hash`
|
||||
* Let `best_vote_data = Eth1Data(block_hash=block_hash, deposit_root=deposit_root, deposit_count=deposit_count)`.
|
||||
* If `D` is nonempty:
|
||||
* Let `best_vote_data` be the `eth1_data` of the member of `D` that has the highest `vote.vote_count`, breaking ties by favoring block hashes with higher associated block height.
|
||||
* Let `best_vote_data` be the `eth1_data` member of `D` that has the highest vote count (`D.count(eth1_data)`), breaking ties by favoring block hashes with higher associated block height.
|
||||
* Set `block.eth1_data = best_vote_data`.
|
||||
|
||||
##### Signature
|
||||
|
||||
28
specs/validator/0_beacon-node-validator-api.md
Normal file
28
specs/validator/0_beacon-node-validator-api.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Ethereum 2.0 Phase 0 -- Beacon Node API for Validator
|
||||
|
||||
__NOTICE__: This document is a work-in-progress for researchers and implementers. This is an accompanying document to [Ethereum 2.0 Phase 0 -- Honest Validator](0_beacon-chain-validator.md) that describes an API exposed by the beacon node, which enables the validator client to participate in the Ethereum 2.0 protocol.
|
||||
|
||||
## Outline
|
||||
|
||||
This document outlines a minimal application programming interface (API) which is exposed by a beacon node for use by a validator client implementation which aims to facilitate [_phase 0_](../../README.md#phase-0) of Ethereum 2.0.
|
||||
|
||||
The API is a REST interface, accessed via HTTP, designed for use as a local communications protocol between binaries. The only supported return data type is currently JSON.
|
||||
|
||||
### Background
|
||||
The beacon node maintains the state of the beacon chain by communicating with other beacon nodes in the Ethereum Serenity network. Conceptually, it does not maintain keypairs that participate with the beacon chain.
|
||||
|
||||
The validator client is a conceptually separate entity which utilizes private keys to perform validator related tasks on the beacon chain, which we call validator "duties". These duties include the production of beacon blocks and signing of attestations.
|
||||
|
||||
Since it is recommended to separate these concerns in the client implementations, we must clearly define the communication between them.
|
||||
|
||||
The goal of this specification is to promote interoperability between beacon nodes and validator clients derived from different projects and to encourage innovation in validator client implementations, independently from beacon node development. For example, the validator client from Lighthouse could communicate with a running instance of the beacon node from Prysm, or a staking pool might create a decentrally managed validator client which utilises the same API.
|
||||
|
||||
This specification is derived from a proposal and discussion on Issues [#1011](https://github.com/ethereum/eth2.0-specs/issues/1011) and [#1012](https://github.com/ethereum/eth2.0-specs/issues/1012)
|
||||
|
||||
|
||||
## Specification
|
||||
|
||||
The API specification has been written in [OpenAPI 3.0](https://swagger.io/docs/specification/about/) and is provided in the [beacon_node_oapi.yaml](beacon_node_oapi.yaml) file alongside this document.
|
||||
|
||||
For convenience, this specification has been uploaded to [SwaggerHub](https://swagger.io/tools/swaggerhub/) at the following URL:
|
||||
[https://app.swaggerhub.com/apis/spble/beacon_node_api_for_validator](https://app.swaggerhub.com/apis/spble/beacon_node_api_for_validator)
|
||||
641
specs/validator/beacon_node_oapi.yaml
Normal file
641
specs/validator/beacon_node_oapi.yaml
Normal file
@@ -0,0 +1,641 @@
|
||||
openapi: "3.0.2"
|
||||
info:
|
||||
title: "Minimal Beacon Node API for Validator"
|
||||
description: "A minimal API specification for the beacon node, which enables a validator to connect and perform its obligations on the Ethereum 2.0 phase 0 beacon chain."
|
||||
version: "0.2.0"
|
||||
license:
|
||||
name: "Apache 2.0"
|
||||
url: "https://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
tags:
|
||||
- name: MinimalSet
|
||||
description: The minimal set of endpoints to enable a working validator implementation.
|
||||
- name: OptionalSet
|
||||
description: Extra endpoints which are nice-to-haves.
|
||||
paths:
|
||||
/node/version:
|
||||
get:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Get version string of the running beacon node."
|
||||
description: "Requests that the beacon node identify information about its implementation in a format similar to a [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3) field."
|
||||
responses:
|
||||
200:
|
||||
description: Request successful
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/version'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
/node/genesis_time:
|
||||
get:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Get the genesis_time parameter from beacon node configuration."
|
||||
description: "Requests the genesis_time parameter from the beacon node, which should be consistent across all beacon nodes that follow the same beacon chain."
|
||||
responses:
|
||||
200:
|
||||
description: Request successful
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/genesis_time'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
|
||||
/node/syncing:
|
||||
get:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Poll to see if the the beacon node is syncing."
|
||||
description: "Requests the beacon node to describe if it's currently syncing or not, and if it is, what block it is up to. This is modelled after the Eth1.0 JSON-RPC eth_syncing call.."
|
||||
responses:
|
||||
200:
|
||||
description: Request successful
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
is_syncing:
|
||||
type: boolean
|
||||
description: "A boolean of whether the node is currently syncing or not."
|
||||
sync_status:
|
||||
$ref: '#/components/schemas/SyncingStatus'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
/node/fork:
|
||||
get:
|
||||
tags:
|
||||
- OptionalSet
|
||||
summary: "Get fork information from running beacon node."
|
||||
description: "Requests the beacon node to provide which fork version it is currently on."
|
||||
responses:
|
||||
200:
|
||||
description: Request successful
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
fork:
|
||||
$ref: '#/components/schemas/Fork'
|
||||
chain_id:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Sometimes called the network id, this number discerns the active chain for the beacon node. Analogous to Eth1.0 JSON-RPC net_version."
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
|
||||
/validator/duties:
|
||||
get:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Get validator duties for the requested validators."
|
||||
description: "Requests the beacon node to provide a set of _duties_, which are actions that should be performed by validators, for a particular epoch. Duties should only need to be checked once per epoch, however a chain reorganization (of > MIN_SEED_LOOKAHEAD epochs) could occur, resulting in a change of duties. For full safety, this API call should be polled at every slot to ensure that chain reorganizations are recognized, and to ensure that the beacon node is properly synchronized."
|
||||
parameters:
|
||||
- name: validator_pubkeys
|
||||
in: query
|
||||
required: true
|
||||
description: "An array of hex-encoded BLS public keys"
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/pubkey'
|
||||
minItems: 1
|
||||
- name: epoch
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: Success response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ValidatorDuty'
|
||||
400:
|
||||
$ref: '#/components/responses/InvalidRequest'
|
||||
406:
|
||||
description: "Duties cannot be provided for the requested epoch."
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
503:
|
||||
$ref: '#/components/responses/CurrentlySyncing'
|
||||
|
||||
/validator/block:
|
||||
get:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Produce a new block, without signature."
|
||||
description: "Requests a beacon node to produce a valid block, which can then be signed by a validator."
|
||||
parameters:
|
||||
- name: slot
|
||||
in: query
|
||||
required: true
|
||||
description: "The slot for which the block should be proposed."
|
||||
schema:
|
||||
type: integer
|
||||
format: uint64
|
||||
- name: randao_reveal
|
||||
in: query
|
||||
required: true
|
||||
description: "The validator's randao reveal value."
|
||||
schema:
|
||||
type: string
|
||||
format: byte
|
||||
responses:
|
||||
200:
|
||||
description: Success response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BeaconBlock'
|
||||
400:
|
||||
$ref: '#/components/responses/InvalidRequest'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
503:
|
||||
$ref: '#/components/responses/CurrentlySyncing'
|
||||
post:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Publish a signed block."
|
||||
description: "Instructs the beacon node to broadcast a newly signed beacon block to the beacon network, to be included in the beacon chain. The beacon node is not required to validate the signed `BeaconBlock`, and a successful response (20X) only indicates that the broadcast has been successful. The beacon node is expected to integrate the new block into its state, and therefore validate the block internally, however blocks which fail the validation are still broadcast but a different status code is returned (202)"
|
||||
parameters:
|
||||
- name: beacon_block
|
||||
in: query
|
||||
required: true
|
||||
description: "The `BeaconBlock` object, as sent from the beacon node originally, but now with the signature field completed."
|
||||
schema:
|
||||
$ref: '#/components/schemas/BeaconBlock'
|
||||
responses:
|
||||
200:
|
||||
description: "The block was validated successfully and has been broadcast. It has also been integrated into the beacon node's database."
|
||||
202:
|
||||
description: "The block failed validation, but was successfully broadcast anyway. It was not integrated into the beacon node's database."
|
||||
400:
|
||||
$ref: '#/components/responses/InvalidRequest'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
503:
|
||||
$ref: '#/components/responses/CurrentlySyncing'
|
||||
|
||||
/validator/attestation:
|
||||
get:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Produce an attestation, without signature."
|
||||
description: "Requests that the beacon node produce an IndexedAttestation, with a blank signature field, which the validator will then sign."
|
||||
parameters:
|
||||
- name: validator_pubkey
|
||||
in: query
|
||||
required: true
|
||||
description: "Uniquely identifying which validator this attestation is to be produced for."
|
||||
schema:
|
||||
$ref: '#/components/schemas/pubkey'
|
||||
- name: poc_bit
|
||||
in: query
|
||||
required: true
|
||||
description: "The proof-of-custody bit that is to be reported by the requesting validator. This bit will be inserted into the appropriate location in the returned `IndexedAttestation`."
|
||||
schema:
|
||||
type: integer
|
||||
format: uint32
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
- name: slot
|
||||
in: query
|
||||
required: true
|
||||
description: "The slot for which the attestation should be proposed."
|
||||
schema:
|
||||
type: integer
|
||||
- name: shard
|
||||
in: query
|
||||
required: true
|
||||
description: "The shard number for which the attestation is to be proposed."
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: Success response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/IndexedAttestation'
|
||||
400:
|
||||
$ref: '#/components/responses/InvalidRequest'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
503:
|
||||
$ref: '#/components/responses/CurrentlySyncing'
|
||||
post:
|
||||
tags:
|
||||
- MinimalSet
|
||||
summary: "Publish a signed attestation."
|
||||
description: "Instructs the beacon node to broadcast a newly signed IndexedAttestation object to the intended shard subnet. The beacon node is not required to validate the signed IndexedAttestation, and a successful response (20X) only indicates that the broadcast has been successful. The beacon node is expected to integrate the new attestation into its state, and therefore validate the attestation internally, however attestations which fail the validation are still broadcast but a different status code is returned (202)"
|
||||
parameters:
|
||||
- name: attestation
|
||||
in: query
|
||||
required: true
|
||||
description: "An `IndexedAttestation` structure, as originally provided by the beacon node, but now with the signature field completed."
|
||||
schema:
|
||||
$ref: '#/components/schemas/IndexedAttestation'
|
||||
responses:
|
||||
200:
|
||||
description: "The attestation was validated successfully and has been broadcast. It has also been integrated into the beacon node's database."
|
||||
202:
|
||||
description: "The attestation failed validation, but was successfully broadcast anyway. It was not integrated into the beacon node's database."
|
||||
400:
|
||||
$ref: '#/components/responses/InvalidRequest'
|
||||
500:
|
||||
$ref: '#/components/responses/InternalError'
|
||||
503:
|
||||
$ref: '#/components/responses/CurrentlySyncing'
|
||||
|
||||
components:
|
||||
schemas:
|
||||
pubkey:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{96}$"
|
||||
description: "The validator's BLS public key, uniquely identifying them. _48-bytes, hex encoded with 0x prefix, case insensitive._"
|
||||
example: "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc"
|
||||
version:
|
||||
type: string
|
||||
description: "A string which uniquely identifies the client implementation and its version; similar to [HTTP User-Agent](https://tools.ietf.org/html/rfc7231#section-5.5.3)."
|
||||
example: "Lighthouse / v0.1.5 (Linux x86_64)"
|
||||
genesis_time:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The genesis_time configured for the beacon node, which is the unix time at which the Eth2.0 chain began."
|
||||
example: 1557716289
|
||||
ValidatorDuty:
|
||||
type: object
|
||||
properties:
|
||||
validator_pubkey:
|
||||
$ref: '#/components/schemas/pubkey'
|
||||
attestation_slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The slot at which the validator must attest."
|
||||
attestation_shard:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The shard in which the validator must attest."
|
||||
block_proposal_slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
nullable: true
|
||||
description: "The slot in which a validator must propose a block, or `null` if block production is not required."
|
||||
SyncingStatus:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
starting_slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The slot at which syncing started (will only be reset after the sync reached its head)"
|
||||
current_slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The most recent slot sync'd by the beacon node."
|
||||
highest_slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Globally, the estimated most recent slot number, or current target slot number."
|
||||
|
||||
BeaconBlock:
|
||||
description: "The [`BeaconBlock`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beaconblock) object from the Eth2.0 spec."
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BeaconBlockCommon'
|
||||
- type: object
|
||||
properties:
|
||||
body:
|
||||
$ref: '#/components/schemas/BeaconBlockBody'
|
||||
BeaconBlockHeader:
|
||||
description: "The [`BeaconBlockHeader`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beaconblockheader) object from the Eth2.0 spec."
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BeaconBlockCommon'
|
||||
- type: object
|
||||
properties:
|
||||
body_root:
|
||||
type: string
|
||||
format: bytes
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "The tree hash merkle root of the `BeaconBlockBody` for the `BeaconBlock`"
|
||||
BeaconBlockCommon:
|
||||
# An abstract object to collect the common fields between the BeaconBlockHeader and the BeaconBlock objects
|
||||
type: object
|
||||
properties:
|
||||
slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The slot to which this block corresponds."
|
||||
parent_root:
|
||||
type: string
|
||||
format: bytes
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "The signing merkle root of the parent `BeaconBlock`."
|
||||
state_root:
|
||||
type: string
|
||||
format: bytes
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "The tree hash merkle root of the `BeaconState` for the `BeaconBlock`."
|
||||
signature:
|
||||
type: string
|
||||
format: bytes
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
example: "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"
|
||||
description: "The BLS signature of the `BeaconBlock` made by the validator of the block."
|
||||
BeaconBlockBody:
|
||||
type: object
|
||||
description: "The [`BeaconBlockBody`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#beaconblockbody) object from the Eth2.0 spec."
|
||||
properties:
|
||||
randao_reveal:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
description: "The RanDAO reveal value provided by the validator."
|
||||
eth1_data:
|
||||
title: Eth1Data
|
||||
type: object
|
||||
description: "The [`Eth1Data`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#eth1data) object from the Eth2.0 spec."
|
||||
properties:
|
||||
deposit_root:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "Root of the deposit tree."
|
||||
deposit_count:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Total number of deposits."
|
||||
block_hash:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "Ethereum 1.x block hash."
|
||||
graffiti:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
proposer_slashings:
|
||||
type: array
|
||||
items:
|
||||
title: ProposerSlashings
|
||||
type: object
|
||||
description: "The [`ProposerSlashing`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#proposerslashing) object from the Eth2.0 spec."
|
||||
properties:
|
||||
proposer_index:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The index of the proposer to be slashed."
|
||||
header_1:
|
||||
$ref: '#/components/schemas/BeaconBlockHeader'
|
||||
header_2:
|
||||
$ref: '#/components/schemas/BeaconBlockHeader'
|
||||
attester_slashings:
|
||||
type: array
|
||||
items:
|
||||
title: AttesterSlashings
|
||||
type: object
|
||||
description: "The [`AttesterSlashing`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attesterslashing) object from the Eth2.0 spec."
|
||||
properties:
|
||||
attestation_1:
|
||||
$ref: '#/components/schemas/IndexedAttestation'
|
||||
attestation_2:
|
||||
$ref: '#/components/schemas/IndexedAttestation'
|
||||
attestations:
|
||||
type: array
|
||||
items:
|
||||
title: Attestation
|
||||
type: object
|
||||
description: "The [`Attestation`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestation) object from the Eth2.0 spec."
|
||||
properties:
|
||||
aggregation_bitfield:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]+$"
|
||||
description: "Attester aggregation bitfield."
|
||||
custody_bitfield:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]+$"
|
||||
description: "Custody bitfield."
|
||||
signature:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
description: "BLS aggregate signature."
|
||||
data:
|
||||
$ref: '#/components/schemas/AttestationData'
|
||||
deposits:
|
||||
type: array
|
||||
items:
|
||||
title: Deposit
|
||||
type: object
|
||||
description: "The [`Deposit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposit) object from the Eth2.0 spec."
|
||||
properties:
|
||||
proof:
|
||||
type: array
|
||||
description: "Branch in the deposit tree."
|
||||
items:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
minItems: 32
|
||||
maxItems: 32
|
||||
index:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Index in the deposit tree."
|
||||
data:
|
||||
title: DepositData
|
||||
type: object
|
||||
description: "The [`DepositData`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#depositdata) object from the Eth2.0 spec."
|
||||
properties:
|
||||
pubkey:
|
||||
$ref: '#/components/schemas/pubkey'
|
||||
withdrawal_credentials:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "The withdrawal credentials."
|
||||
amount:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Amount in Gwei."
|
||||
signature:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
description: "Container self-signature."
|
||||
voluntary_exits:
|
||||
type: array
|
||||
items:
|
||||
title: VoluntaryExit
|
||||
type: object
|
||||
description: "The [`VoluntaryExit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#voluntaryexit) object from the Eth2.0 spec."
|
||||
properties:
|
||||
epoch:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Minimum epoch for processing exit."
|
||||
validator_index:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Index of the exiting validator."
|
||||
signature:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
description: "Validator signature."
|
||||
transfers:
|
||||
type: array
|
||||
items:
|
||||
title: Transfer
|
||||
type: object
|
||||
description: "The [`Transfer`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#transfer) object from the Eth2.0 spec."
|
||||
properties:
|
||||
sender:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Sender index."
|
||||
recipient:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Recipient index."
|
||||
amount:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Amount in Gwei."
|
||||
fee:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Fee in Gwei for block producer."
|
||||
slot:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Inclusion slot."
|
||||
pubkey:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{96}$"
|
||||
description: "Sender withdrawal public key."
|
||||
signature:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
description: "Sender signature."
|
||||
|
||||
Fork:
|
||||
type: object
|
||||
description: "The [`Fork`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#Fork) object from the Eth2.0 spec."
|
||||
properties:
|
||||
previous_version:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{8}$"
|
||||
description: "Previous fork version."
|
||||
current_version:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{8}$"
|
||||
description: "Current fork version."
|
||||
epoch:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Fork epoch number."
|
||||
IndexedAttestation:
|
||||
type: object
|
||||
description: "The [`IndexedAttestation`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#indexedattestation) object from the Eth2.0 spec."
|
||||
properties:
|
||||
custody_bit_0_indices:
|
||||
type: array
|
||||
description: "Validator indices for 0 bits."
|
||||
items:
|
||||
type: integer
|
||||
format: uint64
|
||||
custody_bit_1_indices:
|
||||
type: array
|
||||
description: "Validator indices for 1 bits."
|
||||
items:
|
||||
type: integer
|
||||
format: uint64
|
||||
signature:
|
||||
type: string
|
||||
format: bytes
|
||||
pattern: "^0x[a-fA-F0-9]{192}$"
|
||||
example: "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"
|
||||
description: "The BLS signature of the `IndexedAttestation`, created by the validator of the attestation."
|
||||
data:
|
||||
$ref: '#/components/schemas/AttestationData'
|
||||
AttestationData:
|
||||
type: object
|
||||
description: "The [`AttestationData`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestationdata) object from the Eth2.0 spec."
|
||||
properties:
|
||||
beacon_block_root:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "LMD GHOST vote."
|
||||
source_epoch:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Source epoch from FFG vote."
|
||||
source_root:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "Source root from FFG vote."
|
||||
target_epoch:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "Target epoch from FFG vote."
|
||||
target_root:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "Target root from FFG vote."
|
||||
crosslink:
|
||||
title: CrossLink
|
||||
type: object
|
||||
description: "The [`Crosslink`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#crosslink) object from the Eth2.0 spec, contains data from epochs [`start_epoch`, `end_epoch`)."
|
||||
properties:
|
||||
shard:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The shard number."
|
||||
start_epoch:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The first epoch which the crosslinking data references."
|
||||
end_epoch:
|
||||
type: integer
|
||||
format: uint64
|
||||
description: "The 'end' epoch referred to by the crosslinking data; no data in this Crosslink should refer to the `end_epoch` since it is not included in the crosslinking data interval."
|
||||
parent_root:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "Root of the previous crosslink."
|
||||
data_root:
|
||||
type: string
|
||||
format: byte
|
||||
pattern: "^0x[a-fA-F0-9]{64}$"
|
||||
description: "Root of the crosslinked shard data since the previous crosslink."
|
||||
|
||||
responses:
|
||||
Success:
|
||||
description: "Request successful."
|
||||
InvalidRequest:
|
||||
description: "Invalid request syntax."
|
||||
InternalError:
|
||||
description: "Beacon node internal error."
|
||||
CurrentlySyncing:
|
||||
description: "Beacon node is currently syncing, try again later."
|
||||
NotFound:
|
||||
description: "The requested API endpoint does not exist."
|
||||
Reference in New Issue
Block a user