-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
input generator and short readme #46
- Loading branch information
Showing
7 changed files
with
350 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,3 +37,5 @@ build/ | |
cmake-build-debug/ | ||
# configuration directory with Proof Market credentials | ||
.config | ||
|
||
__pycache__/ |
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 |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Consensus Layer Storage Proofs | ||
|
||
Here is an example of an application for transferring data from the Consensus Layer (CL) to the Execution Layer (EL) in the Ethereum network. | ||
This transfer allows access to historical Ethereum data and CL information such as validators registry. | ||
|
||
Note: for now, EL does not have access to the root of CS's block. However, [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) fixes this. | ||
|
||
# How does it work? | ||
Here is CL's block definition: | ||
``` | ||
class BeaconBlock(Container): | ||
slot: Slot | ||
proposer_index: ValidatorIndex | ||
parent_root: Root | ||
state_root: Root | ||
body: BeaconBlockBody | ||
``` | ||
|
||
`state_root` is a Merkle tree root (based on sha2-256) for `BeaconState`. | ||
Beacon State defines the whole state of the network and can be used to obtain historical data. | ||
|
||
``` | ||
class BeaconState(Container): | ||
# Versioning | ||
genesis_time: uint64 | ||
genesis_validators_root: Root | ||
slot: Slot | ||
fork: Fork | ||
# History | ||
latest_block_header: BeaconBlockHeader | ||
block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] | ||
state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT] | ||
historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT] # Frozen in Capella, replaced by historical_summaries | ||
# Eth1 | ||
eth1_data: Eth1Data | ||
eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH] | ||
eth1_deposit_index: uint64 | ||
# Registry | ||
validators: List[Validator, VALIDATOR_REGISTRY_LIMIT] | ||
balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT] | ||
# Randomness | ||
randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR] | ||
# Slashings | ||
slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR] # Per-epoch sums of slashed effective balances | ||
# Participation | ||
previous_epoch_participation: List[ParticipationFlags, VALIDATOR_REGISTRY_LIMIT] # [Modified in Altair] | ||
current_epoch_participation: List[ParticipationFlags, VALIDATOR_REGISTRY_LIMIT] # [Modified in Altair] | ||
# Finality | ||
justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH] # Bit set for every recent justified epoch | ||
previous_justified_checkpoint: Checkpoint | ||
current_justified_checkpoint: Checkpoint | ||
finalized_checkpoint: Checkpoint | ||
# Inactivity | ||
inactivity_scores: List[uint64, VALIDATOR_REGISTRY_LIMIT] # [New in Altair] | ||
# Sync | ||
current_sync_committee: SyncCommittee # [New in Altair] | ||
next_sync_committee: SyncCommittee # [New in Altair] | ||
# Execution | ||
latest_execution_payload_header: ExecutionPayloadHeader # [New in Bellatrix] | ||
# Withdrawals | ||
next_withdrawal_index: WithdrawalIndex # [New in Capella] | ||
next_withdrawal_validator_index: ValidatorIndex # [New in Capella] | ||
# Deep history valid from Capella onwards | ||
historical_summaries: List[HistoricalSummary, HISTORICAL_ROOTS_LIMIT] # [New in Capella] | ||
``` | ||
|
||
Historical data for blocks produced before Capella update is located in 'historical_roots'. | ||
The newer data is located in `historical_summaries`. | ||
More information about Beacon State structure can be found [here](https://eth2book.info/capella/part3/containers/state/). | ||
|
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 |
---|---|---|
@@ -0,0 +1,185 @@ | ||
from ssz.hashable_container import HashableContainer | ||
from ssz.sedes import ( | ||
Bitlist, | ||
Bitvector, | ||
ByteVector, | ||
List, | ||
Vector, | ||
boolean, | ||
byte, | ||
bytes4, | ||
bytes32, | ||
bytes48, | ||
uint8, | ||
uint64, | ||
uint256 | ||
) | ||
|
||
import constants | ||
|
||
Hash32 = bytes32 | ||
Root = bytes32 | ||
Gwei = uint64 | ||
Epoch = uint64 | ||
Slot = uint64 | ||
CommitteeIndex = uint64 | ||
ValidatorIndex = uint64 | ||
BLSPubkey = bytes48 | ||
ExecutionAddress = ByteVector(20) | ||
WithdrawalIndex = uint64 | ||
ParticipationFlags = uint8 | ||
Version = bytes4 | ||
|
||
class Fork(HashableContainer): | ||
fields = [ | ||
("previous_version", Version), | ||
("current_version", Version), | ||
("epoch", Epoch) # Epoch of latest fork | ||
] | ||
|
||
|
||
class Checkpoint(HashableContainer): | ||
fields = [ | ||
("epoch", Epoch), | ||
("root", Root) | ||
] | ||
|
||
|
||
class BeaconBlockHeader(HashableContainer): | ||
fields = [ | ||
("slot", Slot), | ||
("proposer_index", ValidatorIndex), | ||
("parent_root", Root), | ||
("state_root", Root), | ||
("body_root", Root), | ||
] | ||
|
||
|
||
class Eth1Data(HashableContainer): | ||
fields = [ | ||
("deposit_root", Root), | ||
("deposit_count", uint64), | ||
("block_hash", Hash32), | ||
] | ||
|
||
|
||
class Validator(HashableContainer): | ||
fields = [ | ||
("pubkey", BLSPubkey), | ||
("withdrawal_credentials", bytes32), # Commitment to pubkey for withdrawals | ||
("effective_balance", Gwei), # Balance at stake | ||
("slashed", boolean), | ||
# Status epochs | ||
("activation_eligibility_epoch", Epoch), # When criteria for activation were met | ||
("activation_epoch", Epoch), | ||
("exit_epoch", Epoch), | ||
("withdrawable_epoch", Epoch), # When validator can withdraw funds | ||
] | ||
|
||
|
||
class AttestationData(HashableContainer): | ||
fields = [ | ||
("slot", Slot), | ||
("index", CommitteeIndex), | ||
("beacon_block_root", Root), | ||
("source", Checkpoint), | ||
("target", Checkpoint), | ||
] | ||
|
||
|
||
class PendingAttestation(HashableContainer): | ||
fields = [ | ||
("aggregation_bits", Bitlist(constants.MAX_VALIDATORS_PER_COMMITTEE)), | ||
("data", AttestationData), | ||
("inclusion_delay", Slot), | ||
("proposer_index", ValidatorIndex), | ||
] | ||
|
||
|
||
class SyncCommittee(HashableContainer): | ||
fields = [ | ||
("pubkeys", Vector(BLSPubkey, constants.SYNC_COMMITTEE_SIZE)), | ||
("aggregate_pubkey", BLSPubkey), | ||
] | ||
|
||
class ExecutionPayloadHeader(HashableContainer): | ||
# Execution block header fields | ||
fields = [ | ||
("parent_hash", Hash32), | ||
("fee_recipient", ExecutionAddress), | ||
("state_root", bytes32), | ||
("receipts_root", bytes32), | ||
("logs_bloom", ByteVector(constants.BYTES_PER_LOGS_BLOOM)), | ||
("prev_randao", bytes32), | ||
("block_number", uint64), | ||
("gas_limit", uint64), | ||
("gas_used", uint64), | ||
("timestamp", uint64), | ||
# ("extra_data", ByteList(constants.MAX_EXTRA_DATA_BYTES)), | ||
# workaround - looks like ByteList is partially broken, but extra data is exactly bytes32 | ||
("extra_data", List(byte, constants.MAX_EXTRA_DATA_BYTES)), | ||
("base_fee_per_gas", uint256), | ||
("block_hash", Hash32), | ||
("transactions_root", Root), | ||
("withdrawals_root", Root), | ||
# ("excess_data_gas: uint256", uint256), | ||
] | ||
|
||
class HistoricalSummary(HashableContainer): | ||
""" | ||
`HistoricalSummary` matches the components of the phase0 `HistoricalBatch` | ||
making the two hash_tree_root-compatible. | ||
""" | ||
fields = [ | ||
("block_summary_root", Root), | ||
("state_summary_root", Root), | ||
] | ||
|
||
|
||
Balances = List(Gwei, constants.VALIDATOR_REGISTRY_LIMIT) | ||
|
||
|
||
class BeaconState: | ||
fields = [ | ||
# Versioning | ||
("genesis_time", uint64), | ||
("genesis_validators_root", Root), | ||
("slot", Slot), | ||
("fork", Fork), | ||
# History | ||
("latest_block_header", BeaconBlockHeader), | ||
("block_roots", Vector(Root, constants.SLOTS_PER_HISTORICAL_ROOT)), | ||
("state_roots", Vector(Root, constants.SLOTS_PER_HISTORICAL_ROOT)), | ||
("historical_roots", List(Root, constants.HISTORICAL_ROOTS_LIMIT)), # Frozen in Capella, replaced by historical_summaries | ||
# Eth1 | ||
("eth1_data", Eth1Data), | ||
("eth1_data_votes", List(Eth1Data, constants.EPOCHS_PER_ETH1_VOTING_PERIOD * constants.SLOTS_PER_EPOCH)), | ||
("eth1_deposit_index", uint64), | ||
# Registry | ||
("validators", List(Validator, constants.VALIDATOR_REGISTRY_LIMIT)), | ||
("balances", Balances), | ||
# Randomness | ||
("randao_mixes", Vector(bytes32, constants.EPOCHS_PER_HISTORICAL_VECTOR)), | ||
# Slashings | ||
("slashings", Vector(Gwei, constants.EPOCHS_PER_SLASHINGS_VECTOR)), # Per-epoch sums of slashed effective balances | ||
# Participation | ||
("previous_epoch_participation", List(ParticipationFlags, constants.VALIDATOR_REGISTRY_LIMIT)), | ||
("current_epoch_participation", List(ParticipationFlags, constants.VALIDATOR_REGISTRY_LIMIT)), | ||
# Finality | ||
("justification_bits", Bitvector(constants.JUSTIFICATION_BITS_LENGTH)), # Bit set for every recent justified epoch | ||
("previous_justified_checkpoint", Checkpoint), | ||
("current_justified_checkpoint", Checkpoint), | ||
("finalized_checkpoint", Checkpoint), | ||
# Inactivity | ||
("inactivity_scores", List(uint64, constants.VALIDATOR_REGISTRY_LIMIT)), | ||
# Sync | ||
("current_sync_committee", SyncCommittee), | ||
("next_sync_committee", SyncCommittee), | ||
# Execution | ||
("latest_execution_payload_header", ExecutionPayloadHeader), # (Modified in Capella) | ||
# Withdrawals | ||
("next_withdrawal_index", WithdrawalIndex), # (New in Capella) | ||
("next_withdrawal_validator_index", ValidatorIndex), # (New in Capella) | ||
# Deep history valid from Capella onwards | ||
("historical_summaries", List(HistoricalSummary, constants.HISTORICAL_ROOTS_LIMIT)), # (New in Capella) | ||
] |
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 |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#misc | ||
from enum import Enum | ||
|
||
FAR_FUTURE_EPOCH = 2 ** 64 - 1 | ||
JUSTIFICATION_BITS_LENGTH = 4 | ||
MAX_VALIDATORS_PER_COMMITTEE = 2 ** 11 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#time-parameters-1 | ||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY = 2**8 | ||
SHARD_COMMITTEE_PERIOD = 256 | ||
MIN_ATTESTATION_INCLUSION_DELAY = 2**0 | ||
SLOTS_PER_EPOCH = 2**5 | ||
MIN_SEED_LOOKAHEAD = 2**0 | ||
MAX_SEED_LOOKAHEAD = 2**2 | ||
MIN_EPOCHS_TO_INACTIVITY_PENALTY = 2**2 | ||
EPOCHS_PER_ETH1_VOTING_PERIOD = 2**6 | ||
SLOTS_PER_HISTORICAL_ROOT = 2**13 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#state-list-lengths | ||
EPOCHS_PER_HISTORICAL_VECTOR = 2**16 | ||
EPOCHS_PER_SLASHINGS_VECTOR = 2**13 | ||
HISTORICAL_ROOTS_LIMIT = 2**24 | ||
VALIDATOR_REGISTRY_LIMIT = 2**40 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#rewards-and-penalties | ||
PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX = 3 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#gwei-values | ||
EFFECTIVE_BALANCE_INCREMENT = 2 ** 0 * 10 ** 9 | ||
MAX_EFFECTIVE_BALANCE = 32 * 10 ** 9 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#execution | ||
MAX_WITHDRAWALS_PER_PAYLOAD = 2 ** 4 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#withdrawal-prefixes | ||
ETH1_ADDRESS_WITHDRAWAL_PREFIX = '0x01' | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator-cycle | ||
MIN_PER_EPOCH_CHURN_LIMIT = 2 ** 2 | ||
CHURN_LIMIT_QUOTIENT = 2 ** 16 | ||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#max-operations-per-block | ||
MAX_ATTESTATIONS = 2 ** 7 | ||
|
||
# https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#sync-committee | ||
SYNC_COMMITTEE_SIZE = 2 ** 9 | ||
BYTES_PER_LOGS_BLOOM = 2 ** 8 | ||
MAX_EXTRA_DATA_BYTES = 2 ** 5 | ||
|
||
|
||
# Local constants | ||
GWEI_TO_WEI = 10 ** 9 | ||
SHARE_RATE_PRECISION_E27 = 10**27 | ||
TOTAL_BASIS_POINTS = 10000 | ||
|
||
MAX_BLOCK_GAS_LIMIT = 30_000_000 | ||
|
||
|
||
class Chain(Enum): | ||
MAINNET = "mainnet" | ||
GOERLI = "goerli" | ||
SEPOLIA = "sepolia" |
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 |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from pymerkle import InmemoryTree as MerkleTree | ||
from consensus_layer_ssz import BeaconState | ||
import random | ||
|
||
def get_random_state(): | ||
state_size = 16 | ||
state_data = [random.randint(0, (1<<16)) for _ in range(state_size)] | ||
tree = MerkleTree() | ||
for x in state_data: | ||
tree.append_entry(bytes(x)) | ||
root = tree.get_state() | ||
|
||
state: BeaconState = BeaconState() | ||
state.state_root = [root] | ||
return state, tree |
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 |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from mock_beacon_state import get_random_state | ||
import json | ||
import sys | ||
import random | ||
|
||
def slice_into_low_high(digest): | ||
low = int.from_bytes(digest[:16], 'big') | ||
high = int.from_bytes(digest[16:], 'big') | ||
|
||
return [low, high] | ||
|
||
if __name__ == "__main__": | ||
index = random.randint(1, 16) | ||
state, tree = get_random_state() | ||
merkle_path = tree.prove_inclusion(index) | ||
leaf = tree.get_leaf(index) | ||
root = state.state_root[0] | ||
print(f"Preparing Merkle path for index {index - 1} and state root {root.hex()}") | ||
input = [{"array" : [slice_into_low_high(node) for node in merkle_path.path]}, {"vector": slice_into_low_high(leaf)}, {"vector" : slice_into_low_high(root)}] | ||
with open("path.inp", 'w') as f: | ||
sys.stdout = f | ||
print(json.dumps(input, indent=4)) |
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 |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pymerkle==6.0.0 | ||
ssz==0.3.1 |