* Start fixing enr-fork-id

* Fix time-until-next-fork logic

* Remove fork crate
This commit is contained in:
Paul Hauner
2020-03-26 17:35:12 +11:00
committed by Age Manning
parent bb065e3d00
commit f26bafe436
14 changed files with 129 additions and 152 deletions

View File

@@ -3,6 +3,7 @@ use int_to_bytes::int_to_bytes4;
use serde_derive::{Deserialize, Serialize};
use std::fs::File;
use std::path::Path;
use tree_hash::TreeHash;
use utils::{
fork_from_hex_str, fork_to_hex_str, u32_from_hex_str, u32_to_hex_str, u8_from_hex_str,
u8_to_hex_str,
@@ -123,6 +124,33 @@ pub struct ChainSpec {
}
impl ChainSpec {
/// Returns an `EnrForkId` for the given `slot`.
///
/// Presently, we don't have any forks so we just ignore the slot. In the future this function
/// may return something different based upon the slot.
pub fn enr_fork_id(&self, _slot: Slot) -> EnrForkId {
// TODO: set this to something sensible once v0.11.0 is ready.
let genesis_validators_root = Hash256::zero();
EnrForkId {
fork_digest: Self::compute_fork_digest(
self.genesis_fork_version,
genesis_validators_root,
)
.to_le_bytes(),
next_fork_version: self.genesis_fork_version,
next_fork_epoch: self.far_future_epoch,
}
}
/// Returns the epoch of the next scheduled change in the `fork.current_version`.
///
/// There are no future forks scheduled so this function always returns `None`. This may not
/// always be the case in the future, though.
pub fn next_fork_epoch(&self) -> Option<Epoch> {
None
}
/// Get the domain number, unmodified by the fork.
///
/// Spec v0.10.1
@@ -156,6 +184,35 @@ impl ChainSpec {
self.compute_domain(Domain::Deposit, self.genesis_fork_version)
}
/// Return the 32-byte fork data root for the `current_version` and `genesis_validators_root`.
///
/// This is used primarily in signature domains to avoid collisions across forks/chains.
///
/// Spec v0.11.0
pub fn compute_fork_data_root(
current_version: [u8; 4],
genesis_validators_root: Hash256,
) -> Hash256 {
ForkData {
current_version,
genesis_validators_root,
}
.tree_hash_root()
}
/// Return the 4-byte fork digest for the `current_version` and `genesis_validators_root`.
///
/// This is a digest primarily used for domain separation on the p2p layer.
/// 4-bytes suffices for practical separation of forks/chains.
pub fn compute_fork_digest(current_version: [u8; 4], genesis_validators_root: Hash256) -> u32 {
let fork_data_root = Self::compute_fork_data_root(current_version, genesis_validators_root);
let mut bytes = [0; 4];
bytes.copy_from_slice(&fork_data_root[0..4]);
u32::from_le_bytes(bytes)
}
/// Compute a domain by applying the given `fork_version`.
///
/// Spec v0.10.1

View File

@@ -0,0 +1,32 @@
use crate::test_utils::TestRandom;
use crate::utils::{fork_from_hex_str, fork_to_hex_str};
use crate::{Hash256, SignedRoot};
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
use tree_hash_derive::TreeHash;
/// Specifies a fork of the `BeaconChain`, to prevent replay attacks.
///
/// Spec v0.11.0
#[derive(
Debug, Clone, PartialEq, Default, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
)]
pub struct ForkData {
#[serde(
serialize_with = "fork_to_hex_str",
deserialize_with = "fork_from_hex_str"
)]
pub current_version: [u8; 4],
pub genesis_validators_root: Hash256,
}
impl SignedRoot for ForkData {}
#[cfg(test)]
mod tests {
use super::*;
ssz_and_tree_hash_tests!(ForkData);
}

View File

@@ -25,6 +25,7 @@ pub mod enr_fork_id;
pub mod eth1_data;
pub mod eth_spec;
pub mod fork;
pub mod fork_data;
pub mod free_attestation;
pub mod historical_batch;
pub mod indexed_attestation;
@@ -80,6 +81,7 @@ pub use crate::slot_epoch::{Epoch, Slot, FAR_FUTURE_EPOCH};
pub use crate::subnet_id::SubnetId;
pub use crate::validator::Validator;
pub use crate::voluntary_exit::VoluntaryExit;
pub use fork_data::ForkData;
pub type CommitteeIndex = u64;
pub type Hash256 = H256;