diff --git a/specs/bls_signature.md b/specs/bls_signature.md index d119c4499..3fe1bcc0e 100644 --- a/specs/bls_signature.md +++ b/specs/bls_signature.md @@ -1,6 +1,8 @@ # BLS signature verification -**Warning: This document is pending academic review and should not yet be considered secure.** +**Notice**: This document is a placeholder to facilitate the emergence of cross-client testnets. Substantive changes are postponed until [BLS standardisation](https://github.com/pairingwg/bls_standard) is finalized. + +**Warning**: The constructions in this document should not be considered secure. In particular, the `hash_to_G2` function is known to be unsecure. ## Table of contents diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f69795926..60f774e9a 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -51,6 +51,7 @@ - [`hash`](#hash) - [`hash_tree_root`](#hash_tree_root) - [`signing_root`](#signing_root) + - [`bls_domain`](#bls_domain) - [`slot_to_epoch`](#slot_to_epoch) - [`get_previous_epoch`](#get_previous_epoch) - [`get_current_epoch`](#get_current_epoch) @@ -629,6 +630,16 @@ The `hash` function is SHA256. `def signing_root(object: SSZContainer) -> Bytes32` is a function defined in the [SimpleSerialize spec](../simple-serialize.md#self-signed-containers) to compute signing messages. +### `bls_domain` + +```python +def bls_domain(domain_type: int, fork_version: bytes=b'\x00\x00\x00\x00') -> int: + """ + Return the bls domain given by the ``domain_type`` and optional 4 byte ``fork_version`` (defaults to zero). + """ + return bytes_to_int(int_to_bytes(domain_type, length=4) + fork_version) +``` + ### `slot_to_epoch` ```python @@ -968,7 +979,7 @@ def get_domain(state: BeaconState, """ epoch = get_current_epoch(state) if message_epoch is None else message_epoch fork_version = state.fork.previous_version if epoch < state.fork.epoch else state.fork.current_version - return bytes_to_int(fork_version + int_to_bytes(domain_type, length=4)) + return bls_domain(domain_type, fork_version) ``` ### `get_bitfield_bit` @@ -1765,8 +1776,9 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None: validator_pubkeys = [v.pubkey for v in state.validator_registry] if pubkey not in validator_pubkeys: # Verify the deposit signature (proof of possession) + # 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, get_domain(state, DOMAIN_DEPOSIT) + pubkey, signing_root(deposit.data), deposit.data.signature, bls_domain(DOMAIN_DEPOSIT) ): return diff --git a/specs/networking/libp2p-standardization.md b/specs/networking/libp2p-standardization.md new file mode 100644 index 000000000..b6a46db1b --- /dev/null +++ b/specs/networking/libp2p-standardization.md @@ -0,0 +1,158 @@ +ETH 2.0 Networking Spec - Libp2p standard protocols +=== + +# Abstract + +Ethereum 2.0 clients plan to use the libp2p protocol networking stack for +mainnet release. This document aims to standardize the libp2p client protocols, +configuration and messaging formats. + +# Libp2p Components + +## Transport + +This section details the libp2p transport layer that underlies the +[protocols](#protocols) that are listed in this document. + +Libp2p allows composition of multiple transports. Eth2.0 clients should support +TCP/IP and optionally websockets. Websockets are useful for implementations +running in the browser and therefore native clients would ideally support these implementations +by supporting websockets. + +An ideal libp2p transport would therefore support both TCP/IP and websockets. + +*Note: There is active development in libp2p to facilitate the +[QUIC](https://github.com/libp2p/go-libp2p-quic-transport) transport, which may +be adopted in the future* + +### Encryption + +Libp2p currently offers [Secio](https://github.com/libp2p/specs/pull/106) which +can upgrade a transport which will then encrypt all future communication. Secio +generates a symmetric ephemeral key which peers use to encrypt their +communication. It can support a range of ciphers and currently supports key +derivation for elliptic curve-based public keys. + +Current defaults are: +- Key agreement: `ECDH-P256` (also supports `ECDH-P384`) +- Cipher: `AES-128` (also supports `AES-256`, `TwofishCTR`) +- Digests: `SHA256` (also supports `SHA512`) + +*Note: Secio is being deprecated in favour of [TLS +1.3](https://github.com/libp2p/specs/blob/master/tls/tls.md). It is our +intention to transition to use TLS 1.3 for encryption between nodes, rather +than Secio.* + + +## Protocols + +This section lists the necessary libp2p protocols required by Ethereum 2.0 +running a libp2p network stack. + +## Multistream-select + +#### Protocol id: `/multistream/1.0.0` + +Clients running libp2p should support the +[multistream-select](https://github.com/multiformats/multistream-select/) +protocol which allows clients to negotiate libp2p protocols establish streams +per protocol. + +## Multiplexing + +Libp2p allows clients to compose multiple multiplexing methods. Clients should +support [mplex](https://github.com/libp2p/specs/tree/master/mplex) and +optionally [yamux](https://github.com/hashicorp/yamux/blob/master/spec.md) +(these can be composed). + +**Mplex protocol id: `/mplex/6.7.0`** + +**Yamux protocol id: `/yamux/1.0.0`** + +## Gossipsub + +#### Protocol id: `/eth/serenity/gossipsub/1.0.0` + +*Note: Parameters listed here are subject to a large-scale network feasibility +study* + +The [Gossipsub](https://github.com/libp2p/specs/tree/master/pubsub/gossipsub) +protocol is used for block and attestation propagation across the +network. + +### Configuration Parameters + +Gossipsub has a number of internal configuration parameters which directly +effect the network performance. Clients can implement independently, however +we aim to standardize these across clients to optimize the gossip network for +propagation times and message duplication. Current network-related defaults are: + +``` +( + // The target number of peers in the overlay mesh network (D in the libp2p specs). + mesh_size: 6 + // The minimum number of peers in the mesh network before adding more (D_lo in the libp2p specs). + mesh_lo: 4 + // The maximum number of peers in the mesh network before removing some (D_high in the libp2p sepcs). + mesh_high: 12 + // The number of peers to gossip to during a heartbeat (D_lazy in the libp2p sepcs). + gossip_lazy: 6 // defaults to `mesh_size` + // Time to live for fanout peers (seconds). + fanout_ttl: 60 + // The number of heartbeats to gossip about. + gossip_history: 3 + // Time between each heartbeat (seconds). + heartbeat_interval: 1 +) +``` + +### Topics + +*The Go and Js implementations use string topics - This is likely to be +updated to topic hashes in later versions - https://github.com/libp2p/rust-libp2p/issues/473* + +For Eth2.0 clients, topics are sent as `SHA2-256` hashes of the topic string. + +There are two main topics used to propagate attestations and beacon blocks to +all nodes on the network. + +- The `beacon_block` topic - This topic is used solely for propagating new + beacon blocks to all nodes on the networks. +- The `beacon_attestation` topic - This topic is used to propagate + aggregated attestations to subscribing nodes (typically block proposers) to + be included into future blocks. Attestations are aggregated in their + respective subnets before publishing on this topic. + +Shards are grouped into their own subnets (defined by a shard topic). The +number of shard subnets is defined via `SHARD_SUBNET_COUNT` and the shard +`shard_number % SHARD_SUBNET_COUNT` is assigned to the topic: +`shard{shard_number % SHARD_SUBNET_COUNT}_attestation`. + +### Messages + +*Note: The message format here is Eth2.0-specific* + +Each Gossipsub +[Message](https://github.com/libp2p/go-libp2p-pubsub/blob/master/pb/rpc.proto#L17-L24) +has a maximum size of 512KB (estimated from expected largest uncompressed block +size). + +The `data` field of a Gossipsub `Message` is an SSZ-encoded object. For the `beacon_block` topic, +this is a `beacon_block`. For the `beacon_attestation` topic, this is +an `attestation`. + +## Eth-2 RPC + +#### Protocol Id: `/eth/serenity/beacon/rpc/1` + +The [RPC Interface](./rpc-interface.md) is specified in this repository. + +## Discovery + +Discovery Version 5 +([discv5])(https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md) +will be used for discovery. This protocol uses a UDP transport and specifies +its own encryption, ip-discovery and topic advertisement. Therefore, it has no +need to establish establish streams through `multistream-select`, rather, act +as a standalone implementation that feeds discovered peers/topics (ENR-records) as +`multiaddrs` into the libp2p service. diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index d05f25ef2..f8272d446 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -98,7 +98,7 @@ To submit a deposit: * Pack the validator's [initialization parameters](#initialization) into `deposit_data`, a [`DepositData`](../core/0_beacon-chain.md#depositdata) SSZ object. * Let `amount` be the amount in Gwei to be deposited by the validator where `MIN_DEPOSIT_AMOUNT <= amount <= MAX_EFFECTIVE_BALANCE`. * Set `deposit_data.amount = amount`. -* Let `signature` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=DOMAIN_DEPOSIT`. +* Let `signature` be the result of `bls_sign` of the `signing_root(deposit_data)` with `domain=bls_domain(DOMAIN_DEPOSIT)`. (Deposits are valid regardless of fork version, `bls_domain` will default to zeroes there). * Send a transaction on the Ethereum 1.0 chain to `DEPOSIT_CONTRACT_ADDRESS` executing `def deposit(pubkey: bytes[48], withdrawal_credentials: bytes[32], signature: bytes[96])` along with a deposit of `amount` Gwei. *Note*: Deposits made for the same `pubkey` are treated as for the same validator. A singular `Validator` will be added to `state.validator_registry` with each additional deposit amount added to the validator's balance. A validator can only be activated when total deposits for the validator pubkey meet or exceed `MAX_EFFECTIVE_BALANCE`. diff --git a/test_libs/pyspec/tests/phase0/helpers.py b/test_libs/pyspec/tests/phase0/helpers.py index 4d1973921..140f74a53 100644 --- a/test_libs/pyspec/tests/phase0/helpers.py +++ b/test_libs/pyspec/tests/phase0/helpers.py @@ -3,7 +3,6 @@ from copy import deepcopy from py_ecc import bls from eth2spec.utils.minimal_ssz import signing_root - from eth2spec.utils.merkle_minimal import ( calc_merkle_tree_from_leaves, get_merkle_proof, @@ -106,10 +105,7 @@ def build_deposit_data(state, pubkey, privkey, amount): signature = bls.sign( message_hash=signing_root(deposit_data), privkey=privkey, - domain=spec.get_domain( - state, - spec.DOMAIN_DEPOSIT, - ) + domain=spec.bls_domain(spec.DOMAIN_DEPOSIT), ) deposit_data.signature = signature return deposit_data