1.1.5 merge spec tests (#2781)
* Fix arbitrary check kintsugi * Add merge chain spec fields, and a function to determine which constant to use based on the state variant * increment spec test version * Remove `Transaction` enum wrapper * Remove Transaction new-type * Remove gas validations * Add `--terminal-block-hash-epoch-override` flag * Increment spec tests version to 1.1.5 * Remove extraneous gossip verification https://github.com/ethereum/consensus-specs/pull/2687 * - Remove unused Error variants - Require both "terminal-block-hash-epoch-override" and "terminal-block-hash-override" when either flag is used * - Remove a couple more unused Error variants Co-authored-by: Paul Hauner <paul@paulhauner.com>
This commit is contained in:
parent
cdbe603adf
commit
de49c7ddaa
@ -278,18 +278,6 @@ pub enum ExecutionPayloadError {
|
|||||||
///
|
///
|
||||||
/// The block is invalid and the peer is faulty
|
/// The block is invalid and the peer is faulty
|
||||||
InvalidPayloadTimestamp { expected: u64, found: u64 },
|
InvalidPayloadTimestamp { expected: u64, found: u64 },
|
||||||
/// The gas used in the block exceeds the gas limit
|
|
||||||
///
|
|
||||||
/// ## Peer scoring
|
|
||||||
///
|
|
||||||
/// The block is invalid and the peer is faulty
|
|
||||||
GasUsedExceedsLimit,
|
|
||||||
/// The payload block hash equals the parent hash
|
|
||||||
///
|
|
||||||
/// ## Peer scoring
|
|
||||||
///
|
|
||||||
/// The block is invalid and the peer is faulty
|
|
||||||
BlockHashEqualsParentHash,
|
|
||||||
/// The execution payload transaction list data exceeds size limits
|
/// The execution payload transaction list data exceeds size limits
|
||||||
///
|
///
|
||||||
/// ## Peer scoring
|
/// ## Peer scoring
|
||||||
@ -1353,18 +1341,6 @@ fn validate_execution_payload<T: BeaconChainTypes>(
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// Gas used is less than the gas limit
|
|
||||||
if execution_payload.gas_used > execution_payload.gas_limit {
|
|
||||||
return Err(BlockError::ExecutionPayloadError(
|
|
||||||
ExecutionPayloadError::GasUsedExceedsLimit,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// The execution payload block hash is not equal to the parent hash
|
|
||||||
if execution_payload.block_hash == execution_payload.parent_hash {
|
|
||||||
return Err(BlockError::ExecutionPayloadError(
|
|
||||||
ExecutionPayloadError::BlockHashEqualsParentHash,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// The execution payload transaction list data is within expected size limits
|
// The execution payload transaction list data is within expected size limits
|
||||||
if execution_payload.transactions.len() > T::EthSpec::max_transactions_per_payload() {
|
if execution_payload.transactions.len() > T::EthSpec::max_transactions_per_payload() {
|
||||||
return Err(BlockError::ExecutionPayloadError(
|
return Err(BlockError::ExecutionPayloadError(
|
||||||
|
@ -152,7 +152,7 @@ where
|
|||||||
.terminal_total_difficulty_override
|
.terminal_total_difficulty_override
|
||||||
.unwrap_or(spec.terminal_total_difficulty);
|
.unwrap_or(spec.terminal_total_difficulty);
|
||||||
let terminal_block_hash = config
|
let terminal_block_hash = config
|
||||||
.terminal_block_hash
|
.terminal_block_hash_override
|
||||||
.unwrap_or(spec.terminal_block_hash);
|
.unwrap_or(spec.terminal_block_hash);
|
||||||
|
|
||||||
let execution_layer = if let Some(execution_endpoints) = config.execution_endpoints {
|
let execution_layer = if let Some(execution_endpoints) = config.execution_endpoints {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use beacon_chain::types::Epoch;
|
||||||
use directory::DEFAULT_ROOT_DIR;
|
use directory::DEFAULT_ROOT_DIR;
|
||||||
use network::NetworkConfig;
|
use network::NetworkConfig;
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
@ -76,7 +77,8 @@ pub struct Config {
|
|||||||
pub eth1: eth1::Config,
|
pub eth1: eth1::Config,
|
||||||
pub execution_endpoints: Option<Vec<SensitiveUrl>>,
|
pub execution_endpoints: Option<Vec<SensitiveUrl>>,
|
||||||
pub terminal_total_difficulty_override: Option<Uint256>,
|
pub terminal_total_difficulty_override: Option<Uint256>,
|
||||||
pub terminal_block_hash: Option<Hash256>,
|
pub terminal_block_hash_override: Option<Hash256>,
|
||||||
|
pub terminal_block_hash_epoch_override: Option<Epoch>,
|
||||||
pub fee_recipient: Option<Address>,
|
pub fee_recipient: Option<Address>,
|
||||||
pub http_api: http_api::Config,
|
pub http_api: http_api::Config,
|
||||||
pub http_metrics: http_metrics::Config,
|
pub http_metrics: http_metrics::Config,
|
||||||
@ -100,7 +102,8 @@ impl Default for Config {
|
|||||||
eth1: <_>::default(),
|
eth1: <_>::default(),
|
||||||
execution_endpoints: None,
|
execution_endpoints: None,
|
||||||
terminal_total_difficulty_override: None,
|
terminal_total_difficulty_override: None,
|
||||||
terminal_block_hash: None,
|
terminal_block_hash_override: None,
|
||||||
|
terminal_block_hash_epoch_override: None,
|
||||||
fee_recipient: None,
|
fee_recipient: None,
|
||||||
disabled_forks: Vec::new(),
|
disabled_forks: Vec::new(),
|
||||||
graffiti: Graffiti::default(),
|
graffiti: Graffiti::default(),
|
||||||
|
@ -308,7 +308,8 @@ pub struct JsonExecutionPayload<T: EthSpec> {
|
|||||||
pub base_fee_per_gas: Uint256,
|
pub base_fee_per_gas: Uint256,
|
||||||
pub block_hash: Hash256,
|
pub block_hash: Hash256,
|
||||||
#[serde(with = "serde_transactions")]
|
#[serde(with = "serde_transactions")]
|
||||||
pub transactions: VariableList<Transaction<T>, T::MaxTransactionsPerPayload>,
|
pub transactions:
|
||||||
|
VariableList<Transaction<T::MaxBytesPerTransaction>, T::MaxTransactionsPerPayload>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayload<T>> for JsonExecutionPayload<T> {
|
impl<T: EthSpec> From<ExecutionPayload<T>> for JsonExecutionPayload<T> {
|
||||||
@ -410,16 +411,16 @@ pub mod serde_transactions {
|
|||||||
use serde::{de, Deserializer, Serializer};
|
use serde::{de, Deserializer, Serializer};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
type Value<T, N> = VariableList<Transaction<T>, N>;
|
type Value<M, N> = VariableList<Transaction<M>, N>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ListOfBytesListVisitor<T, N> {
|
pub struct ListOfBytesListVisitor<M, N> {
|
||||||
_phantom_t: PhantomData<T>,
|
_phantom_m: PhantomData<M>,
|
||||||
_phantom_n: PhantomData<N>,
|
_phantom_n: PhantomData<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec, N: Unsigned> serde::de::Visitor<'a> for ListOfBytesListVisitor<T, N> {
|
impl<'a, M: Unsigned, N: Unsigned> serde::de::Visitor<'a> for ListOfBytesListVisitor<M, N> {
|
||||||
type Value = Value<T, N>;
|
type Value = Value<M, N>;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
write!(formatter, "a list of 0x-prefixed byte lists")
|
write!(formatter, "a list of 0x-prefixed byte lists")
|
||||||
@ -433,10 +434,9 @@ pub mod serde_transactions {
|
|||||||
|
|
||||||
while let Some(val) = seq.next_element::<String>()? {
|
while let Some(val) = seq.next_element::<String>()? {
|
||||||
let inner_vec = hex::decode(&val).map_err(de::Error::custom)?;
|
let inner_vec = hex::decode(&val).map_err(de::Error::custom)?;
|
||||||
let opaque_transaction = VariableList::new(inner_vec).map_err(|e| {
|
let transaction = VariableList::new(inner_vec).map_err(|e| {
|
||||||
serde::de::Error::custom(format!("transaction too large: {:?}", e))
|
serde::de::Error::custom(format!("transaction too large: {:?}", e))
|
||||||
})?;
|
})?;
|
||||||
let transaction = Transaction::OpaqueTransaction(opaque_transaction);
|
|
||||||
outer.push(transaction).map_err(|e| {
|
outer.push(transaction).map_err(|e| {
|
||||||
serde::de::Error::custom(format!("too many transactions: {:?}", e))
|
serde::de::Error::custom(format!("too many transactions: {:?}", e))
|
||||||
})?;
|
})?;
|
||||||
@ -446,8 +446,8 @@ pub mod serde_transactions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize<S, T: EthSpec, N: Unsigned>(
|
pub fn serialize<S, M: Unsigned, N: Unsigned>(
|
||||||
value: &Value<T, N>,
|
value: &Value<M, N>,
|
||||||
serializer: S,
|
serializer: S,
|
||||||
) -> Result<S::Ok, S::Error>
|
) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
@ -458,21 +458,19 @@ pub mod serde_transactions {
|
|||||||
// It's important to match on the inner values of the transaction. Serializing the
|
// It's important to match on the inner values of the transaction. Serializing the
|
||||||
// entire `Transaction` will result in appending the SSZ union prefix byte. The
|
// entire `Transaction` will result in appending the SSZ union prefix byte. The
|
||||||
// execution node does not want that.
|
// execution node does not want that.
|
||||||
let hex = match transaction {
|
let hex = hex::encode(&transaction[..]);
|
||||||
Transaction::OpaqueTransaction(val) => hex::encode(&val[..]),
|
|
||||||
};
|
|
||||||
seq.serialize_element(&hex)?;
|
seq.serialize_element(&hex)?;
|
||||||
}
|
}
|
||||||
seq.end()
|
seq.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize<'de, D, T: EthSpec, N: Unsigned>(
|
pub fn deserialize<'de, D, M: Unsigned, N: Unsigned>(
|
||||||
deserializer: D,
|
deserializer: D,
|
||||||
) -> Result<Value<T, N>, D::Error>
|
) -> Result<Value<M, N>, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let visitor: ListOfBytesListVisitor<T, N> = <_>::default();
|
let visitor: ListOfBytesListVisitor<M, N> = <_>::default();
|
||||||
deserializer.deserialize_any(visitor)
|
deserializer.deserialize_any(visitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,7 +556,10 @@ mod test {
|
|||||||
const LOGS_BLOOM_01: &str = "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";
|
const LOGS_BLOOM_01: &str = "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101";
|
||||||
|
|
||||||
fn encode_transactions<E: EthSpec>(
|
fn encode_transactions<E: EthSpec>(
|
||||||
transactions: VariableList<Transaction<E>, E::MaxTransactionsPerPayload>,
|
transactions: VariableList<
|
||||||
|
Transaction<E::MaxBytesPerTransaction>,
|
||||||
|
E::MaxTransactionsPerPayload,
|
||||||
|
>,
|
||||||
) -> Result<serde_json::Value, serde_json::Error> {
|
) -> Result<serde_json::Value, serde_json::Error> {
|
||||||
let ep: JsonExecutionPayload<E> = JsonExecutionPayload {
|
let ep: JsonExecutionPayload<E> = JsonExecutionPayload {
|
||||||
transactions,
|
transactions,
|
||||||
@ -570,7 +571,10 @@ mod test {
|
|||||||
|
|
||||||
fn decode_transactions<E: EthSpec>(
|
fn decode_transactions<E: EthSpec>(
|
||||||
transactions: serde_json::Value,
|
transactions: serde_json::Value,
|
||||||
) -> Result<VariableList<Transaction<E>, E::MaxTransactionsPerPayload>, serde_json::Error> {
|
) -> Result<
|
||||||
|
VariableList<Transaction<E::MaxBytesPerTransaction>, E::MaxTransactionsPerPayload>,
|
||||||
|
serde_json::Error,
|
||||||
|
> {
|
||||||
let json = json!({
|
let json = json!({
|
||||||
"parentHash": HASH_00,
|
"parentHash": HASH_00,
|
||||||
"coinbase": ADDRESS_01,
|
"coinbase": ADDRESS_01,
|
||||||
@ -593,17 +597,17 @@ mod test {
|
|||||||
|
|
||||||
fn assert_transactions_serde<E: EthSpec>(
|
fn assert_transactions_serde<E: EthSpec>(
|
||||||
name: &str,
|
name: &str,
|
||||||
as_obj: VariableList<Transaction<E>, E::MaxTransactionsPerPayload>,
|
as_obj: VariableList<Transaction<E::MaxBytesPerTransaction>, E::MaxTransactionsPerPayload>,
|
||||||
as_json: serde_json::Value,
|
as_json: serde_json::Value,
|
||||||
) {
|
) {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
encode_transactions(as_obj.clone()).unwrap(),
|
encode_transactions::<E>(as_obj.clone()).unwrap(),
|
||||||
as_json,
|
as_json,
|
||||||
"encoding for {}",
|
"encoding for {}",
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
decode_transactions(as_json).unwrap(),
|
decode_transactions::<E>(as_json).unwrap(),
|
||||||
as_obj,
|
as_obj,
|
||||||
"decoding for {}",
|
"decoding for {}",
|
||||||
name
|
name
|
||||||
@ -611,9 +615,9 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Example: if `spec == &[1, 1]`, then two one-byte transactions will be created.
|
/// Example: if `spec == &[1, 1]`, then two one-byte transactions will be created.
|
||||||
fn generate_opaque_transactions<E: EthSpec>(
|
fn generate_transactions<E: EthSpec>(
|
||||||
spec: &[usize],
|
spec: &[usize],
|
||||||
) -> VariableList<Transaction<E>, E::MaxTransactionsPerPayload> {
|
) -> VariableList<Transaction<E::MaxBytesPerTransaction>, E::MaxTransactionsPerPayload> {
|
||||||
let mut txs = VariableList::default();
|
let mut txs = VariableList::default();
|
||||||
|
|
||||||
for &num_bytes in spec {
|
for &num_bytes in spec {
|
||||||
@ -621,7 +625,7 @@ mod test {
|
|||||||
for _ in 0..num_bytes {
|
for _ in 0..num_bytes {
|
||||||
tx.push(0).unwrap();
|
tx.push(0).unwrap();
|
||||||
}
|
}
|
||||||
txs.push(Transaction::OpaqueTransaction(tx)).unwrap();
|
txs.push(tx).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
txs
|
txs
|
||||||
@ -631,32 +635,32 @@ mod test {
|
|||||||
fn transaction_serde() {
|
fn transaction_serde() {
|
||||||
assert_transactions_serde::<MainnetEthSpec>(
|
assert_transactions_serde::<MainnetEthSpec>(
|
||||||
"empty",
|
"empty",
|
||||||
generate_opaque_transactions(&[]),
|
generate_transactions::<MainnetEthSpec>(&[]),
|
||||||
json!([]),
|
json!([]),
|
||||||
);
|
);
|
||||||
assert_transactions_serde::<MainnetEthSpec>(
|
assert_transactions_serde::<MainnetEthSpec>(
|
||||||
"one empty tx",
|
"one empty tx",
|
||||||
generate_opaque_transactions(&[0]),
|
generate_transactions::<MainnetEthSpec>(&[0]),
|
||||||
json!(["0x"]),
|
json!(["0x"]),
|
||||||
);
|
);
|
||||||
assert_transactions_serde::<MainnetEthSpec>(
|
assert_transactions_serde::<MainnetEthSpec>(
|
||||||
"two empty txs",
|
"two empty txs",
|
||||||
generate_opaque_transactions(&[0, 0]),
|
generate_transactions::<MainnetEthSpec>(&[0, 0]),
|
||||||
json!(["0x", "0x"]),
|
json!(["0x", "0x"]),
|
||||||
);
|
);
|
||||||
assert_transactions_serde::<MainnetEthSpec>(
|
assert_transactions_serde::<MainnetEthSpec>(
|
||||||
"one one-byte tx",
|
"one one-byte tx",
|
||||||
generate_opaque_transactions(&[1]),
|
generate_transactions::<MainnetEthSpec>(&[1]),
|
||||||
json!(["0x00"]),
|
json!(["0x00"]),
|
||||||
);
|
);
|
||||||
assert_transactions_serde::<MainnetEthSpec>(
|
assert_transactions_serde::<MainnetEthSpec>(
|
||||||
"two one-byte txs",
|
"two one-byte txs",
|
||||||
generate_opaque_transactions(&[1, 1]),
|
generate_transactions::<MainnetEthSpec>(&[1, 1]),
|
||||||
json!(["0x00", "0x00"]),
|
json!(["0x00", "0x00"]),
|
||||||
);
|
);
|
||||||
assert_transactions_serde::<MainnetEthSpec>(
|
assert_transactions_serde::<MainnetEthSpec>(
|
||||||
"mixed bag",
|
"mixed bag",
|
||||||
generate_opaque_transactions(&[0, 1, 3, 0]),
|
generate_transactions::<MainnetEthSpec>(&[0, 1, 3, 0]),
|
||||||
json!(["0x", "0x00", "0x000000", "0x"]),
|
json!(["0x", "0x00", "0x000000", "0x"]),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -680,7 +684,7 @@ mod test {
|
|||||||
|
|
||||||
use eth2_serde_utils::hex;
|
use eth2_serde_utils::hex;
|
||||||
|
|
||||||
let num_max_bytes = <MainnetEthSpec as EthSpec>::MaxBytesPerOpaqueTransaction::to_usize();
|
let num_max_bytes = <MainnetEthSpec as EthSpec>::MaxBytesPerTransaction::to_usize();
|
||||||
let max_bytes = (0..num_max_bytes).map(|_| 0_u8).collect::<Vec<_>>();
|
let max_bytes = (0..num_max_bytes).map(|_| 0_u8).collect::<Vec<_>>();
|
||||||
let too_many_bytes = (0..=num_max_bytes).map(|_| 0_u8).collect::<Vec<_>>();
|
let too_many_bytes = (0..=num_max_bytes).map(|_| 0_u8).collect::<Vec<_>>();
|
||||||
decode_transactions::<MainnetEthSpec>(
|
decode_transactions::<MainnetEthSpec>(
|
||||||
|
@ -420,6 +420,19 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
|
|||||||
the broad Ethereum community has elected to override the terminal PoW block. \
|
the broad Ethereum community has elected to override the terminal PoW block. \
|
||||||
Incorrect use of this flag will cause your node to experience a consensus
|
Incorrect use of this flag will cause your node to experience a consensus
|
||||||
failure. Be extremely careful with this flag.")
|
failure. Be extremely careful with this flag.")
|
||||||
|
.requires("terminal-block-hash-epoch-override")
|
||||||
|
.takes_value(true)
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("terminal-block-hash-epoch-override")
|
||||||
|
.long("terminal-block-hash-epoch-override")
|
||||||
|
.value_name("EPOCH")
|
||||||
|
.help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH \
|
||||||
|
parameter. This flag should only be used if the user has a clear understanding \
|
||||||
|
that the broad Ethereum community has elected to override the terminal PoW block. \
|
||||||
|
Incorrect use of this flag will cause your node to experience a consensus
|
||||||
|
failure. Be extremely careful with this flag.")
|
||||||
|
.requires("terminal-block-hash-override")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -264,8 +264,10 @@ pub fn get_config<E: EthSpec>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
client_config.fee_recipient = clap_utils::parse_optional(cli_args, "fee-recipient")?;
|
client_config.fee_recipient = clap_utils::parse_optional(cli_args, "fee-recipient")?;
|
||||||
client_config.terminal_block_hash =
|
client_config.terminal_block_hash_override =
|
||||||
clap_utils::parse_optional(cli_args, "terminal-block-hash")?;
|
clap_utils::parse_optional(cli_args, "terminal-block-hash-override")?;
|
||||||
|
client_config.terminal_block_hash_epoch_override =
|
||||||
|
clap_utils::parse_optional(cli_args, "terminal-block-hash-epoch-override")?;
|
||||||
|
|
||||||
if let Some(freezer_dir) = cli_args.value_of("freezer-dir") {
|
if let Some(freezer_dir) = cli_args.value_of("freezer-dir") {
|
||||||
client_config.freezer_db_path = Some(PathBuf::from(freezer_dir));
|
client_config.freezer_db_path = Some(PathBuf::from(freezer_dir));
|
||||||
|
77
consensus/ssz_types/src/serde_utils/list_of_hex_var_list.rs
Normal file
77
consensus/ssz_types/src/serde_utils/list_of_hex_var_list.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
//! Serialize `VaraibleList<VariableList<u8, M>, N>` as list of 0x-prefixed hex string.
|
||||||
|
use crate::VariableList;
|
||||||
|
use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use typenum::Unsigned;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct WrappedListOwned<N: Unsigned>(
|
||||||
|
#[serde(with = "crate::serde_utils::hex_var_list")] VariableList<u8, N>,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
|
pub struct WrappedListRef<'a, N: Unsigned>(
|
||||||
|
#[serde(with = "crate::serde_utils::hex_var_list")] &'a VariableList<u8, N>,
|
||||||
|
);
|
||||||
|
|
||||||
|
pub fn serialize<S, M, N>(
|
||||||
|
list: &VariableList<VariableList<u8, M>, N>,
|
||||||
|
serializer: S,
|
||||||
|
) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
M: Unsigned,
|
||||||
|
N: Unsigned,
|
||||||
|
{
|
||||||
|
let mut seq = serializer.serialize_seq(Some(list.len()))?;
|
||||||
|
for bytes in list {
|
||||||
|
seq.serialize_element(&WrappedListRef(bytes))?;
|
||||||
|
}
|
||||||
|
seq.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Visitor<M, N> {
|
||||||
|
_phantom_m: PhantomData<M>,
|
||||||
|
_phantom_n: PhantomData<N>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, M, N> serde::de::Visitor<'a> for Visitor<M, N>
|
||||||
|
where
|
||||||
|
M: Unsigned,
|
||||||
|
N: Unsigned,
|
||||||
|
{
|
||||||
|
type Value = VariableList<VariableList<u8, M>, N>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(formatter, "a list of 0x-prefixed hex bytes")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: serde::de::SeqAccess<'a>,
|
||||||
|
{
|
||||||
|
let mut list: VariableList<VariableList<u8, M>, N> = <_>::default();
|
||||||
|
|
||||||
|
while let Some(val) = seq.next_element::<WrappedListOwned<M>>()? {
|
||||||
|
list.push(val.0).map_err(|e| {
|
||||||
|
serde::de::Error::custom(format!("failed to push value to list: {:?}.", e))
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(list)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D, M, N>(
|
||||||
|
deserializer: D,
|
||||||
|
) -> Result<VariableList<VariableList<u8, M>, N>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
M: Unsigned,
|
||||||
|
N: Unsigned,
|
||||||
|
{
|
||||||
|
deserializer.deserialize_seq(Visitor::default())
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
pub mod hex_fixed_vec;
|
pub mod hex_fixed_vec;
|
||||||
pub mod hex_var_list;
|
pub mod hex_var_list;
|
||||||
|
pub mod list_of_hex_var_list;
|
||||||
pub mod quoted_u64_fixed_vec;
|
pub mod quoted_u64_fixed_vec;
|
||||||
pub mod quoted_u64_var_list;
|
pub mod quoted_u64_var_list;
|
||||||
|
@ -31,14 +31,11 @@ pub fn slash_validator<T: EthSpec>(
|
|||||||
.safe_add(validator_effective_balance)?,
|
.safe_add(validator_effective_balance)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let min_slashing_penalty_quotient = match state {
|
|
||||||
BeaconState::Base(_) => spec.min_slashing_penalty_quotient,
|
|
||||||
BeaconState::Altair(_) | BeaconState::Merge(_) => spec.min_slashing_penalty_quotient_altair,
|
|
||||||
};
|
|
||||||
decrease_balance(
|
decrease_balance(
|
||||||
state,
|
state,
|
||||||
slashed_index,
|
slashed_index,
|
||||||
validator_effective_balance.safe_div(min_slashing_penalty_quotient)?,
|
validator_effective_balance
|
||||||
|
.safe_div(spec.min_slashing_penalty_quotient_for_state(state))?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Apply proposer and whistleblower rewards
|
// Apply proposer and whistleblower rewards
|
||||||
|
@ -295,50 +295,6 @@ pub fn get_new_eth1_data<T: EthSpec>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#is_valid_gas_limit
|
|
||||||
pub fn verify_is_valid_gas_limit<T: EthSpec>(
|
|
||||||
payload: &ExecutionPayload<T>,
|
|
||||||
parent: &ExecutionPayloadHeader<T>,
|
|
||||||
) -> Result<(), BlockProcessingError> {
|
|
||||||
// check if payload used too much gas
|
|
||||||
if payload.gas_used > payload.gas_limit {
|
|
||||||
return Err(BlockProcessingError::ExecutionInvalidGasLimit {
|
|
||||||
used: payload.gas_used,
|
|
||||||
limit: payload.gas_limit,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// check if payload changed the gas limit too much
|
|
||||||
if payload.gas_limit
|
|
||||||
>= parent
|
|
||||||
.gas_limit
|
|
||||||
.safe_add(parent.gas_limit.safe_div(T::gas_limit_denominator())?)?
|
|
||||||
{
|
|
||||||
return Err(BlockProcessingError::ExecutionInvalidGasLimitIncrease {
|
|
||||||
limit: payload.gas_limit,
|
|
||||||
parent_limit: parent.gas_limit,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if payload.gas_limit
|
|
||||||
<= parent
|
|
||||||
.gas_limit
|
|
||||||
.safe_sub(parent.gas_limit.safe_div(T::gas_limit_denominator())?)?
|
|
||||||
{
|
|
||||||
return Err(BlockProcessingError::ExecutionInvalidGasLimitDecrease {
|
|
||||||
limit: payload.gas_limit,
|
|
||||||
parent_limit: parent.gas_limit,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// check if the gas limit is at least the minimum gas limit
|
|
||||||
if payload.gas_limit < T::min_gas_limit() {
|
|
||||||
return Err(BlockProcessingError::ExecutionInvalidGasLimitTooSmall {
|
|
||||||
limit: payload.gas_limit,
|
|
||||||
min: T::min_gas_limit(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#process_execution_payload
|
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/beacon-chain.md#process_execution_payload
|
||||||
pub fn process_execution_payload<T: EthSpec>(
|
pub fn process_execution_payload<T: EthSpec>(
|
||||||
state: &mut BeaconState<T>,
|
state: &mut BeaconState<T>,
|
||||||
@ -353,21 +309,6 @@ pub fn process_execution_payload<T: EthSpec>(
|
|||||||
found: payload.parent_hash,
|
found: payload.parent_hash,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
block_verify!(
|
|
||||||
payload.block_number
|
|
||||||
== state
|
|
||||||
.latest_execution_payload_header()?
|
|
||||||
.block_number
|
|
||||||
.safe_add(1)?,
|
|
||||||
BlockProcessingError::ExecutionBlockNumberIncontiguous {
|
|
||||||
expected: state
|
|
||||||
.latest_execution_payload_header()?
|
|
||||||
.block_number
|
|
||||||
.safe_add(1)?,
|
|
||||||
found: payload.block_number,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
verify_is_valid_gas_limit(payload, state.latest_execution_payload_header()?)?;
|
|
||||||
}
|
}
|
||||||
block_verify!(
|
block_verify!(
|
||||||
payload.random == *state.get_randao_mix(state.current_epoch())?,
|
payload.random == *state.get_randao_mix(state.current_epoch())?,
|
||||||
|
@ -61,30 +61,10 @@ pub enum BlockProcessingError {
|
|||||||
expected: Hash256,
|
expected: Hash256,
|
||||||
found: Hash256,
|
found: Hash256,
|
||||||
},
|
},
|
||||||
ExecutionBlockNumberIncontiguous {
|
|
||||||
expected: u64,
|
|
||||||
found: u64,
|
|
||||||
},
|
|
||||||
ExecutionRandaoMismatch {
|
ExecutionRandaoMismatch {
|
||||||
expected: Hash256,
|
expected: Hash256,
|
||||||
found: Hash256,
|
found: Hash256,
|
||||||
},
|
},
|
||||||
ExecutionInvalidGasLimit {
|
|
||||||
used: u64,
|
|
||||||
limit: u64,
|
|
||||||
},
|
|
||||||
ExecutionInvalidGasLimitIncrease {
|
|
||||||
limit: u64,
|
|
||||||
parent_limit: u64,
|
|
||||||
},
|
|
||||||
ExecutionInvalidGasLimitDecrease {
|
|
||||||
limit: u64,
|
|
||||||
parent_limit: u64,
|
|
||||||
},
|
|
||||||
ExecutionInvalidGasLimitTooSmall {
|
|
||||||
limit: u64,
|
|
||||||
min: u64,
|
|
||||||
},
|
|
||||||
ExecutionInvalidTimestamp {
|
ExecutionInvalidTimestamp {
|
||||||
expected: u64,
|
expected: u64,
|
||||||
found: u64,
|
found: u64,
|
||||||
|
@ -47,7 +47,6 @@ pub fn process_epoch<T: EthSpec>(
|
|||||||
process_slashings(
|
process_slashings(
|
||||||
state,
|
state,
|
||||||
participation_cache.current_epoch_total_active_balance(),
|
participation_cache.current_epoch_total_active_balance(),
|
||||||
spec.proportional_slashing_multiplier_altair,
|
|
||||||
spec,
|
spec,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ pub fn get_inactivity_penalty_deltas<T: EthSpec>(
|
|||||||
.safe_mul(state.get_inactivity_score(index)?)?;
|
.safe_mul(state.get_inactivity_score(index)?)?;
|
||||||
let penalty_denominator = spec
|
let penalty_denominator = spec
|
||||||
.inactivity_score_bias
|
.inactivity_score_bias
|
||||||
.safe_mul(spec.inactivity_penalty_quotient_altair)?;
|
.safe_mul(spec.inactivity_penalty_quotient_for_state(state))?;
|
||||||
delta.penalize(penalty_numerator.safe_div(penalty_denominator)?)?;
|
delta.penalize(penalty_numerator.safe_div(penalty_denominator)?)?;
|
||||||
}
|
}
|
||||||
deltas
|
deltas
|
||||||
|
@ -43,7 +43,6 @@ pub fn process_epoch<T: EthSpec>(
|
|||||||
process_slashings(
|
process_slashings(
|
||||||
state,
|
state,
|
||||||
validator_statuses.total_balances.current_epoch(),
|
validator_statuses.total_balances.current_epoch(),
|
||||||
spec.proportional_slashing_multiplier,
|
|
||||||
spec,
|
spec,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -6,14 +6,15 @@ use types::{BeaconState, BeaconStateError, ChainSpec, EthSpec, Unsigned};
|
|||||||
pub fn process_slashings<T: EthSpec>(
|
pub fn process_slashings<T: EthSpec>(
|
||||||
state: &mut BeaconState<T>,
|
state: &mut BeaconState<T>,
|
||||||
total_balance: u64,
|
total_balance: u64,
|
||||||
slashing_multiplier: u64,
|
|
||||||
spec: &ChainSpec,
|
spec: &ChainSpec,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let epoch = state.current_epoch();
|
let epoch = state.current_epoch();
|
||||||
let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?;
|
let sum_slashings = state.get_all_slashings().iter().copied().safe_sum()?;
|
||||||
|
|
||||||
let adjusted_total_slashing_balance =
|
let adjusted_total_slashing_balance = std::cmp::min(
|
||||||
std::cmp::min(sum_slashings.safe_mul(slashing_multiplier)?, total_balance);
|
sum_slashings.safe_mul(spec.proportional_slashing_multiplier_for_state(state))?,
|
||||||
|
total_balance,
|
||||||
|
);
|
||||||
|
|
||||||
let (validators, balances) = state.validators_and_balances_mut();
|
let (validators, balances) = state.validators_and_balances_mut();
|
||||||
for (index, validator) in validators.iter().enumerate() {
|
for (index, validator) in validators.iter().enumerate() {
|
||||||
|
@ -127,11 +127,19 @@ pub struct ChainSpec {
|
|||||||
pub altair_fork_version: [u8; 4],
|
pub altair_fork_version: [u8; 4],
|
||||||
/// The Altair fork epoch is optional, with `None` representing "Altair never happens".
|
/// The Altair fork epoch is optional, with `None` representing "Altair never happens".
|
||||||
pub altair_fork_epoch: Option<Epoch>,
|
pub altair_fork_epoch: Option<Epoch>,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Merge hard fork params
|
||||||
|
*/
|
||||||
|
pub inactivity_penalty_quotient_merge: u64,
|
||||||
|
pub min_slashing_penalty_quotient_merge: u64,
|
||||||
|
pub proportional_slashing_multiplier_merge: u64,
|
||||||
pub merge_fork_version: [u8; 4],
|
pub merge_fork_version: [u8; 4],
|
||||||
/// The Merge fork epoch is optional, with `None` representing "Merge never happens".
|
/// The Merge fork epoch is optional, with `None` representing "Merge never happens".
|
||||||
pub merge_fork_epoch: Option<Epoch>,
|
pub merge_fork_epoch: Option<Epoch>,
|
||||||
pub terminal_total_difficulty: Uint256,
|
pub terminal_total_difficulty: Uint256,
|
||||||
pub terminal_block_hash: Hash256,
|
pub terminal_block_hash: Hash256,
|
||||||
|
pub terminal_block_hash_activation_epoch: Epoch,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Networking
|
* Networking
|
||||||
@ -235,6 +243,39 @@ impl ChainSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For a given `BeaconState`, return the inactivity penalty quotient associated with its variant.
|
||||||
|
pub fn inactivity_penalty_quotient_for_state<T: EthSpec>(&self, state: &BeaconState<T>) -> u64 {
|
||||||
|
match state {
|
||||||
|
BeaconState::Base(_) => self.inactivity_penalty_quotient,
|
||||||
|
BeaconState::Altair(_) => self.inactivity_penalty_quotient_altair,
|
||||||
|
BeaconState::Merge(_) => self.inactivity_penalty_quotient_merge,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For a given `BeaconState`, return the proportional slashing multiplier associated with its variant.
|
||||||
|
pub fn proportional_slashing_multiplier_for_state<T: EthSpec>(
|
||||||
|
&self,
|
||||||
|
state: &BeaconState<T>,
|
||||||
|
) -> u64 {
|
||||||
|
match state {
|
||||||
|
BeaconState::Base(_) => self.proportional_slashing_multiplier,
|
||||||
|
BeaconState::Altair(_) => self.proportional_slashing_multiplier_altair,
|
||||||
|
BeaconState::Merge(_) => self.proportional_slashing_multiplier_merge,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For a given `BeaconState`, return the minimum slashing penalty quotient associated with its variant.
|
||||||
|
pub fn min_slashing_penalty_quotient_for_state<T: EthSpec>(
|
||||||
|
&self,
|
||||||
|
state: &BeaconState<T>,
|
||||||
|
) -> u64 {
|
||||||
|
match state {
|
||||||
|
BeaconState::Base(_) => self.min_slashing_penalty_quotient,
|
||||||
|
BeaconState::Altair(_) => self.min_slashing_penalty_quotient_altair,
|
||||||
|
BeaconState::Merge(_) => self.min_slashing_penalty_quotient_merge,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a full `Fork` struct for a given epoch.
|
/// Returns a full `Fork` struct for a given epoch.
|
||||||
pub fn fork_at_epoch(&self, epoch: Epoch) -> Fork {
|
pub fn fork_at_epoch(&self, epoch: Epoch) -> Fork {
|
||||||
let current_fork_name = self.fork_name_at_epoch(epoch);
|
let current_fork_name = self.fork_name_at_epoch(epoch);
|
||||||
@ -367,7 +408,7 @@ impl ChainSpec {
|
|||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
genesis_slot: Slot::new(0),
|
genesis_slot: Slot::new(0),
|
||||||
far_future_epoch: Epoch::new(u64::max_value()),
|
far_future_epoch: Epoch::new(u64::MAX),
|
||||||
base_rewards_per_epoch: 4,
|
base_rewards_per_epoch: 4,
|
||||||
deposit_contract_tree_depth: 32,
|
deposit_contract_tree_depth: 32,
|
||||||
|
|
||||||
@ -479,12 +520,22 @@ impl ChainSpec {
|
|||||||
domain_contribution_and_proof: 9,
|
domain_contribution_and_proof: 9,
|
||||||
altair_fork_version: [0x01, 0x00, 0x00, 0x00],
|
altair_fork_version: [0x01, 0x00, 0x00, 0x00],
|
||||||
altair_fork_epoch: Some(Epoch::new(74240)),
|
altair_fork_epoch: Some(Epoch::new(74240)),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Merge hard fork params
|
||||||
|
*/
|
||||||
|
inactivity_penalty_quotient_merge: u64::checked_pow(2, 24)
|
||||||
|
.expect("pow does not overflow"),
|
||||||
|
min_slashing_penalty_quotient_merge: u64::checked_pow(2, 5)
|
||||||
|
.expect("pow does not overflow"),
|
||||||
|
proportional_slashing_multiplier_merge: 3,
|
||||||
merge_fork_version: [0x02, 0x00, 0x00, 0x00],
|
merge_fork_version: [0x02, 0x00, 0x00, 0x00],
|
||||||
merge_fork_epoch: None,
|
merge_fork_epoch: None,
|
||||||
terminal_total_difficulty: Uint256::MAX
|
terminal_total_difficulty: Uint256::MAX
|
||||||
.checked_sub(Uint256::from(2u64.pow(10)))
|
.checked_sub(Uint256::from(2u64.pow(10)))
|
||||||
.expect("calculation does not overflow"),
|
.expect("calculation does not overflow"),
|
||||||
terminal_block_hash: Hash256::zero(),
|
terminal_block_hash: Hash256::zero(),
|
||||||
|
terminal_block_hash_activation_epoch: Epoch::new(u64::MAX),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Network specific
|
* Network specific
|
||||||
|
@ -3,13 +3,13 @@ use crate::*;
|
|||||||
use safe_arith::SafeArith;
|
use safe_arith::SafeArith;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use ssz_types::typenum::{
|
use ssz_types::typenum::{
|
||||||
Unsigned, U0, U1024, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4, U4096, U512,
|
Unsigned, U0, U1024, U1073741824, U1099511627776, U128, U16, U16777216, U2, U2048, U32, U4,
|
||||||
U64, U65536, U8, U8192,
|
U4096, U512, U64, U65536, U8, U8192,
|
||||||
};
|
};
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use ssz_types::typenum::{bit::B0, UInt, U1048576, U16384, U256, U625};
|
use ssz_types::typenum::{bit::B0, UInt, U1048576, U256, U625};
|
||||||
pub type U5000 = UInt<UInt<UInt<U625, B0>, B0>, B0>; // 625 * 8 = 5000
|
pub type U5000 = UInt<UInt<UInt<U625, B0>, B0>, B0>; // 625 * 8 = 5000
|
||||||
|
|
||||||
const MAINNET: &str = "mainnet";
|
const MAINNET: &str = "mainnet";
|
||||||
@ -86,7 +86,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
/*
|
/*
|
||||||
* New in Merge
|
* New in Merge
|
||||||
*/
|
*/
|
||||||
type MaxBytesPerOpaqueTransaction: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type MaxBytesPerTransaction: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
type MaxTransactionsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type MaxTransactionsPerPayload: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
type BytesPerLogsBloom: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type BytesPerLogsBloom: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
type GasLimitDenominator: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type GasLimitDenominator: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
@ -200,9 +200,9 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
Self::SyncSubcommitteeSize::to_usize()
|
Self::SyncSubcommitteeSize::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `MAX_BYTES_PER_OPAQUE_TRANSACTION` constant for this specification.
|
/// Returns the `MAX_BYTES_PER_TRANSACTION` constant for this specification.
|
||||||
fn max_bytes_per_opaque_transaction() -> usize {
|
fn max_bytes_per_transaction() -> usize {
|
||||||
Self::MaxBytesPerOpaqueTransaction::to_usize()
|
Self::MaxBytesPerTransaction::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `MAX_TRANSACTIONS_PER_PAYLOAD` constant for this specification.
|
/// Returns the `MAX_TRANSACTIONS_PER_PAYLOAD` constant for this specification.
|
||||||
@ -214,16 +214,6 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
fn bytes_per_logs_bloom() -> usize {
|
fn bytes_per_logs_bloom() -> usize {
|
||||||
Self::BytesPerLogsBloom::to_usize()
|
Self::BytesPerLogsBloom::to_usize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `GAS_LIMIT_DENOMINATOR` constant for this specification.
|
|
||||||
fn gas_limit_denominator() -> u64 {
|
|
||||||
Self::GasLimitDenominator::to_u64()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the `MIN_GAS_LIMIT` constant for this specification.
|
|
||||||
fn min_gas_limit() -> u64 {
|
|
||||||
Self::MinGasLimit::to_u64()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to inherit some type values from another EthSpec.
|
/// Macro to inherit some type values from another EthSpec.
|
||||||
@ -258,8 +248,8 @@ impl EthSpec for MainnetEthSpec {
|
|||||||
type MaxVoluntaryExits = U16;
|
type MaxVoluntaryExits = U16;
|
||||||
type SyncCommitteeSize = U512;
|
type SyncCommitteeSize = U512;
|
||||||
type SyncCommitteeSubnetCount = U4;
|
type SyncCommitteeSubnetCount = U4;
|
||||||
type MaxBytesPerOpaqueTransaction = U1048576;
|
type MaxBytesPerTransaction = U1073741824; // 1,073,741,824
|
||||||
type MaxTransactionsPerPayload = U16384;
|
type MaxTransactionsPerPayload = U1048576; // 1,048,576
|
||||||
type BytesPerLogsBloom = U256;
|
type BytesPerLogsBloom = U256;
|
||||||
type GasLimitDenominator = U1024;
|
type GasLimitDenominator = U1024;
|
||||||
type MinGasLimit = U5000;
|
type MinGasLimit = U5000;
|
||||||
@ -306,7 +296,7 @@ impl EthSpec for MinimalEthSpec {
|
|||||||
MaxAttestations,
|
MaxAttestations,
|
||||||
MaxDeposits,
|
MaxDeposits,
|
||||||
MaxVoluntaryExits,
|
MaxVoluntaryExits,
|
||||||
MaxBytesPerOpaqueTransaction,
|
MaxBytesPerTransaction,
|
||||||
MaxTransactionsPerPayload,
|
MaxTransactionsPerPayload,
|
||||||
BytesPerLogsBloom,
|
BytesPerLogsBloom,
|
||||||
GasLimitDenominator,
|
GasLimitDenominator,
|
||||||
|
@ -1,41 +1,10 @@
|
|||||||
use crate::{test_utils::TestRandom, *};
|
use crate::{test_utils::TestRandom, *};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
use std::{ops::Index, slice::SliceIndex};
|
|
||||||
use test_random_derive::TestRandom;
|
use test_random_derive::TestRandom;
|
||||||
use tree_hash_derive::TreeHash;
|
use tree_hash_derive::TreeHash;
|
||||||
|
|
||||||
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
pub type Transaction<T> = VariableList<u8, T>;
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TreeHash)]
|
|
||||||
#[ssz(enum_behaviour = "union")]
|
|
||||||
#[tree_hash(enum_behaviour = "union")]
|
|
||||||
#[serde(tag = "selector", content = "value")]
|
|
||||||
#[serde(bound = "T: EthSpec")]
|
|
||||||
pub enum Transaction<T: EthSpec> {
|
|
||||||
// FIXME(merge): renaming this enum variant to 0 is a bit of a hack...
|
|
||||||
#[serde(rename = "0")]
|
|
||||||
OpaqueTransaction(
|
|
||||||
#[serde(with = "ssz_types::serde_utils::hex_var_list")]
|
|
||||||
VariableList<u8, T::MaxBytesPerOpaqueTransaction>,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: EthSpec, I: SliceIndex<[u8]>> Index<I> for Transaction<T> {
|
|
||||||
type Output = I::Output;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn index(&self, index: I) -> &Self::Output {
|
|
||||||
match self {
|
|
||||||
Self::OpaqueTransaction(v) => Index::index(v, index),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: EthSpec> From<VariableList<u8, T::MaxBytesPerOpaqueTransaction>> for Transaction<T> {
|
|
||||||
fn from(list: VariableList<u8, <T as EthSpec>::MaxBytesPerOpaqueTransaction>) -> Self {
|
|
||||||
Self::OpaqueTransaction(list)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
|
||||||
#[derive(
|
#[derive(
|
||||||
@ -62,8 +31,9 @@ pub struct ExecutionPayload<T: EthSpec> {
|
|||||||
pub extra_data: VariableList<u8, T::MaxExtraDataBytes>,
|
pub extra_data: VariableList<u8, T::MaxExtraDataBytes>,
|
||||||
pub base_fee_per_gas: Hash256,
|
pub base_fee_per_gas: Hash256,
|
||||||
pub block_hash: Hash256,
|
pub block_hash: Hash256,
|
||||||
#[test_random(default)]
|
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
|
||||||
pub transactions: VariableList<Transaction<T>, T::MaxTransactionsPerPayload>,
|
pub transactions:
|
||||||
|
VariableList<Transaction<T::MaxBytesPerTransaction>, T::MaxTransactionsPerPayload>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> ExecutionPayload<T> {
|
impl<T: EthSpec> ExecutionPayload<T> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TESTS_TAG := v1.1.3
|
TESTS_TAG := v1.1.5
|
||||||
TESTS = general minimal mainnet
|
TESTS = general minimal mainnet
|
||||||
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
|
TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS))
|
||||||
|
|
||||||
|
@ -138,7 +138,6 @@ impl<E: EthSpec> EpochTransition<E> for Slashings {
|
|||||||
process_slashings(
|
process_slashings(
|
||||||
state,
|
state,
|
||||||
validator_statuses.total_balances.current_epoch(),
|
validator_statuses.total_balances.current_epoch(),
|
||||||
spec.proportional_slashing_multiplier,
|
|
||||||
spec,
|
spec,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@ -148,7 +147,6 @@ impl<E: EthSpec> EpochTransition<E> for Slashings {
|
|||||||
altair::ParticipationCache::new(state, spec)
|
altair::ParticipationCache::new(state, spec)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.current_epoch_total_active_balance(),
|
.current_epoch_total_active_balance(),
|
||||||
spec.proportional_slashing_multiplier_altair,
|
|
||||||
spec,
|
spec,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user