From 023674ab3b49a4736431c9d3224b66102798ca19 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Wed, 14 Dec 2022 01:20:02 +0000 Subject: [PATCH 01/59] Update Gnosis chain bootnodes (#3793) ## Proposed Changes Update the Gnosis chain bootnodes. The current list of Gnosis bootnodes were abandoned at some point before the Gnosis merge and are now failing to bootstrap peers. There's a workaround list of bootnodes here: https://docs.gnosischain.com/updates/20221208-temporary-bootnodes The list from this PR represents the long-term bootnodes run by the Gnosis team. We will also try to set up SigP bootnodes for Gnosis chain at some point. --- .../built_in_network_configs/gnosis/boot_enr.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/eth2_network_config/built_in_network_configs/gnosis/boot_enr.yaml b/common/eth2_network_config/built_in_network_configs/gnosis/boot_enr.yaml index 4b232d8b324..130c1fa1c32 100644 --- a/common/eth2_network_config/built_in_network_configs/gnosis/boot_enr.yaml +++ b/common/eth2_network_config/built_in_network_configs/gnosis/boot_enr.yaml @@ -1,5 +1,5 @@ # Gnosis Chain Team -- enr:-IS4QGmLwm7gFd0L0CEisllrb1op3v-wAGSc7_pwSMGgN3bOS9Fz7m1dWbwuuPHKqeETz9MbhjVuoWk0ohkyRv98kVoBgmlkgnY0gmlwhGjtlgaJc2VjcDI1NmsxoQLMdh0It9fJbuiLydZ9fpF6MRzgNle0vODaDiMqhbC7WIN1ZHCCIyg -- enr:-IS4QFUVG3dvLPCUEI7ycRvFm0Ieg_ITa5tALmJ9LI7dJ6ieT3J4fF9xLRjOoB4ApV-Rjp7HeLKzyTWG1xRdbFBNZPQBgmlkgnY0gmlwhErP5weJc2VjcDI1NmsxoQOBbaJBvx0-w_pyZUhQl9A510Ho2T0grE0K8JevzES99IN1ZHCCIyg -- enr:-Ku4QOQk8V-Hu2gxFzRXmLYIO4AvWDZhoMFwTf3n3DYm_mbsWv0ZitoqiN6JZUUj6Li6e1Jk1w2zFSVHKPMUP1g5tsgBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD5Jd3FAAAAZP__________gmlkgnY0gmlwhC1PTpmJc2VjcDI1NmsxoQL1Ynt5PoA0UOcHa1Rfn98rmnRlLzNuWTePPP4m4qHVroN1ZHCCKvg -- enr:-Ku4QFaTwgoms-EiiRIfHUH3FXprWUFgjHg4UuWvilqoUQtDbmTszVIxUEOwQUmA2qkiP-T9wXjc_rVUuh9cU7WgwbgBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpD5Jd3FAAAAZP__________gmlkgnY0gmlwhC0hBmCJc2VjcDI1NmsxoQOpsg1XCrXmCwZKcSTcycLwldoKUMHPUpMEVGeg_EEhuYN1ZHCCKvg +- enr:-Ly4QMU1y81COwm1VZgxGF4_eZ21ub9-GHF6dXZ29aEJ0oZpcV2Rysw-viaEKfpcpu9ZarILJLxFZjcKOjE0Sybs3MQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANLnx-Jc2VjcDI1NmsxoQKoaYT8I-wf2I_f_ii6EgoSSXj5T3bhiDyW-7ZLsY3T64hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA +- enr:-Ly4QBf76jLiCA_pDXoZjhyRbuwzFOscFY-MIKkPnmHPQbvaKhIDZutfe38G9ibzgQP0RKrTo3vcWOy4hf_8wOZ-U5MBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhBLGgjaJc2VjcDI1NmsxoQLGeo0Q4lDvxIjHjnkAqEuETTaFIjsNrEcSpdDhcHXWFYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA +- enr:-Ly4QLjZUWdqUO_RwyDqCAccIK5-MbLRD6A2c7oBuVbBgBnWDkEf0UKJVAaJqi2pO101WVQQLYSnYgz1Q3pRhYdrlFoBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANA8sSJc2VjcDI1NmsxoQK4TC_EK1jSs0VVPUpOjIo1rhJmff2SLBPFOWSXMwdLVYhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA +- enr:-Ly4QKwX2rTFtKWKQHSGQFhquxsxL1jewO8JB1MG-jgHqAZVFWxnb3yMoQqnYSV1bk25-_jiLuhIulxar3RBWXEDm6EBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhAN-qZeJc2VjcDI1NmsxoQI7EPGMpecl0QofLp4Wy_lYNCCChUFEH6kY7k-oBGkPFIhzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA From 63c74b37f4805aee853f8be8d9e2e27886ba898f Mon Sep 17 00:00:00 2001 From: Divma Date: Thu, 15 Dec 2022 00:16:38 +0000 Subject: [PATCH 02/59] send error answering bbrange requests when an error occurrs (#3800) ## Issue Addressed While testing withdrawals with @ethDreamer we noticed lighthouse is sending empty batches when an error occurs. As LH peer receiving this, we would consider this a low tolerance action because the peer is claiming the batch is right and is empty. ## Proposed Changes If any kind of error occurs, send a error response instead ## Additional Info Right now we don't handle such thing as a partial batch with an error. If an error is received, the whole batch is discarded. Because of this it makes little sense to send partial batches that end with an error, so it's better to do the proposed solution instead of sending empty batches. --- .../network/src/beacon_processor/worker/rpc_methods.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 3e354a70d21..bfa0ea516fa 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -398,6 +398,15 @@ impl Worker { "block_root" => ?root, "error" => ?e ); + + // send the stream terminator + self.send_error_response( + peer_id, + RPCResponseErrorCode::ServerError, + "Failed fetching blocks".into(), + request_id, + ); + send_response = false; break; } } From 558367ab8c5c2b99c9c5aaca1b4561bbddc9b017 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Fri, 16 Dec 2022 09:20:45 +1100 Subject: [PATCH 03/59] Bounded withdrawals and spec v1.3.0-alpha.2 (#3802) --- .../src/per_block_processing.rs | 33 +++++++++++++++---- consensus/types/presets/gnosis/capella.yaml | 17 ++++++++++ consensus/types/presets/mainnet/capella.yaml | 7 +++- consensus/types/presets/minimal/capella.yaml | 7 +++- consensus/types/src/chain_spec.rs | 6 +++- consensus/types/src/config_and_preset.rs | 25 ++++++++------ consensus/types/src/lib.rs | 4 +-- consensus/types/src/preset.rs | 24 ++++++++++++++ testing/ef_tests/Makefile | 2 +- 9 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 consensus/types/presets/gnosis/capella.yaml diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 52699222600..7af74428b59 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -466,7 +466,9 @@ pub fn compute_timestamp_at_slot( .and_then(|since_genesis| state.genesis_time().safe_add(since_genesis)) } -/// FIXME: add link to this function once the spec is stable +/// Compute the next batch of withdrawals which should be included in a block. +/// +/// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#new-get_expected_withdrawals #[cfg(feature = "withdrawals")] pub fn get_expected_withdrawals( state: &BeaconState, @@ -481,7 +483,11 @@ pub fn get_expected_withdrawals( return Ok(withdrawals.into()); } - for _ in 0..state.validators().len() { + let bound = std::cmp::min( + state.validators().len() as u64, + spec.max_validators_per_withdrawals_sweep, + ); + for _ in 0..bound { let validator = state.get_validator(validator_index as usize)?; let balance = *state.balances().get(validator_index as usize).ok_or( BeaconStateError::BalancesOutOfBounds(validator_index as usize), @@ -518,7 +524,7 @@ pub fn get_expected_withdrawals( Ok(withdrawals.into()) } -/// FIXME: add link to this function once the spec is stable +/// Apply withdrawals to the state. #[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload>( state: &mut BeaconState, @@ -547,11 +553,26 @@ pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload )?; } + // Update the next withdrawal index if this block contained withdrawals if let Some(latest_withdrawal) = expected_withdrawals.last() { *state.next_withdrawal_index_mut()? = latest_withdrawal.index.safe_add(1)?; - let next_validator_index = latest_withdrawal - .validator_index - .safe_add(1)? + + // Update the next validator index to start the next withdrawal sweep + if expected_withdrawals.len() == T::max_withdrawals_per_payload() { + // Next sweep starts after the latest withdrawal's validator index + let next_validator_index = latest_withdrawal + .validator_index + .safe_add(1)? + .safe_rem(state.validators().len() as u64)?; + *state.next_withdrawal_validator_index_mut()? = next_validator_index; + } + } + + // Advance sweep by the max length of the sweep if there was not a full set of withdrawals + if expected_withdrawals.len() != T::max_withdrawals_per_payload() { + let next_validator_index = state + .next_withdrawal_validator_index()? + .safe_add(spec.max_validators_per_withdrawals_sweep)? .safe_rem(state.validators().len() as u64)?; *state.next_withdrawal_validator_index_mut()? = next_validator_index; } diff --git a/consensus/types/presets/gnosis/capella.yaml b/consensus/types/presets/gnosis/capella.yaml new file mode 100644 index 00000000000..913c2956ba7 --- /dev/null +++ b/consensus/types/presets/gnosis/capella.yaml @@ -0,0 +1,17 @@ +# Mainnet preset - Capella + +# Misc +# Max operations per block +# --------------------------------------------------------------- +# 2**4 (= 16) +MAX_BLS_TO_EXECUTION_CHANGES: 16 + +# Execution +# --------------------------------------------------------------- +# 2**4 (= 16) withdrawals +MAX_WITHDRAWALS_PER_PAYLOAD: 16 + +# Withdrawals processing +# --------------------------------------------------------------- +# 2**14 (= 16384) validators +MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16384 diff --git a/consensus/types/presets/mainnet/capella.yaml b/consensus/types/presets/mainnet/capella.yaml index 0c087255bfb..913c2956ba7 100644 --- a/consensus/types/presets/mainnet/capella.yaml +++ b/consensus/types/presets/mainnet/capella.yaml @@ -9,4 +9,9 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16 # Execution # --------------------------------------------------------------- # 2**4 (= 16) withdrawals -MAX_WITHDRAWALS_PER_PAYLOAD: 16 \ No newline at end of file +MAX_WITHDRAWALS_PER_PAYLOAD: 16 + +# Withdrawals processing +# --------------------------------------------------------------- +# 2**14 (= 16384) validators +MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16384 diff --git a/consensus/types/presets/minimal/capella.yaml b/consensus/types/presets/minimal/capella.yaml index eacd6c7cbca..d27253de871 100644 --- a/consensus/types/presets/minimal/capella.yaml +++ b/consensus/types/presets/minimal/capella.yaml @@ -9,4 +9,9 @@ MAX_BLS_TO_EXECUTION_CHANGES: 16 # Execution # --------------------------------------------------------------- # [customized] 2**2 (= 4) -MAX_WITHDRAWALS_PER_PAYLOAD: 4 \ No newline at end of file +MAX_WITHDRAWALS_PER_PAYLOAD: 4 + +# Withdrawals processing +# --------------------------------------------------------------- +# [customized] 2**4 (= 16) validators +MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP: 16 diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index d16c9b8091c..bf9a7ed34db 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -158,8 +158,9 @@ pub struct ChainSpec { * Capella hard fork params */ pub capella_fork_version: [u8; 4], - /// The Capella fork epoch is optional, with `None` representing "Merge never happens". + /// The Capella fork epoch is optional, with `None` representing "Capella never happens". pub capella_fork_epoch: Option, + pub max_validators_per_withdrawals_sweep: u64, /* * Eip4844 hard fork params @@ -634,6 +635,7 @@ impl ChainSpec { */ capella_fork_version: [0x03, 00, 00, 00], capella_fork_epoch: None, + max_validators_per_withdrawals_sweep: 16384, /* * Eip4844 hard fork params @@ -707,6 +709,7 @@ impl ChainSpec { // Capella capella_fork_version: [0x03, 0x00, 0x00, 0x01], capella_fork_epoch: None, + max_validators_per_withdrawals_sweep: 16, // Eip4844 eip4844_fork_version: [0x04, 0x00, 0x00, 0x01], eip4844_fork_epoch: None, @@ -869,6 +872,7 @@ impl ChainSpec { */ capella_fork_version: [0x03, 0x00, 0x00, 0x64], capella_fork_epoch: None, + max_validators_per_withdrawals_sweep: 16384, /* * Eip4844 hard fork params diff --git a/consensus/types/src/config_and_preset.rs b/consensus/types/src/config_and_preset.rs index f72b1710de3..9a618f7cc38 100644 --- a/consensus/types/src/config_and_preset.rs +++ b/consensus/types/src/config_and_preset.rs @@ -1,5 +1,6 @@ use crate::{ - consts::altair, AltairPreset, BasePreset, BellatrixPreset, ChainSpec, Config, EthSpec, ForkName, + consts::altair, AltairPreset, BasePreset, BellatrixPreset, CapellaPreset, ChainSpec, Config, + EthSpec, ForkName, }; use maplit::hashmap; use serde_derive::{Deserialize, Serialize}; @@ -11,7 +12,7 @@ use superstruct::superstruct; /// /// Mostly useful for the API. #[superstruct( - variants(Altair, Bellatrix), + variants(Bellatrix, Capella), variant_attributes(derive(Serialize, Deserialize, Debug, PartialEq, Clone)) )] #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] @@ -24,9 +25,10 @@ pub struct ConfigAndPreset { pub base_preset: BasePreset, #[serde(flatten)] pub altair_preset: AltairPreset, - #[superstruct(only(Bellatrix))] #[serde(flatten)] pub bellatrix_preset: BellatrixPreset, + #[superstruct(only(Capella))] + pub capella_preset: CapellaPreset, /// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks. #[serde(flatten)] pub extra_fields: HashMap, @@ -37,26 +39,29 @@ impl ConfigAndPreset { let config = Config::from_chain_spec::(spec); let base_preset = BasePreset::from_chain_spec::(spec); let altair_preset = AltairPreset::from_chain_spec::(spec); + let bellatrix_preset = BellatrixPreset::from_chain_spec::(spec); let extra_fields = get_extra_fields(spec); - if spec.bellatrix_fork_epoch.is_some() + if spec.capella_fork_epoch.is_some() || fork_name.is_none() - || fork_name == Some(ForkName::Merge) + || fork_name == Some(ForkName::Capella) { - let bellatrix_preset = BellatrixPreset::from_chain_spec::(spec); + let capella_preset = CapellaPreset::from_chain_spec::(spec); - ConfigAndPreset::Bellatrix(ConfigAndPresetBellatrix { + ConfigAndPreset::Capella(ConfigAndPresetCapella { config, base_preset, altair_preset, bellatrix_preset, + capella_preset, extra_fields, }) } else { - ConfigAndPreset::Altair(ConfigAndPresetAltair { + ConfigAndPreset::Bellatrix(ConfigAndPresetBellatrix { config, base_preset, altair_preset, + bellatrix_preset, extra_fields, }) } @@ -131,8 +136,8 @@ mod test { .write(false) .open(tmp_file.as_ref()) .expect("error while opening the file"); - let from: ConfigAndPresetBellatrix = + let from: ConfigAndPresetCapella = serde_yaml::from_reader(reader).expect("error while deserializing"); - assert_eq!(ConfigAndPreset::Bellatrix(from), yamlconfig); + assert_eq!(ConfigAndPreset::Capella(from), yamlconfig); } } diff --git a/consensus/types/src/lib.rs b/consensus/types/src/lib.rs index 92f87f01dd6..6cbb9568dad 100644 --- a/consensus/types/src/lib.rs +++ b/consensus/types/src/lib.rs @@ -124,7 +124,7 @@ pub use crate::bls_to_execution_change::BlsToExecutionChange; pub use crate::chain_spec::{ChainSpec, Config, Domain}; pub use crate::checkpoint::Checkpoint; pub use crate::config_and_preset::{ - ConfigAndPreset, ConfigAndPresetAltair, ConfigAndPresetBellatrix, + ConfigAndPreset, ConfigAndPresetBellatrix, ConfigAndPresetCapella, }; pub use crate::contribution_and_proof::ContributionAndProof; pub use crate::deposit::{Deposit, DEPOSIT_TREE_DEPTH}; @@ -163,7 +163,7 @@ pub use crate::payload::{ FullPayloadCapella, FullPayloadEip4844, FullPayloadMerge, FullPayloadRef, OwnedExecPayload, }; pub use crate::pending_attestation::PendingAttestation; -pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset}; +pub use crate::preset::{AltairPreset, BasePreset, BellatrixPreset, CapellaPreset}; pub use crate::proposer_preparation_data::ProposerPreparationData; pub use crate::proposer_slashing::ProposerSlashing; pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch}; diff --git a/consensus/types/src/preset.rs b/consensus/types/src/preset.rs index 8ee38e46a6d..7d7db228cef 100644 --- a/consensus/types/src/preset.rs +++ b/consensus/types/src/preset.rs @@ -184,6 +184,27 @@ impl BellatrixPreset { } } +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +#[serde(rename_all = "UPPERCASE")] +pub struct CapellaPreset { + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub max_bls_to_execution_changes: u64, + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub max_withdrawals_per_payload: u64, + #[serde(with = "eth2_serde_utils::quoted_u64")] + pub max_validators_per_withdrawals_sweep: u64, +} + +impl CapellaPreset { + pub fn from_chain_spec(spec: &ChainSpec) -> Self { + Self { + max_bls_to_execution_changes: T::max_bls_to_execution_changes() as u64, + max_withdrawals_per_payload: T::max_withdrawals_per_payload() as u64, + max_validators_per_withdrawals_sweep: spec.max_validators_per_withdrawals_sweep, + } + } +} + #[cfg(test)] mod test { use super::*; @@ -219,6 +240,9 @@ mod test { let bellatrix: BellatrixPreset = preset_from_file(&preset_name, "bellatrix.yaml"); assert_eq!(bellatrix, BellatrixPreset::from_chain_spec::(&spec)); + + let capella: CapellaPreset = preset_from_file(&preset_name, "capella.yaml"); + assert_eq!(capella, CapellaPreset::from_chain_spec::(&spec)); } #[test] diff --git a/testing/ef_tests/Makefile b/testing/ef_tests/Makefile index 717ff13c976..d52f546dc26 100644 --- a/testing/ef_tests/Makefile +++ b/testing/ef_tests/Makefile @@ -1,4 +1,4 @@ -TESTS_TAG := v1.3.0-alpha.1 +TESTS_TAG := v1.3.0-alpha.2 TESTS = general minimal mainnet TARBALLS = $(patsubst %,%-$(TESTS_TAG).tar.gz,$(TESTS)) From 0349b104bf648e319c03b8093e0cdbe71354a1c9 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 16 Dec 2022 14:28:14 -0500 Subject: [PATCH 04/59] add blob rpc protocols to --- beacon_node/lighthouse_network/src/rpc/protocol.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 549a0e72073..0773197e865 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -261,6 +261,8 @@ impl UpgradeInfo for RPCProtocol { ProtocolId::new(Protocol::Ping, Version::V1, Encoding::SSZSnappy), ProtocolId::new(Protocol::MetaData, Version::V2, Encoding::SSZSnappy), ProtocolId::new(Protocol::MetaData, Version::V1, Encoding::SSZSnappy), + ProtocolId::new(Protocol::BlobsByRoot, Version::V1, Encoding::SSZSnappy), + ProtocolId::new(Protocol::BlobsByRange, Version::V1, Encoding::SSZSnappy), ]; if self.enable_light_client_server { supported_protocols.push(ProtocolId::new( From ba1cabc0c99e7f53f133933aafe27c0c2d83d0e7 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 16 Dec 2022 14:52:37 -0500 Subject: [PATCH 05/59] Revert "remove json snooper from local testnet scripts" This reverts commit 60d70ca501a46e632e6d563caa00b6032f0dcf75. --- scripts/local_testnet/start_local_testnet.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/local_testnet/start_local_testnet.sh b/scripts/local_testnet/start_local_testnet.sh index a188a1458bc..aa780339b26 100755 --- a/scripts/local_testnet/start_local_testnet.sh +++ b/scripts/local_testnet/start_local_testnet.sh @@ -120,7 +120,7 @@ EL_base_auth_http=5000 (( $VC_COUNT < $BN_COUNT )) && SAS=-s || SAS= for (( el=1; el<=$BN_COUNT; el++ )); do - execute_command_add_PID geth_$el.log ./geth.sh $DATADIR/geth_datadir$el $((EL_base_network + $el)) $((EL_base_http + $el)) $((EL_base_auth_http + $el)) $genesis_file + execute_command_add_PID geth_$el.log ./geth.sh $DATADIR/geth_datadir$el $((EL_base_network + $el)) $((EL_base_http + $el)) $((EL_base_auth_http + $el + 10)) $genesis_file done sleeping 20 @@ -130,6 +130,8 @@ sed -i 's/"shanghaiTime".*$/"shanghaiTime": 0,/g' genesis.json sed -i 's/"shardingForkTime".*$/"shardingForkTime": 0,/g' genesis.json for (( bn=1; bn<=$BN_COUNT; bn++ )); do + + execute_command_add_PID json_snoop_$bn.log json_rpc_snoop -p $((EL_base_auth_http + $bn)) -b 0.0.0.0 http://localhost:$((EL_base_auth_http + $bn + 10)) secret=$DATADIR/geth_datadir$bn/geth/jwtsecret echo $secret execute_command_add_PID beacon_node_$bn.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_$bn $((BN_udp_tcp_base + $bn)) $((BN_http_port_base + $bn)) http://localhost:$((EL_base_auth_http + $bn)) $secret From 22ed36bc6a58a768c0baaa7e80cf44647cea73ee Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 16 Dec 2022 15:16:17 -0500 Subject: [PATCH 06/59] fix is_empty check --- beacon_node/network/src/sync/network_context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 94801aa8711..5a96e19245e 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -50,7 +50,7 @@ impl BlockBlobRequestInfo { } pub fn pop_response(&mut self) -> Option> { - if !self.accumulated_blocks.is_empty() && !self.accumulated_blocks.is_empty() { + if !self.accumulated_blocks.is_empty() && !self.accumulated_sidecars.is_empty() { let beacon_block = self.accumulated_blocks.pop_front().expect("non empty"); let blobs_sidecar = self.accumulated_sidecars.pop_front().expect("non empty"); return Some(SignedBeaconBlockAndBlobsSidecar { From 3a08c7634e68875b40cdee34ba58c6566d397c9f Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Fri, 16 Dec 2022 14:56:07 -0600 Subject: [PATCH 07/59] Make engine_getPayloadV2 accept local block value --- beacon_node/execution_layer/src/engine_api/http.rs | 4 ++-- .../execution_layer/src/engine_api/json_structures.rs | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index c71cfa0c04b..1616b216340 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -760,7 +760,7 @@ impl HttpJsonRpc { ) -> Result, Error> { let params = json!([JsonPayloadIdRequest::from(payload_id)]); - let payload_v2: JsonExecutionPayloadV2 = self + let response: JsonGetPayloadResponse = self .rpc_request( ENGINE_GET_PAYLOAD_V2, params, @@ -768,7 +768,7 @@ impl HttpJsonRpc { ) .await?; - JsonExecutionPayload::V2(payload_v2).try_into_execution_payload(fork_name) + JsonExecutionPayload::V2(response.execution_payload).try_into_execution_payload(fork_name) } pub async fn get_blobs_bundle_v1( diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index feed6215896..18e52eb06f6 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -324,6 +324,15 @@ impl TryFrom> for JsonExecutionPayloadV2 { } } +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[serde(bound = "T: EthSpec", rename_all = "camelCase")] +pub struct JsonGetPayloadResponse { + pub execution_payload: JsonExecutionPayloadV2, + // uncomment this when geth fixes its serialization + //#[serde(with = "eth2_serde_utils::u256_hex_be")] + //pub block_value: Uint256, +} + #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct JsonWithdrawal { From 5de4f5b8d0a956c0a2b2dc5f9faeacab3f8d79a6 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Mon, 19 Dec 2022 11:39:09 -0500 Subject: [PATCH 08/59] handle parent blob request edge cases correctly. fix data availability boundary check --- beacon_node/beacon_chain/src/beacon_chain.rs | 2 + .../beacon_chain/src/blob_verification.rs | 2 + .../beacon_chain/src/block_verification.rs | 96 +++++++++---------- beacon_node/http_api/src/publish_blocks.rs | 25 +++-- .../src/peer_manager/mod.rs | 5 + .../src/rpc/codec/ssz_snappy.rs | 18 +++- .../lighthouse_network/src/service/mod.rs | 6 +- .../beacon_processor/worker/rpc_methods.rs | 8 ++ beacon_node/network/src/router/mod.rs | 5 +- beacon_node/network/src/router/processor.rs | 3 +- beacon_node/network/src/service.rs | 3 +- .../network/src/sync/block_lookups/mod.rs | 36 +++++-- .../src/sync/block_lookups/parent_lookup.rs | 9 +- beacon_node/network/src/sync/manager.rs | 9 +- .../network/src/sync/network_context.rs | 5 +- .../state_processing/src/consensus_context.rs | 9 -- consensus/types/src/signed_block_and_blobs.rs | 13 +-- 17 files changed, 161 insertions(+), 93 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 4c73da695b1..5c6de7b18f6 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2948,6 +2948,8 @@ impl BeaconChain { ops.push(StoreOp::PutState(block.state_root(), &state)); if let Some(blobs) = blobs { + //FIXME(sean) using this for debugging for now + info!(self.log, "Writing blobs to store"; "block_root" => ?block_root); ops.push(StoreOp::PutBlobs(block_root, blobs)); }; let txn_lock = self.store.hot_db.begin_rw_transaction(); diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index ea4ed6e14d9..1b05c7d39f5 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -87,6 +87,8 @@ pub enum BlobError { /// We were unable to process this sync committee message due to an internal error. It's unclear if the /// sync committee message is valid. BeaconChainError(BeaconChainError), + /// No blobs for the specified block where we would expect blobs. + MissingBlobs, } impl From for BlobError { diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 589c0656dbe..b9e65bc0a23 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -579,10 +579,8 @@ pub fn signature_verify_chain_segment( let mut signature_verified_blocks = Vec::with_capacity(chain_segment.len()); for (block_root, block) in &chain_segment { - let mut consensus_context = ConsensusContext::new(block.slot()) - .set_current_block_root(*block_root) - //FIXME(sean) Consider removing this is we pass the blob wrapper everywhere - .set_blobs_sidecar(block.blobs_sidecar()); + let mut consensus_context = + ConsensusContext::new(block.slot()).set_current_block_root(*block_root); signature_verifier.include_all_signatures(block.block(), &mut consensus_context)?; @@ -936,8 +934,7 @@ impl GossipVerifiedBlock { .set_current_block_root(block_root) .set_proposer_index(block.message().proposer_index()) .set_blobs_sidecar_validated(true) // Validated in `validate_blob_for_gossip` - .set_blobs_verified_vs_txs(true) // Validated in `validate_blob_for_gossip` - .set_blobs_sidecar(block.blobs_sidecar()); // TODO: potentially remove + .set_blobs_verified_vs_txs(true); Ok(Self { block, @@ -1009,9 +1006,8 @@ impl SignatureVerifiedBlock { let mut signature_verifier = get_signature_verifier(&state, &pubkey_cache, &chain.spec); - let mut consensus_context = ConsensusContext::new(block.slot()) - .set_current_block_root(block_root) - .set_blobs_sidecar(block.blobs_sidecar()); + let mut consensus_context = + ConsensusContext::new(block.slot()).set_current_block_root(block_root); signature_verifier.include_all_signatures(block.block(), &mut consensus_context)?; @@ -1564,49 +1560,51 @@ impl ExecutionPendingBlock { * Verify kzg proofs and kzg commitments against transactions if required */ //FIXME(sean) should this be prior to applying attestions to fork choice above? done in parallel? - if let Some(ref sidecar) = consensus_context.blobs_sidecar() { - if let Some(data_availability_boundary) = chain.data_availability_boundary() { - if block_slot.epoch(T::EthSpec::slots_per_epoch()) > data_availability_boundary { - let kzg = chain.kzg.as_ref().ok_or(BlockError::BlobValidation( - BlobError::TrustedSetupNotInitialized, - ))?; - let transactions = block - .message() - .body() - .execution_payload_eip4844() - .map(|payload| payload.transactions()) - .map_err(|_| BlockError::BlobValidation(BlobError::TransactionsMissing))? - .ok_or(BlockError::BlobValidation(BlobError::TransactionsMissing))?; - let kzg_commitments = - block.message().body().blob_kzg_commitments().map_err(|_| { - BlockError::BlobValidation(BlobError::KzgCommitmentMissing) - })?; - if !consensus_context.blobs_sidecar_validated() { - if !kzg_utils::validate_blobs_sidecar( - &kzg, - block.slot(), - block_root, - kzg_commitments, - sidecar, - ) - .map_err(|e| BlockError::BlobValidation(BlobError::KzgError(e)))? - { - return Err(BlockError::BlobValidation(BlobError::InvalidKzgProof)); - } - } - if !consensus_context.blobs_verified_vs_txs() - && verify_kzg_commitments_against_transactions::( - transactions, - kzg_commitments, - ) - //FIXME(sean) we should maybe just map this error so we have more info about the mismatch - .is_err() + if let Some(data_availability_boundary) = chain.data_availability_boundary() { + if block_slot.epoch(T::EthSpec::slots_per_epoch()) >= data_availability_boundary { + let sidecar = block + .blobs() + .ok_or(BlockError::BlobValidation(BlobError::MissingBlobs))?; + let kzg = chain.kzg.as_ref().ok_or(BlockError::BlobValidation( + BlobError::TrustedSetupNotInitialized, + ))?; + let transactions = block + .message() + .body() + .execution_payload_eip4844() + .map(|payload| payload.transactions()) + .map_err(|_| BlockError::BlobValidation(BlobError::TransactionsMissing))? + .ok_or(BlockError::BlobValidation(BlobError::TransactionsMissing))?; + let kzg_commitments = block + .message() + .body() + .blob_kzg_commitments() + .map_err(|_| BlockError::BlobValidation(BlobError::KzgCommitmentMissing))?; + if !consensus_context.blobs_sidecar_validated() { + if !kzg_utils::validate_blobs_sidecar( + &kzg, + block.slot(), + block_root, + kzg_commitments, + sidecar, + ) + .map_err(|e| BlockError::BlobValidation(BlobError::KzgError(e)))? { - return Err(BlockError::BlobValidation( - BlobError::TransactionCommitmentMismatch, - )); + return Err(BlockError::BlobValidation(BlobError::InvalidKzgProof)); } } + if !consensus_context.blobs_verified_vs_txs() + && verify_kzg_commitments_against_transactions::( + transactions, + kzg_commitments, + ) + //FIXME(sean) we should maybe just map this error so we have more info about the mismatch + .is_err() + { + return Err(BlockError::BlobValidation( + BlobError::TransactionCommitmentMismatch, + )); + } } } diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index f1c9b5331fd..c2b30d95f81 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -9,6 +9,7 @@ use slot_clock::SlotClock; use std::sync::Arc; use tokio::sync::mpsc::UnboundedSender; use tree_hash::TreeHash; +use types::signed_block_and_blobs::BlockWrapper; use types::{ AbstractExecPayload, BlindedPayload, BlobsSidecar, EthSpec, ExecPayload, ExecutionBlockHash, FullPayload, Hash256, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, @@ -31,13 +32,20 @@ pub async fn publish_block( let block_root = block_root.unwrap_or_else(|| block.canonical_root()); // Send the block, regardless of whether or not it is valid. The API - // specification is very clear that this is the desired behaviour. - let message = if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { + // specification is very clear that this isa the desired behaviour. + let wrapped_block = if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { if let Some(sidecar) = chain.blob_cache.pop(&block_root) { - PubsubMessage::BeaconBlockAndBlobsSidecars(SignedBeaconBlockAndBlobsSidecar { - beacon_block: block.clone(), + let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { + beacon_block: block, blobs_sidecar: Arc::new(sidecar), - }) + }; + crate::publish_pubsub_message( + network_tx, + PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), + )?; + BlockWrapper::BlockAndBlob { + block_sidecar_pair: block_and_blobs, + } } else { //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required return Err(warp_utils::reject::broadcast_without_import(format!( @@ -45,18 +53,19 @@ pub async fn publish_block( ))); } } else { - PubsubMessage::BeaconBlock(block.clone()) + crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; + BlockWrapper::Block { block } }; - crate::publish_pubsub_message(network_tx, message)?; // Determine the delay after the start of the slot, register it with metrics. + let block = wrapped_block.block(); let delay = get_block_delay_ms(seen_timestamp, block.message(), &chain.slot_clock); metrics::observe_duration(&metrics::HTTP_API_BLOCK_BROADCAST_DELAY_TIMES, delay); match chain .process_block( block_root, - block.clone(), + wrapped_block.clone(), CountUnrealized::True, NotifyExecutionLayer::Yes, ) diff --git a/beacon_node/lighthouse_network/src/peer_manager/mod.rs b/beacon_node/lighthouse_network/src/peer_manager/mod.rs index f85ec980df0..64401308cd5 100644 --- a/beacon_node/lighthouse_network/src/peer_manager/mod.rs +++ b/beacon_node/lighthouse_network/src/peer_manager/mod.rs @@ -473,6 +473,11 @@ impl PeerManager { RPCError::ErrorResponse(code, _) => match code { RPCResponseErrorCode::Unknown => PeerAction::HighToleranceError, RPCResponseErrorCode::ResourceUnavailable => { + // Don't ban on this because we want to retry with a block by root request. + if matches!(protocol, Protocol::BlobsByRoot) { + return; + } + // NOTE: This error only makes sense for the `BlocksByRange` and `BlocksByRoot` // protocols. // diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index a70aac34961..ce6e30ebf30 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -531,9 +531,6 @@ fn handle_v2_request( Protocol::BlocksByRoot => Ok(Some(InboundRequest::BlocksByRoot(BlocksByRootRequest { block_roots: VariableList::from_ssz_bytes(decoded_buffer)?, }))), - Protocol::BlobsByRange => Ok(Some(InboundRequest::BlobsByRange( - BlobsByRangeRequest::from_ssz_bytes(decoded_buffer)?, - ))), // MetaData requests return early from InboundUpgrade and do not reach the decoder. // Handle this case just for completeness. Protocol::MetaData => { @@ -826,12 +823,25 @@ mod tests { } } + fn blbrange_request() -> BlobsByRangeRequest { + BlobsByRangeRequest { + start_slot: 0, + count: 10, + } + } + fn bbroot_request() -> BlocksByRootRequest { BlocksByRootRequest { block_roots: VariableList::from(vec![Hash256::zero()]), } } + fn blbroot_request() -> BlobsByRootRequest { + BlobsByRootRequest { + block_roots: VariableList::from(vec![Hash256::zero()]), + } + } + fn ping_message() -> Ping { Ping { data: 1 } } @@ -1454,6 +1464,8 @@ mod tests { OutboundRequest::Goodbye(GoodbyeReason::Fault), OutboundRequest::BlocksByRange(bbrange_request()), OutboundRequest::BlocksByRoot(bbroot_request()), + OutboundRequest::BlobsByRange(blbrange_request()), + OutboundRequest::BlobsByRoot(blbroot_request()), OutboundRequest::MetaData(PhantomData::), ]; for req in requests.iter() { diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index 549fb220957..9adf7699bc2 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -75,6 +75,8 @@ pub enum NetworkEvent { id: AppReqId, /// The peer to which this request was sent. peer_id: PeerId, + /// The error of the failed request. + error: RPCError, }, RequestReceived { /// The peer that sent the request. @@ -1177,9 +1179,9 @@ impl Network { &error, ConnectionDirection::Outgoing, ); - // inform failures of requests comming outside the behaviour + // inform failures of requests coming outside the behaviour if let RequestId::Application(id) = id { - Some(NetworkEvent::RPCFailed { peer_id, id }) + Some(NetworkEvent::RPCFailed { peer_id, id, error }) } else { None } diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 87e8a3fc4ea..6eae7eed59b 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -254,6 +254,14 @@ impl Worker { "peer" => %peer_id, "request_root" => ?root ); + self.send_error_response( + peer_id, + RPCResponseErrorCode::ResourceUnavailable, + "No blob for requested block".into(), + request_id, + ); + send_response = false; + break; } Ok((None, Some(_))) => { debug!( diff --git a/beacon_node/network/src/router/mod.rs b/beacon_node/network/src/router/mod.rs index 5675cb0adf6..31f2092049f 100644 --- a/beacon_node/network/src/router/mod.rs +++ b/beacon_node/network/src/router/mod.rs @@ -11,6 +11,7 @@ use crate::error; use crate::service::{NetworkMessage, RequestId}; use beacon_chain::{BeaconChain, BeaconChainTypes}; use futures::prelude::*; +use lighthouse_network::rpc::RPCError; use lighthouse_network::{ MessageId, NetworkGlobals, PeerId, PeerRequestId, PubsubMessage, Request, Response, }; @@ -58,6 +59,7 @@ pub enum RouterMessage { RPCFailed { peer_id: PeerId, request_id: RequestId, + error: RPCError, }, /// A gossip message has been received. The fields are: message id, the peer that sent us this /// message, the message itself and a bool which indicates if the message should be processed @@ -140,8 +142,9 @@ impl Router { RouterMessage::RPCFailed { peer_id, request_id, + error, } => { - self.processor.on_rpc_error(peer_id, request_id); + self.processor.on_rpc_error(peer_id, request_id, error); } RouterMessage::PubsubMessage(id, peer_id, gossip, should_process) => { self.handle_gossip(id, peer_id, gossip, should_process); diff --git a/beacon_node/network/src/router/processor.rs b/beacon_node/network/src/router/processor.rs index 97c2b226438..5ee0e367b68 100644 --- a/beacon_node/network/src/router/processor.rs +++ b/beacon_node/network/src/router/processor.rs @@ -103,12 +103,13 @@ impl Processor { /// An error occurred during an RPC request. The state is maintained by the sync manager, so /// this function notifies the sync manager of the error. - pub fn on_rpc_error(&mut self, peer_id: PeerId, request_id: RequestId) { + pub fn on_rpc_error(&mut self, peer_id: PeerId, request_id: RequestId, error: RPCError) { // Check if the failed RPC belongs to sync if let RequestId::Sync(request_id) = request_id { self.send_to_sync(SyncMessage::RpcError { peer_id, request_id, + error, }); } } diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs index 4568ed1a229..201494a3450 100644 --- a/beacon_node/network/src/service.rs +++ b/beacon_node/network/src/service.rs @@ -499,10 +499,11 @@ impl NetworkService { response, }); } - NetworkEvent::RPCFailed { id, peer_id } => { + NetworkEvent::RPCFailed { id, peer_id, error } => { self.send_to_router(RouterMessage::RPCFailed { peer_id, request_id: id, + error, }); } NetworkEvent::StatusPeer(peer_id) => { diff --git a/beacon_node/network/src/sync/block_lookups/mod.rs b/beacon_node/network/src/sync/block_lookups/mod.rs index 3b0600775f8..ca633ba7603 100644 --- a/beacon_node/network/src/sync/block_lookups/mod.rs +++ b/beacon_node/network/src/sync/block_lookups/mod.rs @@ -6,6 +6,7 @@ use beacon_chain::{BeaconChainTypes, BlockError}; use fnv::FnvHashMap; use futures::StreamExt; use itertools::{Either, Itertools}; +use lighthouse_network::rpc::{RPCError, RPCResponseErrorCode}; use lighthouse_network::{PeerAction, PeerId}; use lru_cache::LRUTimeCache; use slog::{debug, error, trace, warn, Logger}; @@ -40,6 +41,13 @@ pub type RootBlockTuple = (Hash256, BlockWrapper); const FAILED_CHAINS_CACHE_EXPIRY_SECONDS: u64 = 60; const SINGLE_BLOCK_LOOKUP_MAX_ATTEMPTS: u8 = 3; +/// This is used to resolve the scenario where we request a parent from before the data availability +/// boundary and need to retry with a request for only the block. +pub enum ForceBlockRequest { + True, + False, +} + pub(crate) struct BlockLookups { /// Parent chain lookups being downloaded. parent_lookups: SmallVec<[ParentLookup; 3]>, @@ -165,7 +173,7 @@ impl BlockLookups { } let parent_lookup = ParentLookup::new(block_root, block, peer_id); - self.request_parent(parent_lookup, cx); + self.request_parent(parent_lookup, cx, ForceBlockRequest::False); } /* Lookup responses */ @@ -291,7 +299,7 @@ impl BlockLookups { cx.report_peer(peer_id, PeerAction::LowToleranceError, e); // We try again if possible. - self.request_parent(parent_lookup, cx); + self.request_parent(parent_lookup, cx, ForceBlockRequest::False); } VerifyError::PreviousFailure { parent_root } => { debug!( @@ -367,7 +375,7 @@ impl BlockLookups { { let parent_lookup = self.parent_lookups.remove(pos); trace!(self.log, "Parent lookup's peer disconnected"; &parent_lookup); - self.request_parent(parent_lookup, cx); + self.request_parent(parent_lookup, cx, ForceBlockRequest::False); } } @@ -377,6 +385,7 @@ impl BlockLookups { id: Id, peer_id: PeerId, cx: &mut SyncNetworkContext, + error: RPCError, ) { if let Some(pos) = self .parent_lookups @@ -386,7 +395,19 @@ impl BlockLookups { let mut parent_lookup = self.parent_lookups.remove(pos); parent_lookup.download_failed(); trace!(self.log, "Parent lookup request failed"; &parent_lookup); - self.request_parent(parent_lookup, cx); + + // `ResourceUnavailable` indicates we requested a parent block from prior to the 4844 fork epoch. + let force_block_request = if let RPCError::ErrorResponse( + RPCResponseErrorCode::ResourceUnavailable, + _, + ) = error + { + debug!(self.log, "RPC parent lookup for block and blobs failed. Retrying the request for just a block"; "peer_id" => %peer_id); + ForceBlockRequest::True + } else { + ForceBlockRequest::False + }; + self.request_parent(parent_lookup, cx, force_block_request); } else { return debug!(self.log, "RPC failure for a parent lookup request that was not found"; "peer_id" => %peer_id); }; @@ -542,7 +563,7 @@ impl BlockLookups { // need to keep looking for parents // add the block back to the queue and continue the search parent_lookup.add_block(block); - self.request_parent(parent_lookup, cx); + self.request_parent(parent_lookup, cx, ForceBlockRequest::False); } BlockProcessResult::Ok | BlockProcessResult::Err(BlockError::BlockIsAlreadyKnown { .. }) => { @@ -604,7 +625,7 @@ impl BlockLookups { // Try again if possible parent_lookup.processing_failed(); - self.request_parent(parent_lookup, cx); + self.request_parent(parent_lookup, cx, ForceBlockRequest::False); } BlockProcessResult::Ignored => { // Beacon processor signalled to ignore the block processing result. @@ -697,8 +718,9 @@ impl BlockLookups { &mut self, mut parent_lookup: ParentLookup, cx: &mut SyncNetworkContext, + force_block_request: ForceBlockRequest, ) { - match parent_lookup.request_parent(cx) { + match parent_lookup.request_parent(cx, force_block_request) { Err(e) => { debug!(self.log, "Failed to request parent"; &parent_lookup, "error" => e.as_static()); match e { diff --git a/beacon_node/network/src/sync/block_lookups/parent_lookup.rs b/beacon_node/network/src/sync/block_lookups/parent_lookup.rs index 0e9036ceee9..fd17e18db58 100644 --- a/beacon_node/network/src/sync/block_lookups/parent_lookup.rs +++ b/beacon_node/network/src/sync/block_lookups/parent_lookup.rs @@ -6,6 +6,7 @@ use store::{Hash256, SignedBeaconBlock}; use strum::IntoStaticStr; use types::signed_block_and_blobs::BlockWrapper; +use crate::sync::block_lookups::ForceBlockRequest; use crate::sync::{ manager::{Id, SLOT_IMPORT_TOLERANCE}, network_context::SyncNetworkContext, @@ -72,14 +73,18 @@ impl ParentLookup { } /// Attempts to request the next unknown parent. If the request fails, it should be removed. - pub fn request_parent(&mut self, cx: &mut SyncNetworkContext) -> Result<(), RequestError> { + pub fn request_parent( + &mut self, + cx: &mut SyncNetworkContext, + force_block_request: ForceBlockRequest, + ) -> Result<(), RequestError> { // check to make sure this request hasn't failed if self.downloaded_blocks.len() >= PARENT_DEPTH_TOLERANCE { return Err(RequestError::ChainTooLong); } let (peer_id, request) = self.current_parent_request.request_block()?; - match cx.parent_lookup_request(peer_id, request) { + match cx.parent_lookup_request(peer_id, request, force_block_request) { Ok(request_id) => { self.current_parent_request_id = Some(request_id); Ok(()) diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index c55e90cf46b..60105d42252 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -45,6 +45,7 @@ use crate::sync::range_sync::ExpectedBatchTy; use beacon_chain::{BeaconChain, BeaconChainTypes, BlockError, EngineState}; use futures::StreamExt; use lighthouse_network::rpc::methods::MAX_REQUEST_BLOCKS; +use lighthouse_network::rpc::{RPCError, RPCResponseErrorCode}; use lighthouse_network::types::{NetworkGlobals, SyncState}; use lighthouse_network::SyncInfo; use lighthouse_network::{PeerAction, PeerId}; @@ -131,6 +132,7 @@ pub enum SyncMessage { RpcError { peer_id: PeerId, request_id: RequestId, + error: RPCError, }, /// A batch has been processed by the block processor thread. @@ -282,7 +284,7 @@ impl SyncManager { } /// Handles RPC errors related to requests that were emitted from the sync manager. - fn inject_error(&mut self, peer_id: PeerId, request_id: RequestId) { + fn inject_error(&mut self, peer_id: PeerId, request_id: RequestId, error: RPCError) { trace!(self.log, "Sync manager received a failed RPC"); match request_id { RequestId::SingleBlock { id } => { @@ -291,7 +293,7 @@ impl SyncManager { } RequestId::ParentLookup { id } => { self.block_lookups - .parent_lookup_failed(id, peer_id, &mut self.network); + .parent_lookup_failed(id, peer_id, &mut self.network, error); } RequestId::BackFillSync { id } => { if let Some(batch_id) = self @@ -603,7 +605,8 @@ impl SyncManager { SyncMessage::RpcError { peer_id, request_id, - } => self.inject_error(peer_id, request_id), + error, + } => self.inject_error(peer_id, request_id, error), SyncMessage::BlockProcessed { process_type, result, diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 94801aa8711..5917c7ecca2 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -6,6 +6,7 @@ use super::range_sync::{BatchId, ChainId, ExpectedBatchTy}; use crate::beacon_processor::WorkEvent; use crate::service::{NetworkMessage, RequestId}; use crate::status::ToStatusMessage; +use crate::sync::block_lookups::ForceBlockRequest; use beacon_chain::{BeaconChain, BeaconChainTypes, EngineState}; use fnv::FnvHashMap; use lighthouse_network::rpc::methods::BlobsByRangeRequest; @@ -50,7 +51,7 @@ impl BlockBlobRequestInfo { } pub fn pop_response(&mut self) -> Option> { - if !self.accumulated_blocks.is_empty() && !self.accumulated_blocks.is_empty() { + if !self.accumulated_blocks.is_empty() && !self.accumulated_sidecars.is_empty() { let beacon_block = self.accumulated_blocks.pop_front().expect("non empty"); let blobs_sidecar = self.accumulated_sidecars.pop_front().expect("non empty"); return Some(SignedBeaconBlockAndBlobsSidecar { @@ -504,11 +505,13 @@ impl SyncNetworkContext { &mut self, peer_id: PeerId, request: BlocksByRootRequest, + force_block_request: ForceBlockRequest, ) -> Result { let request = if self .chain .is_data_availability_check_required() .map_err(|_| "Unable to read slot clock")? + && matches!(force_block_request, ForceBlockRequest::False) { trace!( self.log, diff --git a/consensus/state_processing/src/consensus_context.rs b/consensus/state_processing/src/consensus_context.rs index d9453d36446..f5585426ce9 100644 --- a/consensus/state_processing/src/consensus_context.rs +++ b/consensus/state_processing/src/consensus_context.rs @@ -185,13 +185,4 @@ impl ConsensusContext { pub fn blobs_verified_vs_txs(&self) -> bool { self.blobs_verified_vs_txs } - - pub fn set_blobs_sidecar(mut self, blobs_sidecar: Option>>) -> Self { - self.blobs_sidecar = blobs_sidecar; - self - } - - pub fn blobs_sidecar(&self) -> Option>> { - self.blobs_sidecar.clone() - } } diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index 9b4517eb47a..09ff89e7b3e 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -66,20 +66,21 @@ impl BlockWrapper { } } } - pub fn blobs_sidecar(&self) -> Option>> { + + pub fn blobs(&self) -> Option<&BlobsSidecar> { match self { - BlockWrapper::Block { block: _ } => None, + BlockWrapper::Block { .. } => None, BlockWrapper::BlockAndBlob { block_sidecar_pair } => { - Some(block_sidecar_pair.blobs_sidecar.clone()) + Some(&block_sidecar_pair.blobs_sidecar) } } } - pub fn blobs(&self) -> Option<&BlobsSidecar> { + pub fn blobs_cloned(&self) -> Option>> { match self { - BlockWrapper::Block { .. } => None, + BlockWrapper::Block { block: _ } => None, BlockWrapper::BlockAndBlob { block_sidecar_pair } => { - Some(&block_sidecar_pair.blobs_sidecar) + Some(block_sidecar_pair.blobs_sidecar.clone()) } } } From eddfb50c586469d8acb4584445931f286670c38b Mon Sep 17 00:00:00 2001 From: realbigsean Date: Mon, 19 Dec 2022 11:39:54 -0500 Subject: [PATCH 09/59] Revert "Revert "remove json snooper from local testnet scripts"" This reverts commit ba1cabc0c99e7f53f133933aafe27c0c2d83d0e7. --- scripts/local_testnet/start_local_testnet.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/local_testnet/start_local_testnet.sh b/scripts/local_testnet/start_local_testnet.sh index aa780339b26..a188a1458bc 100755 --- a/scripts/local_testnet/start_local_testnet.sh +++ b/scripts/local_testnet/start_local_testnet.sh @@ -120,7 +120,7 @@ EL_base_auth_http=5000 (( $VC_COUNT < $BN_COUNT )) && SAS=-s || SAS= for (( el=1; el<=$BN_COUNT; el++ )); do - execute_command_add_PID geth_$el.log ./geth.sh $DATADIR/geth_datadir$el $((EL_base_network + $el)) $((EL_base_http + $el)) $((EL_base_auth_http + $el + 10)) $genesis_file + execute_command_add_PID geth_$el.log ./geth.sh $DATADIR/geth_datadir$el $((EL_base_network + $el)) $((EL_base_http + $el)) $((EL_base_auth_http + $el)) $genesis_file done sleeping 20 @@ -130,8 +130,6 @@ sed -i 's/"shanghaiTime".*$/"shanghaiTime": 0,/g' genesis.json sed -i 's/"shardingForkTime".*$/"shardingForkTime": 0,/g' genesis.json for (( bn=1; bn<=$BN_COUNT; bn++ )); do - - execute_command_add_PID json_snoop_$bn.log json_rpc_snoop -p $((EL_base_auth_http + $bn)) -b 0.0.0.0 http://localhost:$((EL_base_auth_http + $bn + 10)) secret=$DATADIR/geth_datadir$bn/geth/jwtsecret echo $secret execute_command_add_PID beacon_node_$bn.log ./beacon_node.sh $SAS -d $DEBUG_LEVEL $DATADIR/node_$bn $((BN_udp_tcp_base + $bn)) $((BN_http_port_base + $bn)) http://localhost:$((EL_base_auth_http + $bn)) $secret From 3ab0f46077db6ea6c9424366273a45299401f70d Mon Sep 17 00:00:00 2001 From: realbigsean Date: Mon, 19 Dec 2022 12:27:31 -0500 Subject: [PATCH 10/59] Update beacon_node/http_api/src/publish_blocks.rs Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com> --- beacon_node/http_api/src/publish_blocks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index c2b30d95f81..085f5036f4f 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -32,7 +32,7 @@ pub async fn publish_block( let block_root = block_root.unwrap_or_else(|| block.canonical_root()); // Send the block, regardless of whether or not it is valid. The API - // specification is very clear that this isa the desired behaviour. + // specification is very clear that this is the desired behaviour. let wrapped_block = if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { if let Some(sidecar) = chain.blob_cache.pop(&block_root) { let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { From b75ca74222ac1b8dda5efd6a48b1388cd622f372 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Mon, 19 Dec 2022 15:10:50 -0600 Subject: [PATCH 11/59] Removed `withdrawals` feature flag --- .github/workflows/docker.yml | 2 +- Makefile | 2 +- beacon_node/Cargo.toml | 1 - beacon_node/beacon_chain/Cargo.toml | 1 - beacon_node/beacon_chain/src/beacon_chain.rs | 16 +---- .../beacon_chain/src/execution_payload.rs | 21 ++---- beacon_node/execution_layer/Cargo.toml | 1 - beacon_node/execution_layer/src/engine_api.rs | 3 - .../execution_layer/src/engine_api/http.rs | 6 +- .../src/engine_api/json_structures.rs | 8 --- beacon_node/execution_layer/src/lib.rs | 6 -- .../src/test_utils/mock_execution_layer.rs | 3 - beacon_node/store/Cargo.toml | 1 - beacon_node/store/src/partial_beacon_state.rs | 64 ------------------- common/eth2/Cargo.toml | 1 - consensus/state_processing/Cargo.toml | 1 - .../src/per_block_processing.rs | 9 ++- .../block_signature_verifier.rs | 2 - .../process_operations.rs | 4 +- .../state_processing/src/upgrade/capella.rs | 2 - .../state_processing/src/upgrade/eip4844.rs | 10 +-- consensus/types/Cargo.toml | 1 - consensus/types/src/beacon_block.rs | 2 - consensus/types/src/beacon_block_body.rs | 9 --- consensus/types/src/beacon_state.rs | 2 - .../types/src/beacon_state/tree_hash_cache.rs | 2 - consensus/types/src/execution_payload.rs | 1 - .../types/src/execution_payload_header.rs | 5 -- consensus/types/src/payload.rs | 6 -- consensus/types/src/signed_beacon_block.rs | 4 -- lighthouse/Cargo.toml | 2 - testing/ef_tests/src/cases/operations.rs | 10 +-- testing/ef_tests/src/lib.rs | 2 +- testing/ef_tests/tests/tests.rs | 4 +- .../execution_engine_integration/Cargo.toml | 3 +- 35 files changed, 29 insertions(+), 188 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 25d2cdab302..c0a02adf4ed 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -66,7 +66,7 @@ jobs: DOCKER_CLI_EXPERIMENTAL: enabled VERSION: ${{ needs.extract-version.outputs.VERSION }} VERSION_SUFFIX: ${{ needs.extract-version.outputs.VERSION_SUFFIX }} - CROSS_FEATURES: withdrawals,withdrawals-processing + CROSS_FEATURES: withdrawals-processing steps: - uses: actions/checkout@v3 - name: Update Rust diff --git a/Makefile b/Makefile index 56e05fffcb7..15d09c5867f 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ CROSS_FEATURES ?= gnosis,slasher-lmdb,slasher-mdbx CROSS_PROFILE ?= release # List of features to use when running EF tests. -EF_TEST_FEATURES ?= beacon_chain/withdrawals,beacon_chain/withdrawals-processing +EF_TEST_FEATURES ?= beacon_chain/withdrawals-processing # Cargo profile for regular builds. PROFILE ?= release diff --git a/beacon_node/Cargo.toml b/beacon_node/Cargo.toml index 309d7a83f78..bed32011f1b 100644 --- a/beacon_node/Cargo.toml +++ b/beacon_node/Cargo.toml @@ -13,7 +13,6 @@ node_test_rig = { path = "../testing/node_test_rig" } [features] write_ssz_files = ["beacon_chain/write_ssz_files"] # Writes debugging .ssz files to /tmp during block processing. -withdrawals = ["beacon_chain/withdrawals", "types/withdrawals", "store/withdrawals", "execution_layer/withdrawals"] withdrawals-processing = [ "beacon_chain/withdrawals-processing", "store/withdrawals-processing", diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 6d768476e6a..a6ac6603791 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -10,7 +10,6 @@ default = ["participation_metrics"] write_ssz_files = [] # Writes debugging .ssz files to /tmp during block processing. participation_metrics = [] # Exposes validator participation metrics to Prometheus. fork_from_env = [] # Initialise the harness chain spec from the FORK_NAME env variable -withdrawals = ["state_processing/withdrawals", "types/withdrawals", "store/withdrawals", "execution_layer/withdrawals"] withdrawals-processing = [ "state_processing/withdrawals-processing", "store/withdrawals-processing", diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 17e0a6f121a..5c0311736ca 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -79,14 +79,12 @@ use slasher::Slasher; use slog::{crit, debug, error, info, trace, warn, Logger}; use slot_clock::SlotClock; use ssz::Encode; -#[cfg(feature = "withdrawals")] -use state_processing::per_block_processing::get_expected_withdrawals; use state_processing::{ common::get_attesting_indices_from_state, per_block_processing, per_block_processing::{ - errors::AttestationValidationError, verify_attestation_for_block_inclusion, - VerifySignatures, + errors::AttestationValidationError, get_expected_withdrawals, + verify_attestation_for_block_inclusion, VerifySignatures, }, per_slot_processing, state_advance::{complete_state_advance, partial_state_advance}, @@ -287,7 +285,6 @@ struct PartialBeaconBlock> { voluntary_exits: Vec, sync_aggregate: Option>, prepare_payload_handle: Option>, - #[cfg(feature = "withdrawals")] bls_to_execution_changes: Vec, } @@ -4182,7 +4179,6 @@ impl BeaconChain { let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?; let deposits = eth1_chain.deposits_for_block_inclusion(&state, ð1_data, &self.spec)?; - #[cfg(feature = "withdrawals")] let bls_to_execution_changes = self .op_pool .get_bls_to_execution_changes(&state, &self.spec); @@ -4345,7 +4341,6 @@ impl BeaconChain { voluntary_exits, sync_aggregate, prepare_payload_handle, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, }) } @@ -4375,7 +4370,6 @@ impl BeaconChain { // this function. We can assume that the handle has already been consumed in order to // produce said `execution_payload`. prepare_payload_handle: _, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, } = partial_beacon_block; @@ -4460,7 +4454,6 @@ impl BeaconChain { .to_payload() .try_into() .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - #[cfg(feature = "withdrawals")] bls_to_execution_changes: bls_to_execution_changes.into(), }, }), @@ -4485,7 +4478,6 @@ impl BeaconChain { .to_payload() .try_into() .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - #[cfg(feature = "withdrawals")] bls_to_execution_changes: bls_to_execution_changes.into(), //FIXME(sean) get blobs blob_kzg_commitments: VariableList::from(kzg_commitments), @@ -4743,7 +4735,6 @@ impl BeaconChain { return Ok(()); } - #[cfg(feature = "withdrawals")] let withdrawals = match self.spec.fork_name_at_slot::(prepare_slot) { ForkName::Base | ForkName::Altair | ForkName::Merge => None, ForkName::Capella | ForkName::Eip4844 => { @@ -4778,10 +4769,7 @@ impl BeaconChain { execution_layer .get_suggested_fee_recipient(proposer as u64) .await, - #[cfg(feature = "withdrawals")] withdrawals, - #[cfg(not(feature = "withdrawals"))] - None, ); debug!( diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 1982bdbf022..d52df4853df 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -17,11 +17,9 @@ use fork_choice::{InvalidationOperation, PayloadVerificationStatus}; use proto_array::{Block as ProtoBlock, ExecutionStatus}; use slog::debug; use slot_clock::SlotClock; -#[cfg(feature = "withdrawals")] -use state_processing::per_block_processing::get_expected_withdrawals; use state_processing::per_block_processing::{ - compute_timestamp_at_slot, is_execution_enabled, is_merge_transition_complete, - partially_verify_execution_payload, + compute_timestamp_at_slot, get_expected_withdrawals, is_execution_enabled, + is_merge_transition_complete, partially_verify_execution_payload, }; use std::sync::Arc; use tokio::task::JoinHandle; @@ -382,7 +380,6 @@ pub fn get_execution_payload< let random = *state.get_randao_mix(current_epoch)?; let latest_execution_payload_header_block_hash = state.latest_execution_payload_header()?.block_hash(); - #[cfg(feature = "withdrawals")] let withdrawals = match state { &BeaconState::Capella(_) | &BeaconState::Eip4844(_) => { Some(get_expected_withdrawals(state, spec)?.into()) @@ -407,7 +404,6 @@ pub fn get_execution_payload< proposer_index, latest_execution_payload_header_block_hash, builder_params, - #[cfg(feature = "withdrawals")] withdrawals, ) .await @@ -442,7 +438,7 @@ pub async fn prepare_execution_payload( proposer_index: u64, latest_execution_payload_header_block_hash: ExecutionBlockHash, builder_params: BuilderParams, - #[cfg(feature = "withdrawals")] withdrawals: Option>, + withdrawals: Option>, ) -> Result, BlockProductionError> where T: BeaconChainTypes, @@ -504,15 +500,8 @@ where let suggested_fee_recipient = execution_layer .get_suggested_fee_recipient(proposer_index) .await; - let payload_attributes = PayloadAttributes::new( - timestamp, - random, - suggested_fee_recipient, - #[cfg(feature = "withdrawals")] - withdrawals, - #[cfg(not(feature = "withdrawals"))] - None, - ); + let payload_attributes = + PayloadAttributes::new(timestamp, random, suggested_fee_recipient, withdrawals); // Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. // diff --git a/beacon_node/execution_layer/Cargo.toml b/beacon_node/execution_layer/Cargo.toml index b3bdc54d02a..47c1e0341b6 100644 --- a/beacon_node/execution_layer/Cargo.toml +++ b/beacon_node/execution_layer/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -withdrawals = ["state_processing/withdrawals", "types/withdrawals", "eth2/withdrawals"] withdrawals-processing = ["state_processing/withdrawals-processing", "eth2/withdrawals-processing"] [dependencies] diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 424ca30d137..80cdeacb34f 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -165,7 +165,6 @@ pub struct ExecutionBlockWithTransactions { #[serde(rename = "hash")] pub block_hash: ExecutionBlockHash, pub transactions: Vec, - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844))] pub withdrawals: Vec, } @@ -215,7 +214,6 @@ impl TryFrom> for ExecutionBlockWithTransactions .iter() .map(|tx| Transaction::decode(&Rlp::new(tx))) .collect::, _>>()?, - #[cfg(feature = "withdrawals")] withdrawals: Vec::from(block.withdrawals) .into_iter() .map(|withdrawal| withdrawal.into()) @@ -243,7 +241,6 @@ impl TryFrom> for ExecutionBlockWithTransactions .iter() .map(|tx| Transaction::decode(&Rlp::new(tx))) .collect::, _>>()?, - #[cfg(feature = "withdrawals")] withdrawals: Vec::from(block.withdrawals) .into_iter() .map(|withdrawal| withdrawal.into()) diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 1616b216340..29f66393e5c 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -852,11 +852,11 @@ impl HttpJsonRpc { pub async fn supported_apis_v1(&self) -> Result { Ok(SupportedApis { new_payload_v1: true, - new_payload_v2: cfg!(all(feature = "withdrawals", not(test))), + new_payload_v2: cfg!(not(test)), forkchoice_updated_v1: true, - forkchoice_updated_v2: cfg!(all(feature = "withdrawals", not(test))), + forkchoice_updated_v2: cfg!(not(test)), get_payload_v1: true, - get_payload_v2: cfg!(all(feature = "withdrawals", not(test))), + get_payload_v2: cfg!(not(test)), exchange_transition_configuration_v1: true, }) } diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 18e52eb06f6..13948affb55 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -166,7 +166,6 @@ impl JsonExecutionPayload { base_fee_per_gas: v2.base_fee_per_gas, block_hash: v2.block_hash, transactions: v2.transactions, - #[cfg(feature = "withdrawals")] withdrawals: v2 .withdrawals .map(|v| { @@ -194,7 +193,6 @@ impl JsonExecutionPayload { excess_data_gas: v2.excess_data_gas.ok_or_else(|| Error::BadConversion("Null `excess_data_gas` field converting JsonExecutionPayloadV2 -> ExecutionPayloadEip4844".to_string()))?, block_hash: v2.block_hash, transactions: v2.transactions, - #[cfg(feature = "withdrawals")] withdrawals: v2 .withdrawals .map(|v| { @@ -282,7 +280,6 @@ impl TryFrom> for JsonExecutionPayloadV2 { excess_data_gas: None, block_hash: capella.block_hash, transactions: capella.transactions, - #[cfg(feature = "withdrawals")] withdrawals: Some( Vec::from(capella.withdrawals) .into_iter() @@ -290,8 +287,6 @@ impl TryFrom> for JsonExecutionPayloadV2 { .collect::>() .into(), ), - #[cfg(not(feature = "withdrawals"))] - withdrawals: None, }), ExecutionPayload::Eip4844(eip4844) => Ok(JsonExecutionPayloadV2 { parent_hash: eip4844.parent_hash, @@ -309,7 +304,6 @@ impl TryFrom> for JsonExecutionPayloadV2 { excess_data_gas: Some(eip4844.excess_data_gas), block_hash: eip4844.block_hash, transactions: eip4844.transactions, - #[cfg(feature = "withdrawals")] withdrawals: Some( Vec::from(eip4844.withdrawals) .into_iter() @@ -317,8 +311,6 @@ impl TryFrom> for JsonExecutionPayloadV2 { .collect::>() .into(), ), - #[cfg(not(feature = "withdrawals"))] - withdrawals: None, }), } } diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 1761af09e8e..e22da42a72c 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -1633,7 +1633,6 @@ impl ExecutionLayer { }) } ExecutionBlockWithTransactions::Capella(capella_block) => { - #[cfg(feature = "withdrawals")] let withdrawals = VariableList::new( capella_block .withdrawals @@ -1642,7 +1641,6 @@ impl ExecutionLayer { .collect(), ) .map_err(ApiError::DeserializeWithdrawals)?; - ExecutionPayload::Capella(ExecutionPayloadCapella { parent_hash: capella_block.parent_hash, fee_recipient: capella_block.fee_recipient, @@ -1658,12 +1656,10 @@ impl ExecutionLayer { base_fee_per_gas: capella_block.base_fee_per_gas, block_hash: capella_block.block_hash, transactions, - #[cfg(feature = "withdrawals")] withdrawals, }) } ExecutionBlockWithTransactions::Eip4844(eip4844_block) => { - #[cfg(feature = "withdrawals")] let withdrawals = VariableList::new( eip4844_block .withdrawals @@ -1672,7 +1668,6 @@ impl ExecutionLayer { .collect(), ) .map_err(ApiError::DeserializeWithdrawals)?; - ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { parent_hash: eip4844_block.parent_hash, fee_recipient: eip4844_block.fee_recipient, @@ -1689,7 +1684,6 @@ impl ExecutionLayer { excess_data_gas: eip4844_block.excess_data_gas, block_hash: eip4844_block.block_hash, transactions, - #[cfg(feature = "withdrawals")] withdrawals, }) } diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index f0f84491258..e552b7ca7ab 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -103,10 +103,7 @@ impl MockExecutionLayer { prev_randao, Address::repeat_byte(42), // FIXME: think about how to handle different forks / withdrawals here.. - #[cfg(feature = "withdrawals")] Some(vec![]), - #[cfg(not(feature = "withdrawals"))] - None, ); // Insert a proposer to ensure the fork choice updated command works. diff --git a/beacon_node/store/Cargo.toml b/beacon_node/store/Cargo.toml index b3e8e1fc6b5..897f6b020c7 100644 --- a/beacon_node/store/Cargo.toml +++ b/beacon_node/store/Cargo.toml @@ -28,5 +28,4 @@ directory = { path = "../../common/directory" } strum = { version = "0.24.0", features = ["derive"] } [features] -withdrawals = ["state_processing/withdrawals", "types/withdrawals"] withdrawals-processing = ["state_processing/withdrawals-processing"] \ No newline at end of file diff --git a/beacon_node/store/src/partial_beacon_state.rs b/beacon_node/store/src/partial_beacon_state.rs index 12c56284966..ca35bc0b222 100644 --- a/beacon_node/store/src/partial_beacon_state.rs +++ b/beacon_node/store/src/partial_beacon_state.rs @@ -105,10 +105,8 @@ where pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844, // Withdrawals - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844))] pub next_withdrawal_index: u64, - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844))] pub next_withdrawal_validator_index: u64, } @@ -199,7 +197,6 @@ impl PartialBeaconState { latest_execution_payload_header ] ), - #[cfg(feature = "withdrawals")] BeaconState::Capella(s) => impl_from_state_forgetful!( s, outer, @@ -216,22 +213,6 @@ impl PartialBeaconState { next_withdrawal_validator_index ] ), - #[cfg(not(feature = "withdrawals"))] - BeaconState::Capella(s) => impl_from_state_forgetful!( - s, - outer, - Capella, - PartialBeaconStateCapella, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header - ] - ), - #[cfg(feature = "withdrawals")] BeaconState::Eip4844(s) => impl_from_state_forgetful!( s, outer, @@ -248,21 +229,6 @@ impl PartialBeaconState { next_withdrawal_validator_index ] ), - #[cfg(not(feature = "withdrawals"))] - BeaconState::Eip4844(s) => impl_from_state_forgetful!( - s, - outer, - Eip4844, - PartialBeaconStateEip4844, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header - ] - ), } } @@ -450,7 +416,6 @@ impl TryInto> for PartialBeaconState { latest_execution_payload_header ] ), - #[cfg(feature = "withdrawals")] PartialBeaconState::Capella(inner) => impl_try_into_beacon_state!( inner, Capella, @@ -466,21 +431,6 @@ impl TryInto> for PartialBeaconState { next_withdrawal_validator_index ] ), - #[cfg(not(feature = "withdrawals"))] - PartialBeaconState::Capella(inner) => impl_try_into_beacon_state!( - inner, - Capella, - BeaconStateCapella, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header - ] - ), - #[cfg(feature = "withdrawals")] PartialBeaconState::Eip4844(inner) => impl_try_into_beacon_state!( inner, Eip4844, @@ -496,20 +446,6 @@ impl TryInto> for PartialBeaconState { next_withdrawal_validator_index ] ), - #[cfg(not(feature = "withdrawals"))] - PartialBeaconState::Eip4844(inner) => impl_try_into_beacon_state!( - inner, - Eip4844, - BeaconStateEip4844, - [ - previous_epoch_participation, - current_epoch_participation, - current_sync_committee, - next_sync_committee, - inactivity_scores, - latest_execution_payload_header - ] - ), }; Ok(state) } diff --git a/common/eth2/Cargo.toml b/common/eth2/Cargo.toml index 6ee02b71ba6..fc5eba98e29 100644 --- a/common/eth2/Cargo.toml +++ b/common/eth2/Cargo.toml @@ -35,5 +35,4 @@ procinfo = { version = "0.4.2", optional = true } [features] default = ["lighthouse"] lighthouse = ["proto_array", "psutil", "procinfo", "store", "slashing_protection"] -withdrawals = ["store/withdrawals"] withdrawals-processing = ["store/withdrawals-processing"] \ No newline at end of file diff --git a/consensus/state_processing/Cargo.toml b/consensus/state_processing/Cargo.toml index 39a0be3d9fd..0b79539877a 100644 --- a/consensus/state_processing/Cargo.toml +++ b/consensus/state_processing/Cargo.toml @@ -43,5 +43,4 @@ arbitrary-fuzz = [ "eth2_ssz_types/arbitrary", "tree_hash/arbitrary", ] -withdrawals = ["types/withdrawals"] withdrawals-processing = [] diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 7af74428b59..f1a544099f3 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -19,7 +19,7 @@ pub use process_operations::process_operations; pub use verify_attestation::{ verify_attestation_for_block_inclusion, verify_attestation_for_state, }; -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] pub use verify_bls_to_execution_change::verify_bls_to_execution_change; pub use verify_deposit::{ get_existing_validator_index, verify_deposit_merkle_proof, verify_deposit_signature, @@ -36,7 +36,7 @@ pub mod signature_sets; pub mod tests; mod verify_attestation; mod verify_attester_slashing; -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] mod verify_bls_to_execution_change; mod verify_deposit; mod verify_exit; @@ -165,7 +165,7 @@ pub fn per_block_processing>( // previous block. if is_execution_enabled(state, block.body()) { let payload = block.body().execution_payload()?; - #[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] + #[cfg(feature = "withdrawals-processing")] process_withdrawals::(state, payload, spec)?; process_execution_payload::(state, payload, spec)?; } @@ -469,7 +469,6 @@ pub fn compute_timestamp_at_slot( /// Compute the next batch of withdrawals which should be included in a block. /// /// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#new-get_expected_withdrawals -#[cfg(feature = "withdrawals")] pub fn get_expected_withdrawals( state: &BeaconState, spec: &ChainSpec, @@ -525,7 +524,7 @@ pub fn get_expected_withdrawals( } /// Apply withdrawals to the state. -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] pub fn process_withdrawals<'payload, T: EthSpec, Payload: AbstractExecPayload>( state: &mut BeaconState, payload: Payload::Ref<'payload>, diff --git a/consensus/state_processing/src/per_block_processing/block_signature_verifier.rs b/consensus/state_processing/src/per_block_processing/block_signature_verifier.rs index 50bfbfdc454..bbf2c1caa51 100644 --- a/consensus/state_processing/src/per_block_processing/block_signature_verifier.rs +++ b/consensus/state_processing/src/per_block_processing/block_signature_verifier.rs @@ -170,7 +170,6 @@ where // Deposits are not included because they can legally have invalid signatures. self.include_exits(block)?; self.include_sync_aggregate(block)?; - #[cfg(feature = "withdrawals")] self.include_bls_to_execution_changes(block)?; Ok(()) @@ -345,7 +344,6 @@ where } /// Include the signature of the block's BLS to execution changes for verification. - #[cfg(feature = "withdrawals")] pub fn include_bls_to_execution_changes>( &mut self, block: &'a SignedBeaconBlock, diff --git a/consensus/state_processing/src/per_block_processing/process_operations.rs b/consensus/state_processing/src/per_block_processing/process_operations.rs index 105faba83bd..f27fd48b4f5 100644 --- a/consensus/state_processing/src/per_block_processing/process_operations.rs +++ b/consensus/state_processing/src/per_block_processing/process_operations.rs @@ -34,7 +34,7 @@ pub fn process_operations<'a, T: EthSpec, Payload: AbstractExecPayload>( process_deposits(state, block_body.deposits(), spec)?; process_exits(state, block_body.voluntary_exits(), verify_signatures, spec)?; - #[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] + #[cfg(feature = "withdrawals-processing")] if let Ok(bls_to_execution_changes) = block_body.bls_to_execution_changes() { process_bls_to_execution_changes(state, bls_to_execution_changes, verify_signatures, spec)?; } @@ -295,7 +295,7 @@ pub fn process_exits( /// /// Returns `Ok(())` if the validation and state updates completed successfully. Otherwise returns /// an `Err` describing the invalid object or cause of failure. -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] pub fn process_bls_to_execution_changes( state: &mut BeaconState, bls_to_execution_changes: &[SignedBlsToExecutionChange], diff --git a/consensus/state_processing/src/upgrade/capella.rs b/consensus/state_processing/src/upgrade/capella.rs index 9a883698830..dc759b384d8 100644 --- a/consensus/state_processing/src/upgrade/capella.rs +++ b/consensus/state_processing/src/upgrade/capella.rs @@ -56,9 +56,7 @@ pub fn upgrade_to_capella( // Execution latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_capella(), // Withdrawals - #[cfg(feature = "withdrawals")] next_withdrawal_index: 0, - #[cfg(feature = "withdrawals")] next_withdrawal_validator_index: 0, // Caches total_active_balance: pre.total_active_balance, diff --git a/consensus/state_processing/src/upgrade/eip4844.rs b/consensus/state_processing/src/upgrade/eip4844.rs index 6d66fd8412c..131100bb384 100644 --- a/consensus/state_processing/src/upgrade/eip4844.rs +++ b/consensus/state_processing/src/upgrade/eip4844.rs @@ -10,12 +10,8 @@ pub fn upgrade_to_eip4844( let pre = pre_state.as_capella_mut()?; // FIXME(sean) This is a hack to let us participate in testnets where capella doesn't exist. - // if we are disabling withdrawals, assume we should fork off of bellatrix. - let previous_fork_version = if cfg!(feature = "withdrawals") { - pre.fork.current_version - } else { - spec.bellatrix_fork_version - }; + // let previous_fork_version = spec.bellatrix_fork_version; + let previous_fork_version = pre.fork.current_version; // Where possible, use something like `mem::take` to move fields from behind the &mut // reference. For other fields that don't have a good default value, use `clone`. @@ -64,9 +60,7 @@ pub fn upgrade_to_eip4844( // Execution latest_execution_payload_header: pre.latest_execution_payload_header.upgrade_to_eip4844(), // Withdrawals - #[cfg(feature = "withdrawals")] next_withdrawal_index: pre.next_withdrawal_index, - #[cfg(feature = "withdrawals")] next_withdrawal_validator_index: pre.next_withdrawal_validator_index, // Caches total_active_balance: pre.total_active_balance, diff --git a/consensus/types/Cargo.toml b/consensus/types/Cargo.toml index b3ef3ae3825..671cacfa2eb 100644 --- a/consensus/types/Cargo.toml +++ b/consensus/types/Cargo.toml @@ -72,4 +72,3 @@ arbitrary-fuzz = [ "swap_or_not_shuffle/arbitrary", "tree_hash/arbitrary", ] -withdrawals = [] diff --git a/consensus/types/src/beacon_block.rs b/consensus/types/src/beacon_block.rs index 124cb08bcc0..fd38e9faf26 100644 --- a/consensus/types/src/beacon_block.rs +++ b/consensus/types/src/beacon_block.rs @@ -502,7 +502,6 @@ impl> EmptyBlock for BeaconBlockCape voluntary_exits: VariableList::empty(), sync_aggregate: SyncAggregate::empty(), execution_payload: Payload::Capella::default(), - #[cfg(feature = "withdrawals")] bls_to_execution_changes: VariableList::empty(), }, } @@ -532,7 +531,6 @@ impl> EmptyBlock for BeaconBlockEip4 voluntary_exits: VariableList::empty(), sync_aggregate: SyncAggregate::empty(), execution_payload: Payload::Eip4844::default(), - #[cfg(feature = "withdrawals")] bls_to_execution_changes: VariableList::empty(), blob_kzg_commitments: VariableList::empty(), }, diff --git a/consensus/types/src/beacon_block_body.rs b/consensus/types/src/beacon_block_body.rs index 1dd938ac465..dbdbcddb1b8 100644 --- a/consensus/types/src/beacon_block_body.rs +++ b/consensus/types/src/beacon_block_body.rs @@ -62,7 +62,6 @@ pub struct BeaconBlockBody = FullPay #[superstruct(only(Eip4844), partial_getter(rename = "execution_payload_eip4844"))] #[serde(flatten)] pub execution_payload: Payload::Eip4844, - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844))] pub bls_to_execution_changes: VariableList, @@ -301,7 +300,6 @@ impl From>> voluntary_exits, sync_aggregate, execution_payload: FullPayloadCapella { execution_payload }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, } = body; @@ -319,7 +317,6 @@ impl From>> execution_payload: BlindedPayloadCapella { execution_payload_header: From::from(execution_payload.clone()), }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, }, Some(execution_payload), @@ -345,7 +342,6 @@ impl From>> voluntary_exits, sync_aggregate, execution_payload: FullPayloadEip4844 { execution_payload }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, blob_kzg_commitments, } = body; @@ -364,7 +360,6 @@ impl From>> execution_payload: BlindedPayloadEip4844 { execution_payload_header: From::from(execution_payload.clone()), }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, blob_kzg_commitments, }, @@ -433,7 +428,6 @@ impl BeaconBlockBodyCapella> { voluntary_exits, sync_aggregate, execution_payload: FullPayloadCapella { execution_payload }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, } = self; @@ -450,7 +444,6 @@ impl BeaconBlockBodyCapella> { execution_payload: BlindedPayloadCapella { execution_payload_header: From::from(execution_payload.clone()), }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes: bls_to_execution_changes.clone(), } } @@ -469,7 +462,6 @@ impl BeaconBlockBodyEip4844> { voluntary_exits, sync_aggregate, execution_payload: FullPayloadEip4844 { execution_payload }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, blob_kzg_commitments, } = self; @@ -487,7 +479,6 @@ impl BeaconBlockBodyEip4844> { execution_payload: BlindedPayloadEip4844 { execution_payload_header: From::from(execution_payload.clone()), }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes: bls_to_execution_changes.clone(), blob_kzg_commitments: blob_kzg_commitments.clone(), } diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 48a83f94f45..b3eff7374b2 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -297,10 +297,8 @@ where pub latest_execution_payload_header: ExecutionPayloadHeaderEip4844, // Withdrawals - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844), partial_getter(copy))] pub next_withdrawal_index: u64, - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844), partial_getter(copy))] pub next_withdrawal_validator_index: u64, diff --git a/consensus/types/src/beacon_state/tree_hash_cache.rs b/consensus/types/src/beacon_state/tree_hash_cache.rs index 30dd9f8d6bc..4cfc684f4d3 100644 --- a/consensus/types/src/beacon_state/tree_hash_cache.rs +++ b/consensus/types/src/beacon_state/tree_hash_cache.rs @@ -336,11 +336,9 @@ impl BeaconTreeHashCacheInner { } // Withdrawal indices (Capella and later). - #[cfg(feature = "withdrawals")] if let Ok(next_withdrawal_index) = state.next_withdrawal_index() { hasher.write(next_withdrawal_index.tree_hash_root().as_bytes())?; } - #[cfg(feature = "withdrawals")] if let Ok(next_withdrawal_validator_index) = state.next_withdrawal_validator_index() { hasher.write(next_withdrawal_validator_index.tree_hash_root().as_bytes())?; } diff --git a/consensus/types/src/execution_payload.rs b/consensus/types/src/execution_payload.rs index 18005094e4b..45f52fb65a7 100644 --- a/consensus/types/src/execution_payload.rs +++ b/consensus/types/src/execution_payload.rs @@ -80,7 +80,6 @@ pub struct ExecutionPayload { pub block_hash: ExecutionBlockHash, #[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")] pub transactions: Transactions, - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844))] pub withdrawals: Withdrawals, } diff --git a/consensus/types/src/execution_payload_header.rs b/consensus/types/src/execution_payload_header.rs index a98a68e3e55..e2c23389a1f 100644 --- a/consensus/types/src/execution_payload_header.rs +++ b/consensus/types/src/execution_payload_header.rs @@ -75,7 +75,6 @@ pub struct ExecutionPayloadHeader { pub block_hash: ExecutionBlockHash, #[superstruct(getter(copy))] pub transactions_root: Hash256, - #[cfg(feature = "withdrawals")] #[superstruct(only(Capella, Eip4844))] #[superstruct(getter(copy))] pub withdrawals_root: Hash256, @@ -128,7 +127,6 @@ impl ExecutionPayloadHeaderMerge { base_fee_per_gas: self.base_fee_per_gas, block_hash: self.block_hash, transactions_root: self.transactions_root, - #[cfg(feature = "withdrawals")] withdrawals_root: Hash256::zero(), } } @@ -153,7 +151,6 @@ impl ExecutionPayloadHeaderCapella { excess_data_gas: Uint256::zero(), block_hash: self.block_hash, transactions_root: self.transactions_root, - #[cfg(feature = "withdrawals")] withdrawals_root: self.withdrawals_root, } } @@ -196,7 +193,6 @@ impl From> for ExecutionPayloadHeaderCape base_fee_per_gas: payload.base_fee_per_gas, block_hash: payload.block_hash, transactions_root: payload.transactions.tree_hash_root(), - #[cfg(feature = "withdrawals")] withdrawals_root: payload.withdrawals.tree_hash_root(), } } @@ -219,7 +215,6 @@ impl From> for ExecutionPayloadHeaderEip4 excess_data_gas: payload.excess_data_gas, block_hash: payload.block_hash, transactions_root: payload.transactions.tree_hash_root(), - #[cfg(feature = "withdrawals")] withdrawals_root: payload.withdrawals.tree_hash_root(), } } diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 2d9e37b81ab..8bba00b46df 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -37,7 +37,6 @@ pub trait ExecPayload: Debug + Clone + PartialEq + Hash + TreeHash + fn gas_limit(&self) -> u64; fn transactions(&self) -> Option<&Transactions>; /// fork-specific fields - #[cfg(feature = "withdrawals")] fn withdrawals_root(&self) -> Result; /// Is this a default payload with 0x0 roots for transactions and withdrawals? @@ -241,7 +240,6 @@ impl ExecPayload for FullPayload { }) } - #[cfg(feature = "withdrawals")] fn withdrawals_root(&self) -> Result { match self { FullPayload::Merge(_) => Err(Error::IncorrectStateVariant), @@ -343,7 +341,6 @@ impl<'b, T: EthSpec> ExecPayload for FullPayloadRef<'b, T> { }) } - #[cfg(feature = "withdrawals")] fn withdrawals_root(&self) -> Result { match self { FullPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), @@ -523,7 +520,6 @@ impl ExecPayload for BlindedPayload { None } - #[cfg(feature = "withdrawals")] fn withdrawals_root(&self) -> Result { match self { BlindedPayload::Merge(_) => Err(Error::IncorrectStateVariant), @@ -614,7 +610,6 @@ impl<'b, T: EthSpec> ExecPayload for BlindedPayloadRef<'b, T> { None } - #[cfg(feature = "withdrawals")] fn withdrawals_root(&self) -> Result { match self { BlindedPayloadRef::Merge(_) => Err(Error::IncorrectStateVariant), @@ -712,7 +707,6 @@ macro_rules! impl_exec_payload_common { f(self) } - #[cfg(feature = "withdrawals")] fn withdrawals_root(&self) -> Result { let g = $g; g(self) diff --git a/consensus/types/src/signed_beacon_block.rs b/consensus/types/src/signed_beacon_block.rs index 2a8398f83f3..14f9358f611 100644 --- a/consensus/types/src/signed_beacon_block.rs +++ b/consensus/types/src/signed_beacon_block.rs @@ -341,7 +341,6 @@ impl SignedBeaconBlockCapella> { voluntary_exits, sync_aggregate, execution_payload: BlindedPayloadCapella { .. }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, }, }, @@ -364,7 +363,6 @@ impl SignedBeaconBlockCapella> { voluntary_exits, sync_aggregate, execution_payload: FullPayloadCapella { execution_payload }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, }, }, @@ -397,7 +395,6 @@ impl SignedBeaconBlockEip4844> { voluntary_exits, sync_aggregate, execution_payload: BlindedPayloadEip4844 { .. }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, blob_kzg_commitments, }, @@ -421,7 +418,6 @@ impl SignedBeaconBlockEip4844> { voluntary_exits, sync_aggregate, execution_payload: FullPayloadEip4844 { execution_payload }, - #[cfg(feature = "withdrawals")] bls_to_execution_changes, blob_kzg_commitments, }, diff --git a/lighthouse/Cargo.toml b/lighthouse/Cargo.toml index 3b4dd57533b..2db42d6ec3f 100644 --- a/lighthouse/Cargo.toml +++ b/lighthouse/Cargo.toml @@ -24,8 +24,6 @@ gnosis = [] slasher-mdbx = ["slasher/mdbx"] # Support slasher LMDB backend. slasher-lmdb = ["slasher/lmdb"] -# Support for inclusion of withdrawals fields in all capella consensus types in all APIs. -withdrawals = ["types/withdrawals", "beacon_node/withdrawals"] # Support for withdrawals consensus processing logic. withdrawals-processing = ["beacon_node/withdrawals-processing"] diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index f5487a6940d..a08ee1996ac 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -4,7 +4,7 @@ use crate::case_result::compare_beacon_state_results_without_caches; use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yaml_decode_file}; use crate::testing_spec; use serde_derive::Deserialize; -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] use state_processing::per_block_processing::process_operations::{ process_bls_to_execution_changes, process_bls_to_execution_changes, }; @@ -22,7 +22,7 @@ use state_processing::{ }; use std::fmt::Debug; use std::path::Path; -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] use types::SignedBlsToExecutionChange; use types::{ Attestation, AttesterSlashing, BeaconBlock, BeaconState, BlindedPayload, ChainSpec, Deposit, @@ -42,7 +42,7 @@ struct ExecutionMetadata { } /// Newtype for testing withdrawals. -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] #[derive(Debug, Clone, Deserialize)] pub struct WithdrawalsPayload { payload: FullPayload, @@ -341,7 +341,7 @@ impl Operation for BlindedPayload { } } -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] impl Operation for WithdrawalsPayload { fn handler_name() -> String { "withdrawals".into() @@ -374,7 +374,7 @@ impl Operation for WithdrawalsPayload { } } -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] impl Operation for SignedBlsToExecutionChange { fn handler_name() -> String { "bls_to_execution_change".into() diff --git a/testing/ef_tests/src/lib.rs b/testing/ef_tests/src/lib.rs index fd3bf2bd1b5..a4d4f2d52d4 100644 --- a/testing/ef_tests/src/lib.rs +++ b/testing/ef_tests/src/lib.rs @@ -1,5 +1,5 @@ pub use case_result::CaseResult; -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] pub use cases::WithdrawalsPayload; pub use cases::{ Case, EffectiveBalanceUpdates, Eth1DataReset, HistoricalRootsUpdate, InactivityUpdates, diff --git a/testing/ef_tests/tests/tests.rs b/testing/ef_tests/tests/tests.rs index 0227b92ec86..66c4f83ecea 100644 --- a/testing/ef_tests/tests/tests.rs +++ b/testing/ef_tests/tests/tests.rs @@ -82,14 +82,14 @@ fn operations_execution_payload_blinded() { OperationsHandler::>::default().run(); } -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] #[test] fn operations_withdrawals() { OperationsHandler::>::default().run(); OperationsHandler::>::default().run(); } -#[cfg(all(feature = "withdrawals", feature = "withdrawals-processing"))] +#[cfg(feature = "withdrawals-processing")] #[test] fn operations_bls_to_execution_change() { OperationsHandler::::default().run(); diff --git a/testing/execution_engine_integration/Cargo.toml b/testing/execution_engine_integration/Cargo.toml index b5923aafe5d..e058d58afb6 100644 --- a/testing/execution_engine_integration/Cargo.toml +++ b/testing/execution_engine_integration/Cargo.toml @@ -23,5 +23,4 @@ hex = "0.4.2" fork_choice = { path = "../../consensus/fork_choice" } [features] -default = [] -withdrawals = [] \ No newline at end of file +default = [] \ No newline at end of file From 7d5db8015d3c1d23333919b895790671c561886c Mon Sep 17 00:00:00 2001 From: realbigsean Date: Mon, 19 Dec 2022 19:07:21 -0500 Subject: [PATCH 12/59] correctly respond without skips on first range response --- .../beacon_processor/worker/rpc_methods.rs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 6eae7eed59b..1938f389bcf 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -433,7 +433,17 @@ impl Worker { }; // Pick out the required blocks, ignoring skip-slots. - let mut last_block_root = None; + let mut last_block_root = req + .start_slot + .checked_sub(0) + .map(|prev_slot| { + self.chain + .block_root_at_slot(Slot::new(prev_slot), WhenSlotSkipped::Prev) + }) + .transpose() + .ok() + .flatten() + .flatten(); let maybe_block_roots = process_results(forwards_block_root_iter, |iter| { iter.take_while(|(_, slot)| slot.as_u64() < req.start_slot.saturating_add(req.count)) // map skip slots to None @@ -602,7 +612,17 @@ impl Worker { }; // Pick out the required blocks, ignoring skip-slots. - let mut last_block_root = None; + let mut last_block_root = req + .start_slot + .checked_sub(0) + .map(|prev_slot| { + self.chain + .block_root_at_slot(Slot::new(prev_slot), WhenSlotSkipped::Prev) + }) + .transpose() + .ok() + .flatten() + .flatten(); let maybe_block_roots = process_results(forwards_block_root_iter, |iter| { iter.take_while(|(_, slot)| slot.as_u64() < req.start_slot.saturating_add(req.count)) // map skip slots to None From 0c22d69e1546bbc35193c602dc55348e343c2a79 Mon Sep 17 00:00:00 2001 From: ethDreamer <37123614+ethDreamer@users.noreply.github.com> Date: Mon, 19 Dec 2022 19:35:08 -0600 Subject: [PATCH 13/59] Update consensus/state_processing/src/upgrade/eip4844.rs Co-authored-by: realbigsean --- consensus/state_processing/src/upgrade/eip4844.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/consensus/state_processing/src/upgrade/eip4844.rs b/consensus/state_processing/src/upgrade/eip4844.rs index 131100bb384..92a102ce96d 100644 --- a/consensus/state_processing/src/upgrade/eip4844.rs +++ b/consensus/state_processing/src/upgrade/eip4844.rs @@ -10,7 +10,6 @@ pub fn upgrade_to_eip4844( let pre = pre_state.as_capella_mut()?; // FIXME(sean) This is a hack to let us participate in testnets where capella doesn't exist. - // let previous_fork_version = spec.bellatrix_fork_version; let previous_fork_version = pre.fork.current_version; // Where possible, use something like `mem::take` to move fields from behind the &mut From b224ed81515167c8632ea6f6c66ef94ead4fdd81 Mon Sep 17 00:00:00 2001 From: ethDreamer <37123614+ethDreamer@users.noreply.github.com> Date: Mon, 19 Dec 2022 19:35:17 -0600 Subject: [PATCH 14/59] Update consensus/state_processing/src/upgrade/eip4844.rs Co-authored-by: realbigsean --- consensus/state_processing/src/upgrade/eip4844.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/consensus/state_processing/src/upgrade/eip4844.rs b/consensus/state_processing/src/upgrade/eip4844.rs index 92a102ce96d..e829c01e7e2 100644 --- a/consensus/state_processing/src/upgrade/eip4844.rs +++ b/consensus/state_processing/src/upgrade/eip4844.rs @@ -9,7 +9,6 @@ pub fn upgrade_to_eip4844( let epoch = pre_state.current_epoch(); let pre = pre_state.as_capella_mut()?; - // FIXME(sean) This is a hack to let us participate in testnets where capella doesn't exist. let previous_fork_version = pre.fork.current_version; // Where possible, use something like `mem::take` to move fields from behind the &mut From db29cb08a6c73a37f5296d5bceffc182be56d234 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 21 Dec 2022 00:18:05 +1100 Subject: [PATCH 15/59] Add bootnode binary variable in testnet scripts --- scripts/local_testnet/el_bootnode.sh | 2 +- scripts/local_testnet/vars.env | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/local_testnet/el_bootnode.sh b/scripts/local_testnet/el_bootnode.sh index 1f96bce2c2b..b22812dd93f 100755 --- a/scripts/local_testnet/el_bootnode.sh +++ b/scripts/local_testnet/el_bootnode.sh @@ -1,4 +1,4 @@ priv_key="02fd74636e96a8ffac8e7b01b0de8dea94d6bcf4989513b38cf59eb32163ff91" -/home/sean/CLionProjects/eip4844-interop/geth/go-ethereum/build/bin/bootnode --nodekeyhex $priv_key \ No newline at end of file +$BOOTNODE_BINARY --nodekeyhex $priv_key \ No newline at end of file diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index dbfc41e91f5..9a7c22ea586 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -1,4 +1,5 @@ GETH_BINARY=geth +BOOTNODE_BINARY=bootnode # Base directories for the validator keys and secrets DATADIR=~/.lighthouse/local-testnet From c76e371559c1d057aac9b22cbb47e2689ef7af7e Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Wed, 21 Dec 2022 00:29:15 +1100 Subject: [PATCH 16/59] Add missing source --- scripts/local_testnet/el_bootnode.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/local_testnet/el_bootnode.sh b/scripts/local_testnet/el_bootnode.sh index b22812dd93f..1b8834b8904 100755 --- a/scripts/local_testnet/el_bootnode.sh +++ b/scripts/local_testnet/el_bootnode.sh @@ -1,4 +1,5 @@ priv_key="02fd74636e96a8ffac8e7b01b0de8dea94d6bcf4989513b38cf59eb32163ff91" +source ./vars.env $BOOTNODE_BINARY --nodekeyhex $priv_key \ No newline at end of file From 9c46a1cb215099456628d1150b9e7a44e5b16afd Mon Sep 17 00:00:00 2001 From: realbigsean Date: Tue, 20 Dec 2022 18:56:07 -0500 Subject: [PATCH 17/59] fix rate limits, and a couple other bugs --- .../src/rpc/codec/ssz_snappy.rs | 4 ++-- .../lighthouse_network/src/rpc/protocol.rs | 19 +++++++++++++++---- .../beacon_processor/worker/rpc_methods.rs | 4 ++-- .../network/src/sync/network_context.rs | 12 ++++++++++-- beacon_node/store/src/hot_cold_store.rs | 4 +--- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index ce6e30ebf30..e6654a308d7 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -298,8 +298,8 @@ impl Decoder for SSZSnappyOutboundCodec { .rpc_response_limits::(&self.fork_context); if ssz_limits.is_out_of_bounds(length, self.max_packet_size) { return Err(RPCError::InvalidData(format!( - "RPC response length is out of bounds, length {}", - length + "RPC response length is out of bounds, length {}, max {}, min {}", + length, ssz_limits.max, ssz_limits.min ))); } // Calculate worst case compression length for given uncompressed length diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 0773197e865..2a91a4bb4d2 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -23,7 +23,7 @@ use tokio_util::{ use types::BlobsSidecar; use types::{ BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, Blob, EmptyBlock, EthSpec, - ForkContext, ForkName, Hash256, MainnetEthSpec, Signature, SignedBeaconBlock, + ForkContext, ForkName, Hash256, MainnetEthSpec, Signature, SignedBeaconBlock }; lazy_static! { @@ -107,6 +107,12 @@ lazy_static! { .as_ssz_bytes() .len(); + pub static ref BLOBS_SIDECAR_MIN: usize = BlobsSidecar::::empty().as_ssz_bytes().len(); + pub static ref BLOBS_SIDECAR_MAX: usize = BlobsSidecar::::max_size(); + + //FIXME(sean) these are underestimates + pub static ref SIGNED_BLOCK_AND_BLOBS_MIN: usize = *BLOBS_SIDECAR_MIN + *SIGNED_BEACON_BLOCK_BASE_MIN; + pub static ref SIGNED_BLOCK_AND_BLOBS_MAX: usize =*BLOBS_SIDECAR_MAX + *SIGNED_BEACON_BLOCK_EIP4844_MAX; } /// The maximum bytes that can be sent across the RPC pre-merge. @@ -359,9 +365,14 @@ impl ProtocolId { Protocol::BlocksByRange => rpc_block_limits_by_fork(fork_context.current_fork()), Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()), - //FIXME(sean) add blob sizes - Protocol::BlobsByRange => rpc_block_limits_by_fork(fork_context.current_fork()), - Protocol::BlobsByRoot => rpc_block_limits_by_fork(fork_context.current_fork()), + Protocol::BlobsByRange => RpcLimits::new( + *BLOBS_SIDECAR_MIN, + *BLOBS_SIDECAR_MAX, + ), + Protocol::BlobsByRoot => RpcLimits::new( + *SIGNED_BLOCK_AND_BLOBS_MIN, + *SIGNED_BLOCK_AND_BLOBS_MAX, + ), Protocol::Ping => RpcLimits::new( ::ssz_fixed_len(), diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 1938f389bcf..0824ca171eb 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -435,7 +435,7 @@ impl Worker { // Pick out the required blocks, ignoring skip-slots. let mut last_block_root = req .start_slot - .checked_sub(0) + .checked_sub(1) .map(|prev_slot| { self.chain .block_root_at_slot(Slot::new(prev_slot), WhenSlotSkipped::Prev) @@ -614,7 +614,7 @@ impl Worker { // Pick out the required blocks, ignoring skip-slots. let mut last_block_root = req .start_slot - .checked_sub(0) + .checked_sub(1) .map(|prev_slot| { self.chain .block_root_at_slot(Slot::new(prev_slot), WhenSlotSkipped::Prev) diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 5917c7ecca2..45cbb193582 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -314,14 +314,18 @@ impl SyncNetworkContext { let (chain_id, batch_id, info) = entry.get_mut(); let chain_id = chain_id.clone(); let batch_id = batch_id.clone(); + let stream_terminator = maybe_block.is_none(); info.add_block_response(maybe_block); - let maybe_block = info.pop_response().map(|block_sidecar_pair| { + let maybe_block_wrapped = info.pop_response().map(|block_sidecar_pair| { BlockWrapper::BlockAndBlob { block_sidecar_pair } }); if info.is_finished() { entry.remove(); } - Some((chain_id, batch_id, maybe_block)) + if !stream_terminator && maybe_block_wrapped.is_none() { + return None + } + Some((chain_id, batch_id, maybe_block_wrapped)) } Entry::Vacant(_) => None, } @@ -356,6 +360,7 @@ impl SyncNetworkContext { let (chain_id, batch_id, info) = entry.get_mut(); let chain_id = chain_id.clone(); let batch_id = batch_id.clone(); + let stream_terminator = maybe_sidecar.is_none(); info.add_sidecar_response(maybe_sidecar); let maybe_block = info .pop_response() @@ -363,6 +368,9 @@ impl SyncNetworkContext { if info.is_finished() { entry.remove(); } + if !stream_terminator && maybe_block.is_none() { + return None + } Some((chain_id, batch_id, maybe_block)) } Entry::Vacant(_) => None, diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 732795fce2d..439c99c018f 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -503,9 +503,7 @@ impl, Cold: ItemStore> HotColdDB } pub fn get_blobs(&self, block_root: &Hash256) -> Result>, Error> { - if let Some(blobs) = self.blob_cache.lock().get(block_root) { - Ok(Some(blobs.clone())) - } else if let Some(bytes) = self + if let Some(bytes) = self .hot_db .get_bytes(DBColumn::BeaconBlob.into(), block_root.as_bytes())? { From a67fa516c7f574e33df78d047c5158e003d1cbfd Mon Sep 17 00:00:00 2001 From: realbigsean Date: Tue, 20 Dec 2022 19:32:54 -0500 Subject: [PATCH 18/59] don't expect context bytes for blob messages --- .../src/rpc/codec/ssz_snappy.rs | 64 ++++++++++--------- beacon_node/store/src/hot_cold_store.rs | 2 + scripts/local_testnet/genesis.json | 4 +- scripts/local_testnet/vars.env | 2 +- 4 files changed, 39 insertions(+), 33 deletions(-) diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index e6654a308d7..ae86ec22081 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -570,38 +570,42 @@ fn handle_v1_response( SignedBeaconBlock::Base(SignedBeaconBlockBase::from_ssz_bytes(decoded_buffer)?), )))), Protocol::BlobsByRange => { - let fork_name = fork_name.take().ok_or_else(|| { - RPCError::ErrorResponse( - RPCResponseErrorCode::InvalidRequest, - format!("No context bytes provided for {} response", protocol), - ) - })?; - match fork_name { - ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRange(Arc::new( - BlobsSidecar::from_ssz_bytes(decoded_buffer)?, - )))), - _ => Err(RPCError::ErrorResponse( - RPCResponseErrorCode::InvalidRequest, - "Invalid forkname for blobsbyrange".to_string(), - )), - } + Ok(Some(RPCResponse::BlobsByRange(Arc::new( + BlobsSidecar::from_ssz_bytes(decoded_buffer)?, + )))) + //FIXME(sean) do we need context bytes? + // let fork_name = fork_name.take().ok_or_else(|| { + // RPCError::ErrorResponse( + // RPCResponseErrorCode::InvalidRequest, + // format!("No context bytes provided for {} response", protocol), + // ) + // })?; + // match fork_name { + // ForkName::Eip4844 => , + // _ => Err(RPCError::ErrorResponse( + // RPCResponseErrorCode::InvalidRequest, + // "Invalid forkname for blobsbyrange".to_string(), + // )), + // } } Protocol::BlobsByRoot => { - let fork_name = fork_name.take().ok_or_else(|| { - RPCError::ErrorResponse( - RPCResponseErrorCode::InvalidRequest, - format!("No context bytes provided for {} response", protocol), - ) - })?; - match fork_name { - ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRoot(Arc::new( - SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, - )))), - _ => Err(RPCError::ErrorResponse( - RPCResponseErrorCode::InvalidRequest, - "Invalid forkname for blobsbyroot".to_string(), - )), - } + Ok(Some(RPCResponse::BlobsByRoot(Arc::new( + SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, + )))) + //FIXME(sean) do we need context bytes? + // let fork_name = fork_name.take().ok_or_else(|| { + // RPCError::ErrorResponse( + // RPCResponseErrorCode::InvalidRequest, + // format!("No context bytes provided for {} response", protocol), + // ) + // })?; + // match fork_name { + // ForkName::Eip4844 => + // _ => Err(RPCError::ErrorResponse( + // RPCResponseErrorCode::InvalidRequest, + // "Invalid forkname for blobsbyroot".to_string(), + // )), + // } } Protocol::Ping => Ok(Some(RPCResponse::Pong(Ping { data: u64::from_ssz_bytes(decoded_buffer)?, diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 439c99c018f..00aa0b2af13 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -503,6 +503,8 @@ impl, Cold: ItemStore> HotColdDB } pub fn get_blobs(&self, block_root: &Hash256) -> Result>, Error> { + // FIXME(sean) I was attempting to use a blob cache here but was getting deadlocks, + // may want to attempt to use one again if let Some(bytes) = self .hot_db .get_bytes(DBColumn::BeaconBlob.into(), block_root.as_bytes())? diff --git a/scripts/local_testnet/genesis.json b/scripts/local_testnet/genesis.json index 751176048cd..f8943567753 100644 --- a/scripts/local_testnet/genesis.json +++ b/scripts/local_testnet/genesis.json @@ -12,8 +12,8 @@ "berlinBlock": 0, "londonBlock": 0, "mergeNetsplitBlock": 0, - "shanghaiTime": 0, - "shardingForkTime": 0, + "shanghaiTime": 1671582851, + "shardingForkTime": 1671582947, "terminalTotalDifficulty": 0 }, "alloc": { diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index dbfc41e91f5..07e315f607a 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -1,4 +1,4 @@ -GETH_BINARY=geth +GETH_BINARY=/home/sean/CLionProjects/eip4844-interop/geth/go-ethereum/build/bin/geth # Base directories for the validator keys and secrets DATADIR=~/.lighthouse/local-testnet From a6b771f265f5ccd81b42936896d97c1af5a2fd32 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 22 Dec 2022 00:19:22 +1100 Subject: [PATCH 19/59] Add more logging to `Error::MaxDistanceExceeded` --- beacon_node/beacon_chain/src/state_advance_timer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/beacon_chain/src/state_advance_timer.rs b/beacon_node/beacon_chain/src/state_advance_timer.rs index f73223fa540..3d21a14c830 100644 --- a/beacon_node/beacon_chain/src/state_advance_timer.rs +++ b/beacon_node/beacon_chain/src/state_advance_timer.rs @@ -186,7 +186,7 @@ async fn state_advance_timer( head_slot, }) => debug!( log, - "Refused to advance head state"; + "Refused to advance head state. Chain may be syncing or lagging too far behind"; "head_slot" => head_slot, "current_slot" => current_slot, ), From 14aa87aff3e5c3d6fde2cf7e8de2952bdea12be1 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 22 Dec 2022 00:19:38 +1100 Subject: [PATCH 20/59] Fix code comment --- beacon_node/http_api/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 30a22214587..e5336ef6ad4 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -1125,11 +1125,8 @@ pub fn serve( .map(|()| warp::reply()) }, ); - /* - * beacon/blocks - */ - // POST beacon/blocks + // POST beacon/blinded_blocks let post_beacon_blinded_blocks = eth_v1 .and(warp::path("beacon")) .and(warp::path("blinded_blocks")) From ccfd092845dc1d90db20369f00069644a64bfc8a Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 22 Dec 2022 00:22:37 +1100 Subject: [PATCH 21/59] Fix blob request logging and incorrect enum type --- beacon_node/network/src/sync/network_context.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 5917c7ecca2..19efd97c4f2 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -178,7 +178,7 @@ impl SyncNetworkContext { ExpectedBatchTy::OnlyBlock => { trace!( self.log, - "Sending BlocksByRange Request"; + "Sending BlocksByRange request"; "method" => "BlocksByRange", "count" => request.count, "peer" => %peer_id, @@ -197,7 +197,7 @@ impl SyncNetworkContext { ExpectedBatchTy::OnlyBlockBlobs => { debug!( self.log, - "Sending BlockBlock by range request"; + "Sending BlobsByRange request"; "method" => "Mixed by range request", "count" => request.count, "peer" => %peer_id, @@ -245,7 +245,7 @@ impl SyncNetworkContext { ExpectedBatchTy::OnlyBlock => { trace!( self.log, - "Sending backfill BlocksByRange Request"; + "Sending backfill BlocksByRange request"; "method" => "BlocksByRange", "count" => request.count, "peer" => %peer_id, @@ -264,7 +264,7 @@ impl SyncNetworkContext { ExpectedBatchTy::OnlyBlockBlobs => { debug!( self.log, - "Sending BlockBlock by range request"; + "Sending backfill BlobsByRange request"; "method" => "Mixed by range request", "count" => request.count, "peer" => %peer_id, @@ -272,7 +272,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeSidecarPair { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillSidecarPair { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { From f7bb458c5e5c25a0500822a76bd8741f4082bba0 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Thu, 22 Dec 2022 02:01:11 +1100 Subject: [PATCH 22/59] Fix incorrect logging --- beacon_node/network/src/sync/network_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 19efd97c4f2..251ac92bb18 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -197,7 +197,7 @@ impl SyncNetworkContext { ExpectedBatchTy::OnlyBlockBlobs => { debug!( self.log, - "Sending BlobsByRange request"; + "Sending BlocksByRange and BlobsByRange requests"; "method" => "Mixed by range request", "count" => request.count, "peer" => %peer_id, @@ -264,7 +264,7 @@ impl SyncNetworkContext { ExpectedBatchTy::OnlyBlockBlobs => { debug!( self.log, - "Sending backfill BlobsByRange request"; + "Sending backfill BlocksByRange and BlobsByRange requests"; "method" => "Mixed by range request", "count" => request.count, "peer" => %peer_id, From 3d253abadcb9381e95ca6d517ceef80cf707be0b Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Wed, 21 Dec 2022 11:40:21 -0600 Subject: [PATCH 23/59] Fixed spec serialization bug --- consensus/types/src/config_and_preset.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/consensus/types/src/config_and_preset.rs b/consensus/types/src/config_and_preset.rs index 9a618f7cc38..ac93818b9c3 100644 --- a/consensus/types/src/config_and_preset.rs +++ b/consensus/types/src/config_and_preset.rs @@ -28,6 +28,7 @@ pub struct ConfigAndPreset { #[serde(flatten)] pub bellatrix_preset: BellatrixPreset, #[superstruct(only(Capella))] + #[serde(flatten)] pub capella_preset: CapellaPreset, /// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks. #[serde(flatten)] From ff772311fa6b73cabb3b02c822960038121b40ad Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 21 Dec 2022 13:56:52 -0500 Subject: [PATCH 24/59] add context bytes to blob messages, fix rpc limits, sync past finalized checkpoint during finalized sync so we can advance our own finalization, fix stream termination bug in blobs by range --- .../src/rpc/codec/ssz_snappy.rs | 67 +++++++++---------- .../lighthouse_network/src/rpc/protocol.rs | 27 ++++---- .../beacon_processor/worker/rpc_methods.rs | 2 +- .../network/src/sync/network_context.rs | 25 +++++-- .../network/src/sync/range_sync/chain.rs | 8 ++- scripts/local_testnet/genesis.json | 4 +- 6 files changed, 74 insertions(+), 59 deletions(-) diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index ae86ec22081..fb07e683137 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -439,6 +439,9 @@ fn context_bytes( SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()), }; } + if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant { + return fork_context.to_context_bytes(ForkName::Eip4844); + } } } None @@ -570,42 +573,38 @@ fn handle_v1_response( SignedBeaconBlock::Base(SignedBeaconBlockBase::from_ssz_bytes(decoded_buffer)?), )))), Protocol::BlobsByRange => { - Ok(Some(RPCResponse::BlobsByRange(Arc::new( - BlobsSidecar::from_ssz_bytes(decoded_buffer)?, - )))) - //FIXME(sean) do we need context bytes? - // let fork_name = fork_name.take().ok_or_else(|| { - // RPCError::ErrorResponse( - // RPCResponseErrorCode::InvalidRequest, - // format!("No context bytes provided for {} response", protocol), - // ) - // })?; - // match fork_name { - // ForkName::Eip4844 => , - // _ => Err(RPCError::ErrorResponse( - // RPCResponseErrorCode::InvalidRequest, - // "Invalid forkname for blobsbyrange".to_string(), - // )), - // } + let fork_name = fork_name.take().ok_or_else(|| { + RPCError::ErrorResponse( + RPCResponseErrorCode::InvalidRequest, + format!("No context bytes provided for {} response", protocol), + ) + })?; + match fork_name { + ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRange(Arc::new( + BlobsSidecar::from_ssz_bytes(decoded_buffer)?, + )))), + _ => Err(RPCError::ErrorResponse( + RPCResponseErrorCode::InvalidRequest, + "Invalid forkname for blobsbyrange".to_string(), + )), + } } Protocol::BlobsByRoot => { - Ok(Some(RPCResponse::BlobsByRoot(Arc::new( - SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, - )))) - //FIXME(sean) do we need context bytes? - // let fork_name = fork_name.take().ok_or_else(|| { - // RPCError::ErrorResponse( - // RPCResponseErrorCode::InvalidRequest, - // format!("No context bytes provided for {} response", protocol), - // ) - // })?; - // match fork_name { - // ForkName::Eip4844 => - // _ => Err(RPCError::ErrorResponse( - // RPCResponseErrorCode::InvalidRequest, - // "Invalid forkname for blobsbyroot".to_string(), - // )), - // } + let fork_name = fork_name.take().ok_or_else(|| { + RPCError::ErrorResponse( + RPCResponseErrorCode::InvalidRequest, + format!("No context bytes provided for {} response", protocol), + ) + })?; + match fork_name { + ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRoot(Arc::new( + SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, + )))), + _ => Err(RPCError::ErrorResponse( + RPCResponseErrorCode::InvalidRequest, + "Invalid forkname for blobsbyroot".to_string(), + )), + } } Protocol::Ping => Ok(Some(RPCResponse::Pong(Ping { data: u64::from_ssz_bytes(decoded_buffer)?, diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 2a91a4bb4d2..8a3149fc517 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -23,7 +23,7 @@ use tokio_util::{ use types::BlobsSidecar; use types::{ BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, Blob, EmptyBlock, EthSpec, - ForkContext, ForkName, Hash256, MainnetEthSpec, Signature, SignedBeaconBlock + ForkContext, ForkName, Hash256, MainnetEthSpec, Signature, SignedBeaconBlock, }; lazy_static! { @@ -364,16 +364,10 @@ impl ProtocolId { Protocol::Goodbye => RpcLimits::new(0, 0), // Goodbye request has no response Protocol::BlocksByRange => rpc_block_limits_by_fork(fork_context.current_fork()), Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()), - - Protocol::BlobsByRange => RpcLimits::new( - *BLOBS_SIDECAR_MIN, - *BLOBS_SIDECAR_MAX, - ), - Protocol::BlobsByRoot => RpcLimits::new( - *SIGNED_BLOCK_AND_BLOBS_MIN, - *SIGNED_BLOCK_AND_BLOBS_MAX, - ), - + Protocol::BlobsByRange => RpcLimits::new(*BLOBS_SIDECAR_MIN, *BLOBS_SIDECAR_MAX), + Protocol::BlobsByRoot => { + RpcLimits::new(*SIGNED_BLOCK_AND_BLOBS_MIN, *SIGNED_BLOCK_AND_BLOBS_MAX) + } Protocol::Ping => RpcLimits::new( ::ssz_fixed_len(), ::ssz_fixed_len(), @@ -392,13 +386,16 @@ impl ProtocolId { /// Returns `true` if the given `ProtocolId` should expect `context_bytes` in the /// beginning of the stream, else returns `false`. pub fn has_context_bytes(&self) -> bool { - if self.version == Version::V2 { - match self.message_name { + match self.version { + Version::V2 => match self.message_name { Protocol::BlocksByRange | Protocol::BlocksByRoot => return true, _ => return false, - } + }, + Version::V1 => match self.message_name { + Protocol::BlobsByRange | Protocol::BlobsByRoot => return true, + _ => return false, + }, } - false } } diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 0824ca171eb..d85bb1f209c 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -689,7 +689,7 @@ impl Worker { self.log, "BlobsByRange Response processed"; "peer" => %peer_id, - "msg" => "Failed to return all requested blocks", + "msg" => "Failed to return all requested blobs", "start_slot" => req.start_slot, "current_slot" => current_slot, "requested" => req.count, diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 45cbb193582..978bd69d068 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -319,12 +319,18 @@ impl SyncNetworkContext { let maybe_block_wrapped = info.pop_response().map(|block_sidecar_pair| { BlockWrapper::BlockAndBlob { block_sidecar_pair } }); - if info.is_finished() { - entry.remove(); + + if stream_terminator && !info.is_finished() { + return None; } if !stream_terminator && maybe_block_wrapped.is_none() { - return None + return None; } + + if info.is_finished() { + entry.remove(); + } + Some((chain_id, batch_id, maybe_block_wrapped)) } Entry::Vacant(_) => None, @@ -365,12 +371,19 @@ impl SyncNetworkContext { let maybe_block = info .pop_response() .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { block_sidecar_pair }); - if info.is_finished() { - entry.remove(); + + if stream_terminator && !info.is_finished() { + return None; } + if !stream_terminator && maybe_block.is_none() { - return None + return None; + } + + if info.is_finished() { + entry.remove(); } + Some((chain_id, batch_id, maybe_block)) } Entry::Vacant(_) => None, diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index 199be788e70..46b6d05d7d6 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -137,10 +137,16 @@ impl SyncingChain { let id = SyncingChain::::id(&target_head_root, &target_head_slot); + let target_slot = if is_finalized_segment { + target_head_slot + (2 * T::EthSpec::slots_per_epoch()) + 1 + } else { + target_head_slot + }; + SyncingChain { id, start_epoch, - target_head_slot, + target_head_slot: target_slot, target_head_root, batches: BTreeMap::new(), peers, diff --git a/scripts/local_testnet/genesis.json b/scripts/local_testnet/genesis.json index f8943567753..751176048cd 100644 --- a/scripts/local_testnet/genesis.json +++ b/scripts/local_testnet/genesis.json @@ -12,8 +12,8 @@ "berlinBlock": 0, "londonBlock": 0, "mergeNetsplitBlock": 0, - "shanghaiTime": 1671582851, - "shardingForkTime": 1671582947, + "shanghaiTime": 0, + "shardingForkTime": 0, "terminalTotalDifficulty": 0 }, "alloc": { From 2f4c44fd88ff50af5bd4225e16f62953f3203f08 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 21 Dec 2022 14:04:14 -0500 Subject: [PATCH 25/59] remove my binary path for geth --- scripts/local_testnet/vars.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index 07e315f607a..dbfc41e91f5 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -1,4 +1,4 @@ -GETH_BINARY=/home/sean/CLionProjects/eip4844-interop/geth/go-ethereum/build/bin/geth +GETH_BINARY=geth # Base directories for the validator keys and secrets DATADIR=~/.lighthouse/local-testnet From 33d01a79119fcb85d48888c98dbf59b6e6c1cd3c Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 21 Dec 2022 15:50:51 -0500 Subject: [PATCH 26/59] miscelaneous fixes on syncing, rpc and responding to peer's sync related requests (#3827) - there was a bug in responding range blob requests where we would incorrectly label the first slot of an epoch as a non-skipped slot if it were skipped. this bug did not exist in the code for responding to block range request because the logic error was mitigated by defensive coding elsewhere - there was a bug where a block received during range sync without a corresponding blob (and vice versa) was incorrectly interpreted as a stream termination - RPC size limit fixes. - Our blob cache was dead locking so I removed use of it for now. - Because of our change in finalized sync batch size from 2 to 1 and our transition to using exact epoch boundaries for batches (rather than one slot past the epoch boundary), we need to sync finalized sync to 2 epochs + 1 slot past our peer's finalized slot in order to finalize the chain locally. - use fork context bytes in rpc methods on both the server and client side --- .../src/rpc/codec/ssz_snappy.rs | 7 +++-- .../lighthouse_network/src/rpc/protocol.rs | 26 ++++++++++++------- .../beacon_processor/worker/rpc_methods.rs | 26 ++++++++++++++++--- .../network/src/sync/network_context.rs | 25 ++++++++++++++++-- .../network/src/sync/range_sync/chain.rs | 8 +++++- beacon_node/store/src/hot_cold_store.rs | 6 ++--- 6 files changed, 78 insertions(+), 20 deletions(-) diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index ce6e30ebf30..fb07e683137 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -298,8 +298,8 @@ impl Decoder for SSZSnappyOutboundCodec { .rpc_response_limits::(&self.fork_context); if ssz_limits.is_out_of_bounds(length, self.max_packet_size) { return Err(RPCError::InvalidData(format!( - "RPC response length is out of bounds, length {}", - length + "RPC response length is out of bounds, length {}, max {}, min {}", + length, ssz_limits.max, ssz_limits.min ))); } // Calculate worst case compression length for given uncompressed length @@ -439,6 +439,9 @@ fn context_bytes( SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()), }; } + if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant { + return fork_context.to_context_bytes(ForkName::Eip4844); + } } } None diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 0773197e865..8a3149fc517 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -107,6 +107,12 @@ lazy_static! { .as_ssz_bytes() .len(); + pub static ref BLOBS_SIDECAR_MIN: usize = BlobsSidecar::::empty().as_ssz_bytes().len(); + pub static ref BLOBS_SIDECAR_MAX: usize = BlobsSidecar::::max_size(); + + //FIXME(sean) these are underestimates + pub static ref SIGNED_BLOCK_AND_BLOBS_MIN: usize = *BLOBS_SIDECAR_MIN + *SIGNED_BEACON_BLOCK_BASE_MIN; + pub static ref SIGNED_BLOCK_AND_BLOBS_MAX: usize =*BLOBS_SIDECAR_MAX + *SIGNED_BEACON_BLOCK_EIP4844_MAX; } /// The maximum bytes that can be sent across the RPC pre-merge. @@ -358,11 +364,10 @@ impl ProtocolId { Protocol::Goodbye => RpcLimits::new(0, 0), // Goodbye request has no response Protocol::BlocksByRange => rpc_block_limits_by_fork(fork_context.current_fork()), Protocol::BlocksByRoot => rpc_block_limits_by_fork(fork_context.current_fork()), - - //FIXME(sean) add blob sizes - Protocol::BlobsByRange => rpc_block_limits_by_fork(fork_context.current_fork()), - Protocol::BlobsByRoot => rpc_block_limits_by_fork(fork_context.current_fork()), - + Protocol::BlobsByRange => RpcLimits::new(*BLOBS_SIDECAR_MIN, *BLOBS_SIDECAR_MAX), + Protocol::BlobsByRoot => { + RpcLimits::new(*SIGNED_BLOCK_AND_BLOBS_MIN, *SIGNED_BLOCK_AND_BLOBS_MAX) + } Protocol::Ping => RpcLimits::new( ::ssz_fixed_len(), ::ssz_fixed_len(), @@ -381,13 +386,16 @@ impl ProtocolId { /// Returns `true` if the given `ProtocolId` should expect `context_bytes` in the /// beginning of the stream, else returns `false`. pub fn has_context_bytes(&self) -> bool { - if self.version == Version::V2 { - match self.message_name { + match self.version { + Version::V2 => match self.message_name { Protocol::BlocksByRange | Protocol::BlocksByRoot => return true, _ => return false, - } + }, + Version::V1 => match self.message_name { + Protocol::BlobsByRange | Protocol::BlobsByRoot => return true, + _ => return false, + }, } - false } } diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 6eae7eed59b..d85bb1f209c 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -433,7 +433,17 @@ impl Worker { }; // Pick out the required blocks, ignoring skip-slots. - let mut last_block_root = None; + let mut last_block_root = req + .start_slot + .checked_sub(1) + .map(|prev_slot| { + self.chain + .block_root_at_slot(Slot::new(prev_slot), WhenSlotSkipped::Prev) + }) + .transpose() + .ok() + .flatten() + .flatten(); let maybe_block_roots = process_results(forwards_block_root_iter, |iter| { iter.take_while(|(_, slot)| slot.as_u64() < req.start_slot.saturating_add(req.count)) // map skip slots to None @@ -602,7 +612,17 @@ impl Worker { }; // Pick out the required blocks, ignoring skip-slots. - let mut last_block_root = None; + let mut last_block_root = req + .start_slot + .checked_sub(1) + .map(|prev_slot| { + self.chain + .block_root_at_slot(Slot::new(prev_slot), WhenSlotSkipped::Prev) + }) + .transpose() + .ok() + .flatten() + .flatten(); let maybe_block_roots = process_results(forwards_block_root_iter, |iter| { iter.take_while(|(_, slot)| slot.as_u64() < req.start_slot.saturating_add(req.count)) // map skip slots to None @@ -669,7 +689,7 @@ impl Worker { self.log, "BlobsByRange Response processed"; "peer" => %peer_id, - "msg" => "Failed to return all requested blocks", + "msg" => "Failed to return all requested blobs", "start_slot" => req.start_slot, "current_slot" => current_slot, "requested" => req.count, diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 5917c7ecca2..978bd69d068 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -314,14 +314,24 @@ impl SyncNetworkContext { let (chain_id, batch_id, info) = entry.get_mut(); let chain_id = chain_id.clone(); let batch_id = batch_id.clone(); + let stream_terminator = maybe_block.is_none(); info.add_block_response(maybe_block); - let maybe_block = info.pop_response().map(|block_sidecar_pair| { + let maybe_block_wrapped = info.pop_response().map(|block_sidecar_pair| { BlockWrapper::BlockAndBlob { block_sidecar_pair } }); + + if stream_terminator && !info.is_finished() { + return None; + } + if !stream_terminator && maybe_block_wrapped.is_none() { + return None; + } + if info.is_finished() { entry.remove(); } - Some((chain_id, batch_id, maybe_block)) + + Some((chain_id, batch_id, maybe_block_wrapped)) } Entry::Vacant(_) => None, } @@ -356,13 +366,24 @@ impl SyncNetworkContext { let (chain_id, batch_id, info) = entry.get_mut(); let chain_id = chain_id.clone(); let batch_id = batch_id.clone(); + let stream_terminator = maybe_sidecar.is_none(); info.add_sidecar_response(maybe_sidecar); let maybe_block = info .pop_response() .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { block_sidecar_pair }); + + if stream_terminator && !info.is_finished() { + return None; + } + + if !stream_terminator && maybe_block.is_none() { + return None; + } + if info.is_finished() { entry.remove(); } + Some((chain_id, batch_id, maybe_block)) } Entry::Vacant(_) => None, diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index 199be788e70..46b6d05d7d6 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -137,10 +137,16 @@ impl SyncingChain { let id = SyncingChain::::id(&target_head_root, &target_head_slot); + let target_slot = if is_finalized_segment { + target_head_slot + (2 * T::EthSpec::slots_per_epoch()) + 1 + } else { + target_head_slot + }; + SyncingChain { id, start_epoch, - target_head_slot, + target_head_slot: target_slot, target_head_root, batches: BTreeMap::new(), peers, diff --git a/beacon_node/store/src/hot_cold_store.rs b/beacon_node/store/src/hot_cold_store.rs index 732795fce2d..00aa0b2af13 100644 --- a/beacon_node/store/src/hot_cold_store.rs +++ b/beacon_node/store/src/hot_cold_store.rs @@ -503,9 +503,9 @@ impl, Cold: ItemStore> HotColdDB } pub fn get_blobs(&self, block_root: &Hash256) -> Result>, Error> { - if let Some(blobs) = self.blob_cache.lock().get(block_root) { - Ok(Some(blobs.clone())) - } else if let Some(bytes) = self + // FIXME(sean) I was attempting to use a blob cache here but was getting deadlocks, + // may want to attempt to use one again + if let Some(bytes) = self .hot_db .get_bytes(DBColumn::BeaconBlob.into(), block_root.as_bytes())? { From cb28201f5b66243f9150b874c53d62688797f52b Mon Sep 17 00:00:00 2001 From: realbigsean Date: Thu, 22 Dec 2022 08:54:24 -0500 Subject: [PATCH 27/59] update built in 4844 testnet --- .../eip4844/boot_enr.yaml | 6 +- .../eip4844/config.yaml | 94 +++++------------- .../eip4844/genesis.ssz.zip | Bin 3546 -> 3514 bytes scripts/local_testnet/vars.env | 2 +- 4 files changed, 27 insertions(+), 75 deletions(-) diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml index 4d52cc59752..143387543b8 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml @@ -1,3 +1,3 @@ -- enr:-MK4QLij8YaVQ6fIi09rDuD9fufxBlCZRXwfM1q6SbNJfy5ZZdAvtlnsfqhIeI0IqeOZdaPExVCfZfR4JJTIuKXFR76GAYJGrqHnh2F0dG5ldHOIAAAAAAAAAACEZXRoMpBCynldgwAP_QMAAAAAAAAAgmlkgnY0gmlwhCJ7uEyJc2VjcDI1NmsxoQJpeftU6RbmIhcFllICznlAMJXL3EwHEGhn73_Gk0wrCYhzeW5jbmV0cwCDdGNwgjLIg3VkcIIu4A -- enr:-JG4QK27MZvV3QbwdLt055Yhei27SjAsDXMFGCdl-Q7SDiCgR_qbiW3BmcOClehFVJgMa6IfjHeJBdbC0jvrr2NycOqGAYJLWb5kgmlkgnY0gmlwhCJE_eeJc2VjcDI1NmsxoQIecO7Y9C7J2Bs7RNxXaUkU6BfmPKIhEsDScKAoxENaRYN0Y3CCdl-DdWRwgnZf -- enr:-JG4QExcHW3vzBcE0f_r-93nSA4iBy4qNLthSyTw7p0tlPwjMl1JVTAgLSNHLLZJzOGtelJO4sw37LliuHyJ55zN5J6GAYJLWTvzgmlkgnY0gmlwhCKq1cmJc2VjcDI1NmsxoQJT2d4jtKQbHNw3tZPLhoMlR73o5LNdi-bk_bYq6siwuIN0Y3CCdl-DdWRwgnZf \ No newline at end of file +- enr:-MK4QFnkGjrt5qw5Ct5XXT9QYvfqmH8Cf6xqKuczTHWixDUZQmngyLrlftv-tMRbXDAxZZQDxNciNTjx7XpW0G4yQguGAYU2Pmnxh2F0dG5ldHOIAAAAAAAAAACEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCJ5ITWJc2VjcDI1NmsxoQIlwaxycUgJ_Ht4lYdDlInbIuRxu0HcHcFbu0D7As2SLYhzeW5jbmV0cwCDdGNwgjLIg3VkcIIu4A +- enr:-MK4QBqN5McD5YYgfEnfQjWUvrSaCITjBvQevlP5q0nCVbKuZRoa2XvGWOBwTDQyLNYiqgeettVwXs0PrSc1rOY2rjKGAYU2M7A8h2F0dG5ldHOIAAAAAAAAAgCEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCJ6vpeJc2VjcDI1NmsxoQNJzjxNKr7-a-iEDs0KvaL_vo1UH91kefEiWzgAdwSntYhzeW5jbmV0cw-DdGNwgjLIg3VkcIIu4A +- enr:-MK4QEzb6r0hpSyiko9u-mbEX1TzdTD9RcSiU4jhey5jJbTAHLdXNFR32CfjingVa6QMyCPtZRUfzSGbJ0ur3-Pdxe-GAYU2OwM5h2F0dG5ldHOIAAAAAAAAAACEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCPi7faJc2VjcDI1NmsxoQIKBTGU_riCSYrscdRCLuocbNzhF9RTNItPfD4_PmYngIhzeW5jbmV0cwCDdGNwgjLIg3VkcIIu4A diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml index d6e6aef57a5..88c3107ea9d 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml @@ -1,85 +1,37 @@ -# Prater config - -# Extends the mainnet preset -CONFIG_NAME: 'eip4844' -PRESET_BASE: 'mainnet' - -# Transition -# --------------------------------------------------------------- -TERMINAL_TOTAL_DIFFICULTY: 40 -# By default, don't use these params -TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 -TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 +CONFIG_NAME: testnet +PRESET_BASE: mainnet # Genesis -# --------------------------------------------------------------- -# `2**14` (= 16,384) -MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 2 -# Mar-01-2021 08:53:32 AM +UTC -MIN_GENESIS_TIME: 1653318000 -# Prater area code (Vienna) +# The genesis fork version looks weird for legacy reasons GENESIS_FORK_VERSION: 0x00000ffd -# Customized for Prater: 1919188 seconds (Mar-23-2021 02:00:00 PM +UTC) -GENESIS_DELAY: 0 - - -# Forking -# --------------------------------------------------------------- -# Some forks are disabled for now: -# - These may be re-assigned to another fork-version later -# - Temporarily set to max uint64 value: 2**64 - 1 # Altair -ALTAIR_FORK_VERSION: 0x01000ffd -ALTAIR_FORK_EPOCH: 1 +ALTAIR_FORK_EPOCH: 2 +ALTAIR_FORK_VERSION: 0x20000090 + # Merge -BELLATRIX_FORK_VERSION: 0x02000ffd -BELLATRIX_FORK_EPOCH: 2 -# Sharding -EIP4844_FORK_VERSION: 0x83000ffd -EIP4844_FORK_EPOCH: 3 +BELLATRIX_FORK_EPOCH: 3 +BELLATRIX_FORK_VERSION: 0x20000091 +TERMINAL_TOTAL_DIFFICULTY: 2 -# TBD, 2**32 is a placeholder. Merge transition approach is in active R&D. -TRANSITION_TOTAL_DIFFICULTY: 40 +# Capella +CAPELLA_FORK_EPOCH: 4 +CAPELLA_FORK_VERSION: 0x20000092 +MAX_WITHDRAWALS_PER_PAYLOAD: 4 +# EIP4844 +EIP4844_FORK_EPOCH: 5 +EIP4844_FORK_VERSION: 0x20000093 # Time parameters -# --------------------------------------------------------------- -# 12 seconds SECONDS_PER_SLOT: 12 -# 14 (estimate from Eth1 mainnet) -SECONDS_PER_ETH1_BLOCK: 14 -# 2**8 (= 256) epochs ~27 hours -MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 -# 2**8 (= 256) epochs ~27 hours -SHARD_COMMITTEE_PERIOD: 256 -# 2**11 (= 2,048) Eth1 blocks ~8 hours -ETH1_FOLLOW_DISTANCE: 15 - - -# Validator cycle -# --------------------------------------------------------------- -# 2**2 (= 4) -INACTIVITY_SCORE_BIAS: 4 -# 2**4 (= 16) -INACTIVITY_SCORE_RECOVERY_RATE: 16 -# 2**4 * 10**9 (= 16,000,000,000) Gwei -EJECTION_BALANCE: 16000000000 -# 2**2 (= 4) -MIN_PER_EPOCH_CHURN_LIMIT: 4 -# 2**16 (= 65,536) -CHURN_LIMIT_QUOTIENT: 65536 - - -# Fork choice -# --------------------------------------------------------------- -# 40% -PROPOSER_SCORE_BOOST: 40 +SLOTS_PER_EPOCH: 32 # Deposit contract -# --------------------------------------------------------------- -# Ethereum Goerli testnet +DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242 + DEPOSIT_CHAIN_ID: 1331 -DEPOSIT_NETWORK_ID: 69 -# Prater test deposit contract on Goerli Testnet -DEPOSIT_CONTRACT_ADDRESS: 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 +DEPOSIT_NETWORK_ID: 1331 + +ETH1_FOLLOW_DISTANCE: 1 +MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 2 diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/genesis.ssz.zip b/common/eth2_network_config/built_in_network_configs/eip4844/genesis.ssz.zip index 88b405071058d5163f5757e775c7cea3dd4b1183..06c1b45fdcc2cde730587ba28932b174f0ee21a4 100644 GIT binary patch delta 901 zcmV;01A6@08@d}cP)h>@6aWGM2mt*>mR0`Y|4a@I000&QDF6!q8~|r!Ze??6b1rjp zdR0^j00RwRq+=Xlq>(ute{CM6piCuCrY<~kDZ`j{=u9b6Hjn0gU@D5jY#FIBM@^jv zuFW>Du*e+h>(aC_&!A9;=I}sL=1P~Fny#s6u4M-j5x6hmm){Q_o-Ys2KWgE|iGll? zUJSG>Y(8{ec*%ud%Mz}hXtRIJ`tVINXU%`QVMgTLV0qwy#?^n#CI92-t`6g-buGEF zC^lhl)~)pSjwNn6P`7k`)w+HCSJbq-b}qAF1N;G6@DMBOL974<$Bi6uq@-MfvV?bL;p$Z{MSSDp>@mmpw2K`!`?pm|YhS$?_%!wEiNvrwuRPxJ_FLl+l*mC-uBe0=hK&M)jg%?@a){Q>t%ChzMNLj zK0ac><<&!K!nSp)D4Z0t^y*KgqZ+>ySW{Bnx!2Ku>z{Y5*LUlwW?%lea%Vwz? z$se?OXJp5WT8FnKWF!qfHFjpvtu8l?48PZBM_!*M!2@A!v)4R1WKzVE$eVdLdSC0@ zV)XR5<8Pno*0oh&eB5idUc9tBX;k*lqu+1&aeme2=F^%i8eF=gdeFPk1>v<0FS&9f zn7eL&f6=)019PS%m&Fu!58lqMer$N|Tj{-qecxzjX}|VW@skcri=N&iX6(3ntplri z92ycV%RRVk#3yI=Hcd%wKk$dD)-y7G$;&^T^Fs34T8AGTK4kw6P)h*<9s?8r0ssgA z{Y92l{^9>j4h;YR76d5(3ji1Z000000001!k_{9r1posLV5DPpcnbgl1n2_*00ig* b002-+1qJ{B000310RT||002`B00000Wa+Mq literal 3546 zcmWIWW@Zs#-~dAQe7jHvC=g@OWZ-5{U`S8ROD)bU)+;Wq3Ju|9U_Wndo?P2!1IDEl z+zgB?FPIq^z{K0LnHgd%5(hqpFTYu{*W2;tls(gqI~Y&j)RWnMZi-TB+}Y%~8C{DE zqusJ9rW_9nG{0@5)qQH=K0jY+WBx@3;m=N}1U(CyK0A7s+0kTO>j@nTY6TVR>?f_Cfb@`kC4Vby-KgCKNu{b}Y31 z+}y$v|KA&fcZtNr2+ZDK|Mt|S>-*%keNA|KXs4*O{oCD}cIDn&X?>Ly=G{?x#D%~= z`>?C8L{_}GQTq9b{vvs;nIh&puRW{$YGuDk+uCGJUGs}vQSI*U^Jc|P5w%dH) zs>1IpzVSZ`6En{d{`xNbdD&Ipcb{(lICXaEaj(LY?;cw!n$8Cl7HVi z#y9il>sLp3&xf$xi;t+PiMX+K`TN|Txj|)@JB@>miL*|#7mNDy;Yf>YxbyR8^^>F| z<8AaRkDfiBt!^eM>~%tNkGg<)QrX^m?$G~-uUT$9_(7EU8r$}m{*L!I7nQ%;b<6#n zdg{}qXS0O=e)}%J$Ke03g&oh&O}Rh+|DRh+uVy-XF)eI+d;QDH;2R4qLhS6)o?UV6 z{Of0~bwgZQYF~!?sXc<)*)nyXZ#^vJUK|zg@%!1A&OFUZ_p~& Date: Thu, 22 Dec 2022 10:26:09 -0500 Subject: [PATCH 28/59] config updates --- .../eip4844/config.yaml | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml index 88c3107ea9d..d5e18559162 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml @@ -1,9 +1,28 @@ CONFIG_NAME: testnet PRESET_BASE: mainnet +# Transition +# --------------------------------------------------------------- +TERMINAL_TOTAL_DIFFICULTY: 2 +# By default, don't use these params +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 +TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 + # Genesis +# --------------------------------------------------------------- # The genesis fork version looks weird for legacy reasons +MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 2 +# Dec 1, 2020, 12pm UTC +MIN_GENESIS_TIME: 1606824000 GENESIS_FORK_VERSION: 0x00000ffd +# 604800 seconds (7 days) +GENESIS_DELAY: 604800 + +# Forking +# --------------------------------------------------------------- +# Some forks are disabled for now: +# - These may be re-assigned to another fork-version later +# - Temporarily set to max uint64 value: 2**64 - 1 # Altair ALTAIR_FORK_EPOCH: 2 @@ -12,7 +31,6 @@ ALTAIR_FORK_VERSION: 0x20000090 # Merge BELLATRIX_FORK_EPOCH: 3 BELLATRIX_FORK_VERSION: 0x20000091 -TERMINAL_TOTAL_DIFFICULTY: 2 # Capella CAPELLA_FORK_EPOCH: 4 @@ -24,14 +42,38 @@ EIP4844_FORK_EPOCH: 5 EIP4844_FORK_VERSION: 0x20000093 # Time parameters +# --------------------------------------------------------------- +# 12 seconds SECONDS_PER_SLOT: 12 -SLOTS_PER_EPOCH: 32 +# 14 (estimate from Eth1 mainnet) +SECONDS_PER_ETH1_BLOCK: 14 +# 2**8 (= 256) epochs ~27 hours +MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256 +# 2**8 (= 256) epochs ~27 hours +SHARD_COMMITTEE_PERIOD: 256 +ETH1_FOLLOW_DISTANCE: 1 + +# Validator cycle +# --------------------------------------------------------------- +# 2**2 (= 4) +INACTIVITY_SCORE_BIAS: 4 +# 2**4 (= 16) +INACTIVITY_SCORE_RECOVERY_RATE: 16 +# 2**4 * 10**9 (= 16,000,000,000) Gwei +EJECTION_BALANCE: 16000000000 +# 2**2 (= 4) +MIN_PER_EPOCH_CHURN_LIMIT: 4 +# 2**16 (= 65,536) +CHURN_LIMIT_QUOTIENT: 65536 + +# Fork choice +# --------------------------------------------------------------- +# 40% +PROPOSER_SCORE_BOOST: 40 # Deposit contract +# --------------------------------------------------------------- DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242 - DEPOSIT_CHAIN_ID: 1331 DEPOSIT_NETWORK_ID: 1331 -ETH1_FOLLOW_DISTANCE: 1 -MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 2 From 12402b309df4f01c503a75d638ac4f1432da28c1 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Thu, 22 Dec 2022 14:08:38 -0500 Subject: [PATCH 29/59] fix geth binary path --- scripts/local_testnet/vars.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/local_testnet/vars.env b/scripts/local_testnet/vars.env index bf3c4f3c171..9a7c22ea586 100644 --- a/scripts/local_testnet/vars.env +++ b/scripts/local_testnet/vars.env @@ -1,4 +1,4 @@ -GETH_BINARY=/geth +GETH_BINARY=geth BOOTNODE_BINARY=bootnode # Base directories for the validator keys and secrets From cd6655dba91e46b2f91edfdb0a39135c95ea7cff Mon Sep 17 00:00:00 2001 From: Diva M Date: Thu, 22 Dec 2022 17:30:04 -0500 Subject: [PATCH 30/59] handle no blobs from peers instead of empty blobs in range requests --- .../src/sync/block_sidecar_coupling.rs | 115 +++++++++ beacon_node/network/src/sync/manager.rs | 197 +++++++++------ beacon_node/network/src/sync/mod.rs | 1 + .../network/src/sync/network_context.rs | 239 +++++------------- .../network/src/sync/range_sync/range.rs | 22 +- consensus/types/src/blobs_sidecar.rs | 9 +- 6 files changed, 316 insertions(+), 267 deletions(-) create mode 100644 beacon_node/network/src/sync/block_sidecar_coupling.rs diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs new file mode 100644 index 00000000000..762f37692fe --- /dev/null +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -0,0 +1,115 @@ +use std::{ + collections::{hash_map::OccupiedEntry, VecDeque}, + sync::Arc, +}; + +use types::{ + signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock, + SignedBeaconBlockAndBlobsSidecar, +}; + +struct ReceivedData { + block: Option>>, + blob: Option>>, +} + +#[derive(Debug, Default)] +pub struct BlockBlobRequestInfo { + /// Blocks we have received awaiting for their corresponding sidecar. + accumulated_blocks: VecDeque>>, + /// Sidecars we have received awaiting for their corresponding block. + accumulated_sidecars: VecDeque>>, + /// Whether the individual RPC request for blocks is finished or not. + is_blocks_rpc_finished: bool, + /// Whether the individual RPC request for sidecars is finished or not. + is_sidecar_rpc_finished: bool, +} + +pub struct BlockBlobRequestEntry<'a, K, T: EthSpec> { + entry: OccupiedEntry<'a, K, BlockBlobRequestInfo>, +} + +impl<'a, K, T: EthSpec> From>> + for BlockBlobRequestEntry<'a, K, T> +{ + fn from(entry: OccupiedEntry<'a, K, BlockBlobRequestInfo>) -> Self { + BlockBlobRequestEntry { entry } + } +} + +impl BlockBlobRequestInfo { + pub fn add_block_response(&mut self, maybe_block: Option>>) { + match maybe_block { + Some(block) => self.accumulated_blocks.push_back(block), + None => self.is_blocks_rpc_finished = true, + } + } + + pub fn add_sidecar_response(&mut self, maybe_sidecar: Option>>) { + match maybe_sidecar { + Some(sidecar) => self.accumulated_sidecars.push_back(sidecar), + None => self.is_sidecar_rpc_finished = true, + } + } + + pub fn into_responses(self) -> Result>, &'static str> { + let BlockBlobRequestInfo { + accumulated_blocks, + accumulated_sidecars, + .. + } = self; + + // Create the storage for our pairs. + let mut pairs = Vec::with_capacity(accumulated_blocks.len()); + + // ASSUMPTION: There can't be more more blobs than blocks. i.e. sending any block (empty + // included) for a skipped slot is not permitted. + for sidecar in accumulated_sidecars { + let blob_slot = sidecar.beacon_block_slot; + // First queue any blocks that might not have a blob. + while let Some(block) = { + // We identify those if their slot is less than the current blob's slot. + match accumulated_blocks.front() { + Some(borrowed_block) if borrowed_block.slot() < blob_slot => { + accumulated_blocks.pop_front() + } + Some(_) => None, + None => { + // We received a blob and ran out of blocks. This is a peer error + return Err("Blob without more blobs to pair with returned by peer"); + } + } + } { + pairs.push(BlockWrapper::Block { block }) + } + + // The next block must be present and must match the blob's slot + let next_block = accumulated_blocks + .pop_front() + .expect("If block stream ended, an error was previously returned"); + if next_block.slot() != blob_slot { + // We verified that the slot of the block is not less than the slot of the blob (it + // would have been returned before). It's also not equal, so this block is ahead + // than the blob. This means the blob is not paired. + return Err("Blob without a matching block returned by peer"); + } + pairs.push(BlockWrapper::BlockAndBlob { + block_sidecar_pair: SignedBeaconBlockAndBlobsSidecar { + beacon_block: next_block, + blobs_sidecar: sidecar, + }, + }); + } + + // Every remaining block does not have a blob + for block in accumulated_blocks { + pairs.push(BlockWrapper::Block { block }) + } + + Ok(pairs) + } + + pub fn is_finished(&self) -> bool { + self.is_blocks_rpc_finished && self.is_sidecar_rpc_finished + } +} diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 60105d42252..155e2d2131c 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -35,7 +35,7 @@ use super::backfill_sync::{BackFillSync, ProcessResult, SyncStart}; use super::block_lookups::BlockLookups; -use super::network_context::SyncNetworkContext; +use super::network_context::{BlockOrBlob, SyncNetworkContext}; use super::peer_sync_info::{remote_sync_type, PeerSyncType}; use super::range_sync::{RangeSync, RangeSyncType, EPOCHS_PER_BATCH}; use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent as BeaconWorkEvent}; @@ -45,11 +45,11 @@ use crate::sync::range_sync::ExpectedBatchTy; use beacon_chain::{BeaconChain, BeaconChainTypes, BlockError, EngineState}; use futures::StreamExt; use lighthouse_network::rpc::methods::MAX_REQUEST_BLOCKS; -use lighthouse_network::rpc::{RPCError, RPCResponseErrorCode}; +use lighthouse_network::rpc::RPCError; use lighthouse_network::types::{NetworkGlobals, SyncState}; use lighthouse_network::SyncInfo; use lighthouse_network::{PeerAction, PeerId}; -use slog::{crit, debug, error, info, trace, Logger}; +use slog::{crit, debug, error, info, trace, warn, Logger}; use std::boxed::Box; use std::ops::Sub; use std::sync::Arc; @@ -746,17 +746,17 @@ impl SyncManager { &mut self.network, ), RequestId::BackFillSync { id } => { - if let Some((batch_id, block)) = self.network.backfill_sync_block_response( - id, - beacon_block, - ExpectedBatchTy::OnlyBlock, - ) { + let is_stream_terminator = beacon_block.is_none(); + if let Some(batch_id) = self + .network + .backfill_sync_only_blocks_response(id, is_stream_terminator) + { match self.backfill_sync.on_block_response( &mut self.network, batch_id, &peer_id, id, - block, + beacon_block.map(|block| BlockWrapper::Block { block }), ) { Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), Ok(ProcessResult::Successful) => {} @@ -769,61 +769,125 @@ impl SyncManager { } } RequestId::RangeSync { id } => { - if let Some((chain_id, batch_id, block)) = self.network.range_sync_block_response( - id, - beacon_block, - ExpectedBatchTy::OnlyBlock, - ) { + let is_stream_terminator = beacon_block.is_none(); + if let Some((chain_id, batch_id)) = self + .network + .range_sync_block_response(id, is_stream_terminator) + { self.range_sync.blocks_by_range_response( &mut self.network, peer_id, chain_id, batch_id, id, - block, + beacon_block.map(|block| BlockWrapper::Block { block }), ); self.update_sync_state(); } } RequestId::BackFillSidecarPair { id } => { - if let Some((batch_id, block)) = self.network.backfill_sync_block_response( - id, - beacon_block, - ExpectedBatchTy::OnlyBlockBlobs, - ) { - match self.backfill_sync.on_block_response( - &mut self.network, - batch_id, - &peer_id, - id, - block, - ) { - Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), - Ok(ProcessResult::Successful) => {} - Err(_error) => { - // The backfill sync has failed, errors are reported - // within. - self.update_sync_state(); - } + self.block_blob_backfill_response(id, peer_id, beacon_block.into()) + } + RequestId::RangeSidecarPair { id } => { + self.block_blob_range_response(id, peer_id, beacon_block.into()) + } + } + } + + /// Handles receiving a response for a range sync request that should have both blocks and + /// blobs. + fn block_blob_range_response( + &mut self, + id: Id, + peer_id: PeerId, + block_or_blob: BlockOrBlob, + ) { + if let Some((chain_id, batch_id, block_responses)) = self + .network + .range_sync_block_and_blob_response(id, block_or_blob) + { + match block_responses { + Ok(blocks) => { + for block in blocks + .into_iter() + .map(|block| Some(block)) + // chain the stream terminator + .chain(vec![None]) + { + self.range_sync.blocks_by_range_response( + &mut self.network, + peer_id, + chain_id, + batch_id, + id, + block, + ); + self.update_sync_state(); } } + Err(e) => { + // inform backfill that the request needs to be treated as failed + // With time we will want to downgrade this log + warn!( + self.log, "Blocks and blobs request for backfill received invalid data"; + "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e + ); + // TODO: penalize the peer for being a bad boy + let id = RequestId::RangeSidecarPair { id }; + self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) + } } - RequestId::RangeSidecarPair { id } => { - if let Some((chain_id, batch_id, block)) = self.network.range_sync_block_response( - id, - beacon_block, - ExpectedBatchTy::OnlyBlockBlobs, - ) { - self.range_sync.blocks_by_range_response( - &mut self.network, - peer_id, - chain_id, - batch_id, - id, - block, + } + } + + /// Handles receiving a response for a bacjfill sync request that should have both blocks and + /// blobs. + fn block_blob_backfill_response( + &mut self, + id: Id, + peer_id: PeerId, + block_or_blob: BlockOrBlob, + ) { + if let Some((batch_id, block_responses)) = self + .network + .backfill_sync_block_and_blob_response(id, block_or_blob) + { + match block_responses { + Ok(blocks) => { + for block in blocks + .into_iter() + .map(|block| Some(block)) + // chain the stream terminator + .chain(vec![None]) + { + match self.backfill_sync.on_block_response( + &mut self.network, + batch_id, + &peer_id, + id, + block, + ) { + Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), + Ok(ProcessResult::Successful) => {} + Err(_error) => { + // The backfill sync has failed, errors are reported + // within. + self.update_sync_state(); + } + } + } + } + Err(e) => { + // inform backfill that the request needs to be treated as failed + // With time we will want to downgrade this log + warn!( + self.log, "Blocks and blobs request for backfill received invalid data"; + "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); - self.update_sync_state(); + // TODO: penalize the peer for being a bad boy + let id = RequestId::BackFillSidecarPair { id }; + self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } } @@ -844,44 +908,13 @@ impl SyncManager { unreachable!("An only blocks request does not receive sidecars") } RequestId::BackFillSidecarPair { id } => { - if let Some((batch_id, block)) = self - .network - .backfill_sync_sidecar_response(id, maybe_sidecar) - { - match self.backfill_sync.on_block_response( - &mut self.network, - batch_id, - &peer_id, - id, - block, - ) { - Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), - Ok(ProcessResult::Successful) => {} - Err(_error) => { - // The backfill sync has failed, errors are reported - // within. - self.update_sync_state(); - } - } - } + self.block_blob_backfill_response(id, peer_id, maybe_sidecar.into()) } RequestId::RangeSync { .. } => { - unreachable!("And only blocks range request does not receive sidecars") + unreachable!("Only-blocks range requests don't receive sidecars") } RequestId::RangeSidecarPair { id } => { - if let Some((chain_id, batch_id, block)) = - self.network.range_sync_sidecar_response(id, maybe_sidecar) - { - self.range_sync.blocks_by_range_response( - &mut self.network, - peer_id, - chain_id, - batch_id, - id, - block, - ); - self.update_sync_state(); - } + self.block_blob_range_response(id, peer_id, maybe_sidecar.into()) } } } diff --git a/beacon_node/network/src/sync/mod.rs b/beacon_node/network/src/sync/mod.rs index dc18a5c981e..7b244bceceb 100644 --- a/beacon_node/network/src/sync/mod.rs +++ b/beacon_node/network/src/sync/mod.rs @@ -3,6 +3,7 @@ //! Stores the various syncing methods for the beacon chain. mod backfill_sync; mod block_lookups; +mod block_sidecar_coupling; pub mod manager; mod network_context; mod peer_sync_info; diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 978bd69d068..912a5620e8a 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -1,6 +1,7 @@ //! Provides network functionality for the Syncing thread. This fundamentally wraps a network //! channel and stores a global RPC ID to perform requests. +use super::block_sidecar_coupling::BlockBlobRequestInfo; use super::manager::{Id, RequestId as SyncRequestId}; use super::range_sync::{BatchId, ChainId, ExpectedBatchTy}; use crate::beacon_processor::WorkEvent; @@ -13,59 +14,11 @@ use lighthouse_network::rpc::methods::BlobsByRangeRequest; use lighthouse_network::rpc::{BlocksByRangeRequest, BlocksByRootRequest, GoodbyeReason}; use lighthouse_network::{Client, NetworkGlobals, PeerAction, PeerId, ReportSource, Request}; use slog::{debug, trace, warn}; -use slot_clock::SlotClock; use std::collections::hash_map::Entry; -use std::collections::VecDeque; use std::sync::Arc; use tokio::sync::mpsc; use types::signed_block_and_blobs::BlockWrapper; -use types::{ - BlobsSidecar, ChainSpec, EthSpec, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, -}; - -#[derive(Debug, Default)] -struct BlockBlobRequestInfo { - /// Blocks we have received awaiting for their corresponding sidecar. - accumulated_blocks: VecDeque>>, - /// Sidecars we have received awaiting for their corresponding block. - accumulated_sidecars: VecDeque>>, - /// Whether the individual RPC request for blocks is finished or not. - is_blocks_rpc_finished: bool, - /// Whether the individual RPC request for sidecars is finished or not. - is_sidecar_rpc_finished: bool, -} - -impl BlockBlobRequestInfo { - pub fn add_block_response(&mut self, maybe_block: Option>>) { - match maybe_block { - Some(block) => self.accumulated_blocks.push_back(block), - None => self.is_blocks_rpc_finished = true, - } - } - - pub fn add_sidecar_response(&mut self, maybe_sidecar: Option>>) { - match maybe_sidecar { - Some(sidecar) => self.accumulated_sidecars.push_back(sidecar), - None => self.is_sidecar_rpc_finished = true, - } - } - - pub fn pop_response(&mut self) -> Option> { - if !self.accumulated_blocks.is_empty() && !self.accumulated_sidecars.is_empty() { - let beacon_block = self.accumulated_blocks.pop_front().expect("non empty"); - let blobs_sidecar = self.accumulated_sidecars.pop_front().expect("non empty"); - return Some(SignedBeaconBlockAndBlobsSidecar { - beacon_block, - blobs_sidecar, - }); - } - None - } - - pub fn is_finished(&self) -> bool { - self.is_blocks_rpc_finished && self.is_sidecar_rpc_finished - } -} +use types::{BlobsSidecar, EthSpec, SignedBeaconBlock}; /// Wraps a Network channel to employ various RPC related network functionality for the Sync manager. This includes management of a global RPC request Id. pub struct SyncNetworkContext { @@ -104,6 +57,24 @@ pub struct SyncNetworkContext { log: slog::Logger, } +/// Small enumeration to make dealing with block and blob requests easier. +pub enum BlockOrBlob { + Block(Option>>), + Blob(Option>>), +} + +impl From>>> for BlockOrBlob { + fn from(block: Option>>) -> Self { + BlockOrBlob::Block(block) + } +} + +impl From>>> for BlockOrBlob { + fn from(blob: Option>>) -> Self { + BlockOrBlob::Blob(blob) + } +} + impl SyncNetworkContext { pub fn new( network_send: mpsc::UnboundedSender>, @@ -300,91 +271,45 @@ impl SyncNetworkContext { } } - /// Received a blocks by range response. + /// Response for a request that is only for blocks. pub fn range_sync_block_response( &mut self, request_id: Id, - maybe_block: Option>>, - batch_type: ExpectedBatchTy, - ) -> Option<(ChainId, BatchId, Option>)> { - match batch_type { - ExpectedBatchTy::OnlyBlockBlobs => { - match self.range_sidecar_pair_requests.entry(request_id) { - Entry::Occupied(mut entry) => { - let (chain_id, batch_id, info) = entry.get_mut(); - let chain_id = chain_id.clone(); - let batch_id = batch_id.clone(); - let stream_terminator = maybe_block.is_none(); - info.add_block_response(maybe_block); - let maybe_block_wrapped = info.pop_response().map(|block_sidecar_pair| { - BlockWrapper::BlockAndBlob { block_sidecar_pair } - }); - - if stream_terminator && !info.is_finished() { - return None; - } - if !stream_terminator && maybe_block_wrapped.is_none() { - return None; - } - - if info.is_finished() { - entry.remove(); - } - - Some((chain_id, batch_id, maybe_block_wrapped)) - } - Entry::Vacant(_) => None, - } - } - ExpectedBatchTy::OnlyBlock => { - // if the request is just for blocks then it can be removed on a stream termination - match maybe_block { - Some(block) => { - self.range_requests - .get(&request_id) - .cloned() - .map(|(chain_id, batch_id)| { - (chain_id, batch_id, Some(BlockWrapper::Block { block })) - }) - } - None => self - .range_requests - .remove(&request_id) - .map(|(chain_id, batch_id)| (chain_id, batch_id, None)), - } - } + is_stream_terminator: bool, + ) -> Option<(ChainId, BatchId)> { + if is_stream_terminator { + self.range_requests + .remove(&request_id) + .map(|(chain_id, batch_id)| (chain_id, batch_id)) + } else { + self.range_requests.get(&request_id).cloned() } } - pub fn range_sync_sidecar_response( + /// Received a blocks by range response for a request that couples blocks and blobs. + pub fn range_sync_block_and_blob_response( &mut self, request_id: Id, - maybe_sidecar: Option>>, - ) -> Option<(ChainId, BatchId, Option>)> { + block_or_blob: BlockOrBlob, + ) -> Option<( + ChainId, + BatchId, + Result>, &'static str>, + )> { match self.range_sidecar_pair_requests.entry(request_id) { Entry::Occupied(mut entry) => { - let (chain_id, batch_id, info) = entry.get_mut(); - let chain_id = chain_id.clone(); - let batch_id = batch_id.clone(); - let stream_terminator = maybe_sidecar.is_none(); - info.add_sidecar_response(maybe_sidecar); - let maybe_block = info - .pop_response() - .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { block_sidecar_pair }); - - if stream_terminator && !info.is_finished() { - return None; + let (_, _, info) = entry.get_mut(); + match block_or_blob { + BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } - - if !stream_terminator && maybe_block.is_none() { - return None; - } - if info.is_finished() { - entry.remove(); + // If the request is finished, unqueue everything + let (chain_id, batch_id, info) = entry.remove(); + Some((chain_id, batch_id, info.into_responses())) + } else { + None } - - Some((chain_id, batch_id, maybe_block)) } Entry::Vacant(_) => None, } @@ -418,65 +343,41 @@ impl SyncNetworkContext { } } - /// Received a blocks by range response. - pub fn backfill_sync_block_response( + /// Response for a request that is only for blocks. + pub fn backfill_sync_only_blocks_response( &mut self, request_id: Id, - maybe_block: Option>>, - batch_type: ExpectedBatchTy, - ) -> Option<(BatchId, Option>)> { - match batch_type { - ExpectedBatchTy::OnlyBlockBlobs => { - match self.backfill_sidecar_pair_requests.entry(request_id) { - Entry::Occupied(mut entry) => { - let (batch_id, info) = entry.get_mut(); - let batch_id = batch_id.clone(); - info.add_block_response(maybe_block); - let maybe_block = info.pop_response().map(|block_sidecar_pair| { - BlockWrapper::BlockAndBlob { block_sidecar_pair } - }); - if info.is_finished() { - entry.remove(); - } - Some((batch_id, maybe_block)) - } - Entry::Vacant(_) => None, - } - } - ExpectedBatchTy::OnlyBlock => { - // if the request is just for blocks then it can be removed on a stream termination - match maybe_block { - Some(block) => self - .backfill_requests - .get(&request_id) - .cloned() - .map(|batch_id| (batch_id, Some(BlockWrapper::Block { block }))), - None => self - .backfill_requests - .remove(&request_id) - .map(|batch_id| (batch_id, None)), - } - } + is_stream_terminator: bool, + ) -> Option { + if is_stream_terminator { + self.backfill_requests + .remove(&request_id) + .map(|batch_id| batch_id) + } else { + self.backfill_requests.get(&request_id).cloned() } } - pub fn backfill_sync_sidecar_response( + /// Received a blocks by range response for a request that couples blocks and blobs. + pub fn backfill_sync_block_and_blob_response( &mut self, request_id: Id, - maybe_sidecar: Option>>, - ) -> Option<(BatchId, Option>)> { + block_or_blob: BlockOrBlob, + ) -> Option<(BatchId, Result>, &'static str>)> { match self.backfill_sidecar_pair_requests.entry(request_id) { Entry::Occupied(mut entry) => { - let (batch_id, info) = entry.get_mut(); - let batch_id = batch_id.clone(); - info.add_sidecar_response(maybe_sidecar); - let maybe_block = info - .pop_response() - .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { block_sidecar_pair }); + let (_, info) = entry.get_mut(); + match block_or_blob { + BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + } if info.is_finished() { - entry.remove(); + // If the request is finished, unqueue everything + let (batch_id, info) = entry.remove(); + Some((batch_id, info.into_responses())) + } else { + None } - Some((batch_id, maybe_block)) } Entry::Vacant(_) => None, } diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index 73e6f49eb0e..a4869f75b73 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -686,13 +686,10 @@ mod tests { // add some peers let (peer1, local_info, head_info) = rig.head_peer(); range.add_peer(&mut rig.cx, local_info, peer1, head_info); - let ((chain1, batch1, _), id1) = match rig.grab_request(&peer1).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => ( - rig.cx - .range_sync_block_response(id, None, ExpectedBatchTy::OnlyBlock) - .unwrap(), - id, - ), + let ((chain1, batch1), id1) = match rig.grab_request(&peer1).0 { + RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { + (rig.cx.range_sync_response(id, true).unwrap(), id) + } other => panic!("unexpected request {:?}", other), }; @@ -708,13 +705,10 @@ mod tests { // while the ee is offline, more peers might arrive. Add a new finalized peer. let (peer2, local_info, finalized_info) = rig.finalized_peer(); range.add_peer(&mut rig.cx, local_info, peer2, finalized_info); - let ((chain2, batch2, _), id2) = match rig.grab_request(&peer2).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => ( - rig.cx - .range_sync_block_response(id, None, ExpectedBatchTy::OnlyBlock) - .unwrap(), - id, - ), + let ((chain2, batch2), id2) = match rig.grab_request(&peer2).0 { + RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { + (rig.cx.range_sync_response(id, true).unwrap(), id) + } other => panic!("unexpected request {:?}", other), }; diff --git a/consensus/types/src/blobs_sidecar.rs b/consensus/types/src/blobs_sidecar.rs index 430936cc275..f1e2a4bb16b 100644 --- a/consensus/types/src/blobs_sidecar.rs +++ b/consensus/types/src/blobs_sidecar.rs @@ -1,13 +1,17 @@ -use crate::{Blob, EthSpec, Hash256, SignedRoot, Slot}; +use crate::test_utils::TestRandom; +use crate::{Blob, EthSpec, Hash256, SignedBeaconBlock, SignedRoot, Slot}; use kzg::KzgProof; use serde_derive::{Deserialize, Serialize}; use ssz::Encode; use ssz_derive::{Decode, Encode}; use ssz_types::VariableList; +use test_random_derive::TestRandom; use tree_hash_derive::TreeHash; #[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, PartialEq, Default)] +#[derive( + Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, PartialEq, Default, TestRandom, +)] #[serde(bound = "T: EthSpec")] pub struct BlobsSidecar { pub beacon_block_root: Hash256, @@ -23,6 +27,7 @@ impl BlobsSidecar { pub fn empty() -> Self { Self::default() } + #[allow(clippy::integer_arithmetic)] pub fn max_size() -> usize { // Fixed part From 847f0de0ea20dcf8f27525b731102260828006c1 Mon Sep 17 00:00:00 2001 From: Diva M Date: Thu, 22 Dec 2022 17:32:33 -0500 Subject: [PATCH 31/59] change base From fbc147e273d15b779587154d89d2691ff77c749a Mon Sep 17 00:00:00 2001 From: Diva M Date: Thu, 22 Dec 2022 17:34:01 -0500 Subject: [PATCH 32/59] remove unused entry struct --- .../network/src/sync/block_sidecar_coupling.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index 762f37692fe..60c5a62eaa3 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -1,7 +1,4 @@ -use std::{ - collections::{hash_map::OccupiedEntry, VecDeque}, - sync::Arc, -}; +use std::{collections::VecDeque, sync::Arc}; use types::{ signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock, @@ -25,18 +22,6 @@ pub struct BlockBlobRequestInfo { is_sidecar_rpc_finished: bool, } -pub struct BlockBlobRequestEntry<'a, K, T: EthSpec> { - entry: OccupiedEntry<'a, K, BlockBlobRequestInfo>, -} - -impl<'a, K, T: EthSpec> From>> - for BlockBlobRequestEntry<'a, K, T> -{ - fn from(entry: OccupiedEntry<'a, K, BlockBlobRequestInfo>) -> Self { - BlockBlobRequestEntry { entry } - } -} - impl BlockBlobRequestInfo { pub fn add_block_response(&mut self, maybe_block: Option>>) { match maybe_block { From e24f6c93d90387c7c17071add448fbdb1e307147 Mon Sep 17 00:00:00 2001 From: Diva M Date: Thu, 22 Dec 2022 17:38:16 -0500 Subject: [PATCH 33/59] fix ctrl c'd comment --- beacon_node/network/src/sync/manager.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 155e2d2131c..f003ca27e55 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -827,10 +827,10 @@ impl SyncManager { } } Err(e) => { - // inform backfill that the request needs to be treated as failed + // inform range that the request needs to be treated as failed // With time we will want to downgrade this log warn!( - self.log, "Blocks and blobs request for backfill received invalid data"; + self.log, "Blocks and blobs request for range received invalid data"; "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy From 48ff56d9cb0173b4a61b6727017b5059b59275c6 Mon Sep 17 00:00:00 2001 From: Diva M Date: Thu, 22 Dec 2022 17:38:55 -0500 Subject: [PATCH 34/59] spelling --- beacon_node/network/src/sync/manager.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index f003ca27e55..305f9f70691 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -841,7 +841,7 @@ impl SyncManager { } } - /// Handles receiving a response for a bacjfill sync request that should have both blocks and + /// Handles receiving a response for a Backfill sync request that should have both blocks and /// blobs. fn block_blob_backfill_response( &mut self, From 3643f5cc19fe02d661ab08a61289113b6901211e Mon Sep 17 00:00:00 2001 From: Diva M Date: Thu, 22 Dec 2022 17:47:36 -0500 Subject: [PATCH 35/59] spelling --- beacon_node/network/src/sync/network_context.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 912a5620e8a..8e651e89737 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -304,7 +304,7 @@ impl SyncNetworkContext { BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { - // If the request is finished, unqueue everything + // If the request is finished, dequeue everything let (chain_id, batch_id, info) = entry.remove(); Some((chain_id, batch_id, info.into_responses())) } else { @@ -372,7 +372,7 @@ impl SyncNetworkContext { BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { - // If the request is finished, unqueue everything + // If the request is finished, dequeue everything let (batch_id, info) = entry.remove(); Some((batch_id, info.into_responses())) } else { From 66f9aa922d5f049deb1eec8a7877b9aaba163224 Mon Sep 17 00:00:00 2001 From: Diva M Date: Fri, 23 Dec 2022 09:52:10 -0500 Subject: [PATCH 36/59] clean up and improvements --- .../src/sync/block_sidecar_coupling.rs | 87 +++++++------------ .../network/src/sync/network_context.rs | 8 +- 2 files changed, 36 insertions(+), 59 deletions(-) diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index 60c5a62eaa3..95acadffb62 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -5,11 +5,6 @@ use types::{ SignedBeaconBlockAndBlobsSidecar, }; -struct ReceivedData { - block: Option>>, - blob: Option>>, -} - #[derive(Debug, Default)] pub struct BlockBlobRequestInfo { /// Blocks we have received awaiting for their corresponding sidecar. @@ -17,84 +12,68 @@ pub struct BlockBlobRequestInfo { /// Sidecars we have received awaiting for their corresponding block. accumulated_sidecars: VecDeque>>, /// Whether the individual RPC request for blocks is finished or not. - is_blocks_rpc_finished: bool, + is_blocks_stream_terminated: bool, /// Whether the individual RPC request for sidecars is finished or not. - is_sidecar_rpc_finished: bool, + is_sidecars_stream_terminated: bool, } impl BlockBlobRequestInfo { pub fn add_block_response(&mut self, maybe_block: Option>>) { match maybe_block { Some(block) => self.accumulated_blocks.push_back(block), - None => self.is_blocks_rpc_finished = true, + None => self.is_blocks_stream_terminated = true, } } pub fn add_sidecar_response(&mut self, maybe_sidecar: Option>>) { match maybe_sidecar { Some(sidecar) => self.accumulated_sidecars.push_back(sidecar), - None => self.is_sidecar_rpc_finished = true, + None => self.is_sidecars_stream_terminated = true, } } pub fn into_responses(self) -> Result>, &'static str> { let BlockBlobRequestInfo { accumulated_blocks, - accumulated_sidecars, + mut accumulated_sidecars, .. } = self; - // Create the storage for our pairs. - let mut pairs = Vec::with_capacity(accumulated_blocks.len()); - - // ASSUMPTION: There can't be more more blobs than blocks. i.e. sending any block (empty + // ASSUMPTION: There can't be more more blobs than blocks. i.e. sending any blob (empty // included) for a skipped slot is not permitted. - for sidecar in accumulated_sidecars { - let blob_slot = sidecar.beacon_block_slot; - // First queue any blocks that might not have a blob. - while let Some(block) = { - // We identify those if their slot is less than the current blob's slot. - match accumulated_blocks.front() { - Some(borrowed_block) if borrowed_block.slot() < blob_slot => { - accumulated_blocks.pop_front() - } - Some(_) => None, - None => { - // We received a blob and ran out of blocks. This is a peer error - return Err("Blob without more blobs to pair with returned by peer"); - } + let pairs = accumulated_blocks + .into_iter() + .map(|beacon_block| { + if accumulated_sidecars + .front() + .map(|sidecar| sidecar.beacon_block_slot == beacon_block.slot()) + .unwrap_or(false) + { + let blobs_sidecar = + accumulated_sidecars.pop_front().ok_or("missing sidecar")?; + Ok(BlockWrapper::BlockAndBlob { + block_sidecar_pair: SignedBeaconBlockAndBlobsSidecar { + beacon_block, + blobs_sidecar, + }, + }) + } else { + Ok(BlockWrapper::Block { + block: beacon_block, + }) } - } { - pairs.push(BlockWrapper::Block { block }) - } - - // The next block must be present and must match the blob's slot - let next_block = accumulated_blocks - .pop_front() - .expect("If block stream ended, an error was previously returned"); - if next_block.slot() != blob_slot { - // We verified that the slot of the block is not less than the slot of the blob (it - // would have been returned before). It's also not equal, so this block is ahead - // than the blob. This means the blob is not paired. - return Err("Blob without a matching block returned by peer"); - } - pairs.push(BlockWrapper::BlockAndBlob { - block_sidecar_pair: SignedBeaconBlockAndBlobsSidecar { - beacon_block: next_block, - blobs_sidecar: sidecar, - }, - }); - } + }) + .collect::, _>>(); - // Every remaining block does not have a blob - for block in accumulated_blocks { - pairs.push(BlockWrapper::Block { block }) + // if accumulated sidecars is not empty, throw an error. + if !accumulated_sidecars.is_empty() { + return Err("Received more sidecars than blocks"); } - Ok(pairs) + pairs } pub fn is_finished(&self) -> bool { - self.is_blocks_rpc_finished && self.is_sidecar_rpc_finished + self.is_blocks_stream_terminated && self.is_sidecars_stream_terminated } } diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 8e651e89737..cc94db77cae 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -278,11 +278,9 @@ impl SyncNetworkContext { is_stream_terminator: bool, ) -> Option<(ChainId, BatchId)> { if is_stream_terminator { - self.range_requests - .remove(&request_id) - .map(|(chain_id, batch_id)| (chain_id, batch_id)) + self.range_requests.remove(&request_id) } else { - self.range_requests.get(&request_id).cloned() + self.range_requests.get(&request_id).copied() } } @@ -354,7 +352,7 @@ impl SyncNetworkContext { .remove(&request_id) .map(|batch_id| batch_id) } else { - self.backfill_requests.get(&request_id).cloned() + self.backfill_requests.get(&request_id).copied() } } From 5db0a88d4f4fed0854e77be0ccdd84842f8aea82 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 23 Dec 2022 10:27:01 -0500 Subject: [PATCH 37/59] fix compilation errors from merge --- .../lighthouse_network/src/rpc/codec/ssz_snappy.rs | 5 ++++- lcli/Cargo.toml | 1 - testing/ef_tests/Cargo.toml | 1 - testing/ef_tests/src/cases/operations.rs | 13 +++++-------- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index d69b42c0be7..df5350d9494 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -719,7 +719,10 @@ fn context_bytes_to_fork_name( let encoded = hex::encode(context_bytes); RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - format!("Context bytes {} do not correspond to a valid fork", encoded), + format!( + "Context bytes {} do not correspond to a valid fork", + encoded + ), ) }) } diff --git a/lcli/Cargo.toml b/lcli/Cargo.toml index 4130c0f6afc..0da6b6f0902 100644 --- a/lcli/Cargo.toml +++ b/lcli/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" [features] portable = ["bls/supranational-portable"] fake_crypto = ['bls/fake_crypto'] -withdrawals = ["types/withdrawals", "beacon_chain/withdrawals", "store/withdrawals", "state_processing/withdrawals"] withdrawals-processing = ["beacon_chain/withdrawals-processing", "store/withdrawals-processing", "state_processing/withdrawals-processing"] [dependencies] diff --git a/testing/ef_tests/Cargo.toml b/testing/ef_tests/Cargo.toml index 1b42b42ff10..23bb29364d8 100644 --- a/testing/ef_tests/Cargo.toml +++ b/testing/ef_tests/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" ef_tests = [] milagro = ["bls/milagro"] fake_crypto = ["bls/fake_crypto"] -withdrawals = ["state_processing/withdrawals", "store/withdrawals", "beacon_chain/withdrawals", "types/withdrawals", "execution_layer/withdrawals"] withdrawals-processing = ["state_processing/withdrawals-processing", "store/withdrawals-processing", "beacon_chain/withdrawals-processing", "execution_layer/withdrawals-processing"] [dependencies] diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index dd43eeccef3..a2356519ad5 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -5,9 +5,9 @@ use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yam use crate::testing_spec; use serde_derive::Deserialize; #[cfg(feature = "withdrawals-processing")] -use state_processing::per_block_processing::process_operations::{ - process_bls_to_execution_changes, process_bls_to_execution_changes, -}; +use state_processing::per_block_processing::process_operations::process_bls_to_execution_changes; +#[cfg(feature = "withdrawals-processing")] +use state_processing::per_block_processing::process_withdrawals; use state_processing::{ per_block_processing::{ errors::BlockProcessingError, @@ -356,10 +356,6 @@ impl Operation for WithdrawalsPayload { return false; } - if !cfg!(feature = "withdrawals") { - return false; - } - fork_name != ForkName::Base && fork_name != ForkName::Altair && fork_name != ForkName::Merge } @@ -372,7 +368,7 @@ impl Operation for WithdrawalsPayload { }) } - #[cfg(feature = "withdrawals")] + #[cfg(feature = "withdrawals-processing")] fn apply_to( &self, state: &mut BeaconState, @@ -386,6 +382,7 @@ impl Operation for WithdrawalsPayload { process_withdrawals::<_, FullPayload<_>>(state, self.payload.to_ref(), spec) } } +} #[cfg(feature = "withdrawals-processing")] impl Operation for SignedBlsToExecutionChange { From 901764b8f0c85eaee474bb95c29af72400197efe Mon Sep 17 00:00:00 2001 From: Diva M Date: Fri, 23 Dec 2022 10:32:26 -0500 Subject: [PATCH 38/59] backfill batches need to be of just one epoch --- .../network/src/sync/backfill_sync/mod.rs | 2 +- .../network/src/sync/network_context.rs | 20 ++++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/beacon_node/network/src/sync/backfill_sync/mod.rs b/beacon_node/network/src/sync/backfill_sync/mod.rs index 76850a54546..56ed551530c 100644 --- a/beacon_node/network/src/sync/backfill_sync/mod.rs +++ b/beacon_node/network/src/sync/backfill_sync/mod.rs @@ -33,7 +33,7 @@ use types::{Epoch, EthSpec}; /// we will negatively report peers with poor bandwidth. This can be set arbitrarily high, in which /// case the responder will fill the response up to the max request size, assuming they have the /// bandwidth to do so. -pub const BACKFILL_EPOCHS_PER_BATCH: u64 = 2; +pub const BACKFILL_EPOCHS_PER_BATCH: u64 = 1; /// The maximum number of batches to queue before requesting more. const BACKFILL_BATCH_BUFFER_SIZE: u8 = 20; diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index a38f1e0fe4c..36da3bf8213 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -531,25 +531,21 @@ impl SyncNetworkContext { id } + /// Check whether a batch for this epoch (and only this epoch) should request just blocks or + /// blocks and blobs. pub fn batch_type(&self, epoch: types::Epoch) -> ExpectedBatchTy { - // Keep tests only for blocks. + const _: () = assert!( + super::backfill_sync::BACKFILL_EPOCHS_PER_BATCH == 1 + && super::range_sync::EPOCHS_PER_BATCH == 1, + "To deal with alignment with 4844 boundaries, batches need to be of just one epoch" + ); #[cfg(test)] { + // Keep tests only for blocks. return ExpectedBatchTy::OnlyBlock; } #[cfg(not(test))] { - use super::range_sync::EPOCHS_PER_BATCH; - assert_eq!( - EPOCHS_PER_BATCH, 1, - "If this is not one, everything will fail horribly" - ); - - // Here we need access to the beacon chain, check the fork boundary, the current epoch, the - // blob period to serve and check with that if the batch is a blob batch or not. - // NOTE: This would carelessly assume batch sizes are always 1 epoch, to avoid needing to - // align with the batch boundary. - if let Some(data_availability_boundary) = self.chain.data_availability_boundary() { if epoch >= data_availability_boundary { ExpectedBatchTy::OnlyBlockBlobs From 24087f104d9883ca65e2b03badda57847b3ddf94 Mon Sep 17 00:00:00 2001 From: Diva M Date: Fri, 23 Dec 2022 10:49:46 -0500 Subject: [PATCH 39/59] add the batch type to the Batch's KV --- beacon_node/network/src/sync/range_sync/batch.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/beacon_node/network/src/sync/range_sync/batch.rs b/beacon_node/network/src/sync/range_sync/batch.rs index b0d266e0740..7453e1df614 100644 --- a/beacon_node/network/src/sync/range_sync/batch.rs +++ b/beacon_node/network/src/sync/range_sync/batch.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; use std::hash::{Hash, Hasher}; use std::ops::Sub; use std::sync::Arc; +use strum::Display; use types::signed_block_and_blobs::BlockWrapper; use types::{Epoch, EthSpec, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, Slot}; @@ -40,7 +41,8 @@ impl BatchTy { pub struct MixedBlockTyErr; /// Type of expected batch. -#[derive(Debug, Clone)] +#[derive(Debug, Copy, Clone, Display)] +#[strum(serialize_all = "snake_case")] pub enum ExpectedBatchTy { OnlyBlockBlobs, OnlyBlock, @@ -247,7 +249,7 @@ impl BatchInfo { start_slot: self.start_slot.into(), count: self.end_slot.sub(self.start_slot).into(), }, - self.batch_type.clone(), + self.batch_type, ) } @@ -557,6 +559,7 @@ impl slog::KV for BatchInfo { serializer.emit_usize("processed", self.failed_processing_attempts.len())?; serializer.emit_u8("processed_no_penalty", self.non_faulty_processing_attempts)?; serializer.emit_arguments("state", &format_args!("{:?}", self.state))?; + serializer.emit_arguments("batch_ty", &format_args!("{}", self.batch_type)); slog::Result::Ok(()) } } From 5e11edc61202c6a3e5c7691904917a630516bd49 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 23 Dec 2022 12:47:38 -0500 Subject: [PATCH 40/59] fix blob validation for empty blobs --- .../beacon_chain/src/blob_verification.rs | 7 ++ .../beacon_chain/src/block_verification.rs | 23 ++++--- beacon_node/http_api/src/publish_blocks.rs | 6 +- .../network/src/beacon_processor/mod.rs | 4 +- .../beacon_processor/worker/sync_methods.rs | 6 +- .../src/sync/block_sidecar_coupling.rs | 10 ++- beacon_node/network/src/sync/manager.rs | 24 ++++--- .../network/src/sync/range_sync/batch.rs | 8 +-- .../state_processing/src/consensus_context.rs | 3 - consensus/types/src/blobs_sidecar.rs | 9 +++ consensus/types/src/signed_beacon_block.rs | 27 ++++++++ consensus/types/src/signed_block_and_blobs.rs | 65 ++++++++----------- crypto/kzg/src/kzg_proof.rs | 8 +++ 13 files changed, 119 insertions(+), 81 deletions(-) diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index 1b05c7d39f5..3e5f5e740f0 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -5,6 +5,7 @@ use crate::{kzg_utils, BeaconChainError}; use bls::PublicKey; use state_processing::per_block_processing::eip4844::eip4844::verify_kzg_commitments_against_transactions; use types::consts::eip4844::BLS_MODULUS; +use types::signed_beacon_block::BlobReconstructionError; use types::{BeaconStateError, BlobsSidecar, Hash256, KzgCommitment, Slot, Transactions}; #[derive(Debug)] @@ -91,6 +92,12 @@ pub enum BlobError { MissingBlobs, } +impl From for BlobError { + fn from(_: BlobReconstructionError) -> Self { + BlobError::MissingBlobs + } +} + impl From for BlobError { fn from(e: BeaconChainError) -> Self { BlobError::BeaconChainError(e) diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index b9e65bc0a23..6f330b8eaf6 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -87,6 +87,7 @@ use std::time::Duration; use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp}; use task_executor::JoinHandle; use tree_hash::TreeHash; +use types::signed_beacon_block::BlobReconstructionError; use types::signed_block_and_blobs::BlockWrapper; use types::{ BeaconBlockRef, BeaconState, BeaconStateError, BlindedPayload, ChainSpec, CloneConfig, Epoch, @@ -479,6 +480,12 @@ impl From for BlockError { } } +impl From for BlockError { + fn from(e: BlobReconstructionError) -> Self { + BlockError::BlobValidation(BlobError::from(e)) + } +} + /// Stores information about verifying a payload against an execution engine. pub struct PayloadVerificationOutcome { pub payload_verification_status: PayloadVerificationStatus, @@ -905,7 +912,7 @@ impl GossipVerifiedBlock { // Validate the block's execution_payload (if any). validate_execution_payload_for_gossip(&parent_block, block.message(), chain)?; - if let Some(blobs_sidecar) = block.blobs() { + if let Some(blobs_sidecar) = block.blobs(Some(block_root))? { let kzg_commitments = block .message() .body() @@ -919,7 +926,7 @@ impl GossipVerifiedBlock { .map_err(|_| BlockError::BlobValidation(BlobError::TransactionsMissing))? .ok_or(BlockError::BlobValidation(BlobError::TransactionsMissing))?; validate_blob_for_gossip( - blobs_sidecar, + &blobs_sidecar, kzg_commitments, transactions, block.slot(), @@ -1134,12 +1141,8 @@ impl IntoExecutionPendingBlock for Arc &SignedBeaconBlock { @@ -1563,7 +1566,7 @@ impl ExecutionPendingBlock { if let Some(data_availability_boundary) = chain.data_availability_boundary() { if block_slot.epoch(T::EthSpec::slots_per_epoch()) >= data_availability_boundary { let sidecar = block - .blobs() + .blobs(Some(block_root))? .ok_or(BlockError::BlobValidation(BlobError::MissingBlobs))?; let kzg = chain.kzg.as_ref().ok_or(BlockError::BlobValidation( BlobError::TrustedSetupNotInitialized, @@ -1586,7 +1589,7 @@ impl ExecutionPendingBlock { block.slot(), block_root, kzg_commitments, - sidecar, + &sidecar, ) .map_err(|e| BlockError::BlobValidation(BlobError::KzgError(e)))? { diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index 085f5036f4f..f024e49e2a8 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -43,9 +43,7 @@ pub async fn publish_block( network_tx, PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), )?; - BlockWrapper::BlockAndBlob { - block_sidecar_pair: block_and_blobs, - } + BlockWrapper::BlockAndBlob(block_and_blobs) } else { //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required return Err(warp_utils::reject::broadcast_without_import(format!( @@ -54,7 +52,7 @@ pub async fn publish_block( } } else { crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; - BlockWrapper::Block { block } + BlockWrapper::Block(block) }; // Determine the delay after the start of the slot, register it with metrics. diff --git a/beacon_node/network/src/beacon_processor/mod.rs b/beacon_node/network/src/beacon_processor/mod.rs index 887ecc49776..9de006c84f5 100644 --- a/beacon_node/network/src/beacon_processor/mod.rs +++ b/beacon_node/network/src/beacon_processor/mod.rs @@ -1699,7 +1699,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - BlockWrapper::Block { block }, + BlockWrapper::Block(block), work_reprocessing_tx, duplicate_cache, seen_timestamp, @@ -1721,7 +1721,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - BlockWrapper::BlockAndBlob { block_sidecar_pair }, + BlockWrapper::BlockAndBlob(block_sidecar_pair), work_reprocessing_tx, duplicate_cache, seen_timestamp, diff --git a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs index dafc00bddb9..b9ad82cf8b9 100644 --- a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs @@ -194,11 +194,9 @@ impl Worker { let unwrapped = downloaded_blocks .into_iter() .map(|block| match block { - BlockWrapper::Block { block } => block, + BlockWrapper::Block(block) => block, //FIXME(sean) handle blobs in backfill - BlockWrapper::BlockAndBlob { - block_sidecar_pair: _, - } => todo!(), + BlockWrapper::BlockAndBlob(_) => todo!(), }) .collect(); diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index 95acadffb62..f82417db3a1 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -51,16 +51,14 @@ impl BlockBlobRequestInfo { { let blobs_sidecar = accumulated_sidecars.pop_front().ok_or("missing sidecar")?; - Ok(BlockWrapper::BlockAndBlob { - block_sidecar_pair: SignedBeaconBlockAndBlobsSidecar { + Ok(BlockWrapper::BlockAndBlob( + SignedBeaconBlockAndBlobsSidecar { beacon_block, blobs_sidecar, }, - }) + )) } else { - Ok(BlockWrapper::Block { - block: beacon_block, - }) + Ok(BlockWrapper::Block(beacon_block)) } }) .collect::, _>>(); diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 305f9f70691..109ed81941a 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -734,14 +734,14 @@ impl SyncManager { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - beacon_block.map(|block| BlockWrapper::Block { block }), + beacon_block.map(|block| BlockWrapper::Block(block)), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - beacon_block.map(|block| BlockWrapper::Block { block }), + beacon_block.map(|block| BlockWrapper::Block(block)), seen_timestamp, &mut self.network, ), @@ -756,7 +756,7 @@ impl SyncManager { batch_id, &peer_id, id, - beacon_block.map(|block| BlockWrapper::Block { block }), + beacon_block.map(|block| BlockWrapper::Block(block)), ) { Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), Ok(ProcessResult::Successful) => {} @@ -780,7 +780,7 @@ impl SyncManager { chain_id, batch_id, id, - beacon_block.map(|block| BlockWrapper::Block { block }), + beacon_block.map(|block| BlockWrapper::Block(block)), ); self.update_sync_state(); } @@ -930,9 +930,11 @@ impl SyncManager { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { - // TODO: why is this in an arc - block_sidecar_pair: (*block_sidecar_pair).clone(), + block_sidecar_pair.map(|block_sidecar_pair| { + BlockWrapper::BlockAndBlob( + // TODO: why is this in an arc + (*block_sidecar_pair).clone(), + ) }), seen_timestamp, &mut self.network, @@ -940,9 +942,11 @@ impl SyncManager { RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { - // TODO: why is this in an arc - block_sidecar_pair: (*block_sidecar_pair).clone(), + block_sidecar_pair.map(|block_sidecar_pair| { + BlockWrapper::BlockAndBlob( + // TODO: why is this in an arc + (*block_sidecar_pair).clone(), + ) }), seen_timestamp, &mut self.network, diff --git a/beacon_node/network/src/sync/range_sync/batch.rs b/beacon_node/network/src/sync/range_sync/batch.rs index b0d266e0740..f7e5945988a 100644 --- a/beacon_node/network/src/sync/range_sync/batch.rs +++ b/beacon_node/network/src/sync/range_sync/batch.rs @@ -25,11 +25,11 @@ impl BatchTy { match self { BatchTy::Blocks(blocks) => blocks .into_iter() - .map(|block| BlockWrapper::Block { block }) + .map(|block| BlockWrapper::Block(block)) .collect(), BatchTy::BlocksAndBlobs(block_sidecar_pair) => block_sidecar_pair .into_iter() - .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob { block_sidecar_pair }) + .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob(block_sidecar_pair)) .collect(), } } @@ -413,7 +413,7 @@ impl BatchInfo { match self.batch_type { ExpectedBatchTy::OnlyBlockBlobs => { let blocks = blocks.into_iter().map(|block| { - let BlockWrapper::BlockAndBlob { block_sidecar_pair: block_and_blob } = block else { + let BlockWrapper::BlockAndBlob(block_and_blob) = block else { panic!("Batches should never have a mixed type. This is a bug. Contact D") }; block_and_blob @@ -422,7 +422,7 @@ impl BatchInfo { } ExpectedBatchTy::OnlyBlock => { let blocks = blocks.into_iter().map(|block| { - let BlockWrapper::Block { block } = block else { + let BlockWrapper::Block(block) = block else { panic!("Batches should never have a mixed type. This is a bug. Contact D") }; block diff --git a/consensus/state_processing/src/consensus_context.rs b/consensus/state_processing/src/consensus_context.rs index f5585426ce9..3a5aebc474e 100644 --- a/consensus/state_processing/src/consensus_context.rs +++ b/consensus/state_processing/src/consensus_context.rs @@ -21,8 +21,6 @@ pub struct ConsensusContext { /// Cache of indexed attestations constructed during block processing. indexed_attestations: HashMap<(AttestationData, BitList), IndexedAttestation>, - /// Should only be populated if the sidecar has not been validated. - blobs_sidecar: Option>>, /// Whether `validate_blobs_sidecar` has successfully passed. blobs_sidecar_validated: bool, /// Whether `verify_kzg_commitments_against_transactions` has successfully passed. @@ -49,7 +47,6 @@ impl ConsensusContext { proposer_index: None, current_block_root: None, indexed_attestations: HashMap::new(), - blobs_sidecar: None, blobs_sidecar_validated: false, blobs_verified_vs_txs: false, } diff --git a/consensus/types/src/blobs_sidecar.rs b/consensus/types/src/blobs_sidecar.rs index f1e2a4bb16b..d522227a6f3 100644 --- a/consensus/types/src/blobs_sidecar.rs +++ b/consensus/types/src/blobs_sidecar.rs @@ -28,6 +28,15 @@ impl BlobsSidecar { Self::default() } + pub fn empty_from_parts(beacon_block_root: Hash256, beacon_block_slot: Slot) -> Self { + Self { + beacon_block_root, + beacon_block_slot, + blobs: VariableList::empty(), + kzg_aggregated_proof: KzgProof::empty(), + } + } + #[allow(clippy::integer_arithmetic)] pub fn max_size() -> usize { // Fixed part diff --git a/consensus/types/src/signed_beacon_block.rs b/consensus/types/src/signed_beacon_block.rs index 14f9358f611..89ccb95a164 100644 --- a/consensus/types/src/signed_beacon_block.rs +++ b/consensus/types/src/signed_beacon_block.rs @@ -36,6 +36,10 @@ impl From for Hash256 { } } +pub enum BlobReconstructionError { + BlobsMissing, +} + /// A `BeaconBlock` and a signature from its proposer. #[superstruct( variants(Base, Altair, Merge, Capella, Eip4844), @@ -235,6 +239,29 @@ impl> SignedBeaconBlock pub fn canonical_root(&self) -> Hash256 { self.message().tree_hash_root() } + + /// Reconstructs an empty `BlobsSidecar`, using the given block root if provided, else calculates it. + /// If this block has kzg commitments, an error will be returned. If this block is from prior to the + /// Eip4844 fork, `None` will be returned. + pub fn reconstruct_empty_blobs( + &self, + block_root_opt: Option, + ) -> Result>, BlobReconstructionError> { + self.message() + .body() + .blob_kzg_commitments() + .map(|kzg_commitments| { + if kzg_commitments.len() > 0 { + Err(BlobReconstructionError::BlobsMissing) + } else { + Ok(Some(BlobsSidecar::empty_from_parts( + block_root_opt.unwrap_or(self.canonical_root()), + self.slot(), + ))) + } + }) + .unwrap_or(Ok(None)) + } } // We can convert pre-Bellatrix blocks without payloads into blocks with payloads. diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index 09ff89e7b3e..4fcd09de4d3 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -1,3 +1,4 @@ +use crate::signed_beacon_block::BlobReconstructionError; use crate::{BlobsSidecar, EthSpec, Hash256, SignedBeaconBlock, SignedBeaconBlockEip4844, Slot}; use serde_derive::{Deserialize, Serialize}; use ssz::{Decode, DecodeError}; @@ -35,60 +36,52 @@ impl SignedBeaconBlockAndBlobsSidecar { /// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. #[derive(Clone, Debug)] pub enum BlockWrapper { - Block { - block: Arc>, - }, - BlockAndBlob { - block_sidecar_pair: SignedBeaconBlockAndBlobsSidecar, - }, + Block(Arc>), + BlockAndBlob(SignedBeaconBlockAndBlobsSidecar), } impl BlockWrapper { pub fn slot(&self) -> Slot { match self { - BlockWrapper::Block { block } => block.slot(), - BlockWrapper::BlockAndBlob { block_sidecar_pair } => { + BlockWrapper::Block(block) => block.slot(), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.slot() } } } pub fn block(&self) -> &SignedBeaconBlock { match self { - BlockWrapper::Block { block } => &block, - BlockWrapper::BlockAndBlob { block_sidecar_pair } => &block_sidecar_pair.beacon_block, + BlockWrapper::Block(block) => &block, + BlockWrapper::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, } } pub fn block_cloned(&self) -> Arc> { match self { - BlockWrapper::Block { block } => block.clone(), - BlockWrapper::BlockAndBlob { block_sidecar_pair } => { + BlockWrapper::Block(block) => block.clone(), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.clone() } } } - pub fn blobs(&self) -> Option<&BlobsSidecar> { + pub fn blobs( + &self, + block_root: Option, + ) -> Result>>, BlobReconstructionError> { match self { - BlockWrapper::Block { .. } => None, - BlockWrapper::BlockAndBlob { block_sidecar_pair } => { - Some(&block_sidecar_pair.blobs_sidecar) - } - } - } - - pub fn blobs_cloned(&self) -> Option>> { - match self { - BlockWrapper::Block { block: _ } => None, - BlockWrapper::BlockAndBlob { block_sidecar_pair } => { - Some(block_sidecar_pair.blobs_sidecar.clone()) + BlockWrapper::Block(block) => block + .reconstruct_empty_blobs(block_root) + .map(|blob_opt| blob_opt.map(Arc::new)), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + Ok(Some(block_sidecar_pair.blobs_sidecar.clone())) } } } pub fn message(&self) -> crate::BeaconBlockRef { match self { - BlockWrapper::Block { block } => block.message(), - BlockWrapper::BlockAndBlob { block_sidecar_pair } => { + BlockWrapper::Block(block) => block.message(), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.message() } } @@ -100,8 +93,8 @@ impl BlockWrapper { pub fn deconstruct(self) -> (Arc>, Option>>) { match self { - BlockWrapper::Block { block } => (block, None), - BlockWrapper::BlockAndBlob { block_sidecar_pair } => { + BlockWrapper::Block(block) => (block, None), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, blobs_sidecar, @@ -112,29 +105,25 @@ impl BlockWrapper { } } -// TODO: probably needes to be changed. This is needed because SignedBeaconBlockAndBlobsSidecar +// FIXME(sean): probably needs to be changed. This is needed because SignedBeaconBlockAndBlobsSidecar // does not implement Hash impl std::hash::Hash for BlockWrapper { fn hash(&self, state: &mut H) { match self { - BlockWrapper::Block { block } => block.hash(state), - BlockWrapper::BlockAndBlob { - block_sidecar_pair: block_and_blob, - } => block_and_blob.beacon_block.hash(state), + BlockWrapper::Block(block) => block.hash(state), + BlockWrapper::BlockAndBlob(block_and_blob) => block_and_blob.beacon_block.hash(state), } } } impl From> for BlockWrapper { fn from(block: SignedBeaconBlock) -> Self { - BlockWrapper::Block { - block: Arc::new(block), - } + BlockWrapper::Block(Arc::new(block)) } } impl From>> for BlockWrapper { fn from(block: Arc>) -> Self { - BlockWrapper::Block { block } + BlockWrapper::Block(block) } } diff --git a/crypto/kzg/src/kzg_proof.rs b/crypto/kzg/src/kzg_proof.rs index cb6e14df4ad..be85088f760 100644 --- a/crypto/kzg/src/kzg_proof.rs +++ b/crypto/kzg/src/kzg_proof.rs @@ -12,6 +12,14 @@ const KZG_PROOF_BYTES_LEN: usize = 48; #[ssz(struct_behaviour = "transparent")] pub struct KzgProof(pub [u8; KZG_PROOF_BYTES_LEN]); +impl KzgProof { + pub fn empty() -> Self { + let mut bytes = [0; KZG_PROOF_BYTES_LEN]; + bytes[0] = 192; + Self(bytes) + } +} + impl fmt::Display for KzgProof { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", eth2_serde_utils::hex::encode(self.0)) From d09523802b9dd3c1ef805a9943db2244a69b9c27 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 23 Dec 2022 12:52:26 -0500 Subject: [PATCH 41/59] impl hash correctly for the blob wrapper --- consensus/types/src/blobs_sidecar.rs | 4 +++- consensus/types/src/signed_block_and_blobs.rs | 19 +++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/consensus/types/src/blobs_sidecar.rs b/consensus/types/src/blobs_sidecar.rs index d522227a6f3..de14f7cb527 100644 --- a/consensus/types/src/blobs_sidecar.rs +++ b/consensus/types/src/blobs_sidecar.rs @@ -1,3 +1,4 @@ +use derivative::Derivative; use crate::test_utils::TestRandom; use crate::{Blob, EthSpec, Hash256, SignedBeaconBlock, SignedRoot, Slot}; use kzg::KzgProof; @@ -10,9 +11,10 @@ use tree_hash_derive::TreeHash; #[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] #[derive( - Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, PartialEq, Default, TestRandom, + Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, Default, TestRandom, Derivative )] #[serde(bound = "T: EthSpec")] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] pub struct BlobsSidecar { pub beacon_block_root: Hash256, pub beacon_block_slot: Slot, diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index 4fcd09de4d3..721fe59eca3 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -5,6 +5,7 @@ use ssz::{Decode, DecodeError}; use ssz_derive::{Decode, Encode}; use std::sync::Arc; use tree_hash_derive::TreeHash; +use derivative::Derivative; #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, PartialEq)] #[serde(bound = "T: EthSpec")] @@ -13,8 +14,8 @@ pub struct SignedBeaconBlockAndBlobsSidecarDecode { pub blobs_sidecar: BlobsSidecar, } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, TreeHash, PartialEq)] -#[serde(bound = "T: EthSpec")] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, TreeHash, Derivative)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] pub struct SignedBeaconBlockAndBlobsSidecar { pub beacon_block: Arc>, pub blobs_sidecar: Arc>, @@ -34,7 +35,8 @@ impl SignedBeaconBlockAndBlobsSidecar { } /// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Derivative)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] pub enum BlockWrapper { Block(Arc>), BlockAndBlob(SignedBeaconBlockAndBlobsSidecar), @@ -105,17 +107,6 @@ impl BlockWrapper { } } -// FIXME(sean): probably needs to be changed. This is needed because SignedBeaconBlockAndBlobsSidecar -// does not implement Hash -impl std::hash::Hash for BlockWrapper { - fn hash(&self, state: &mut H) { - match self { - BlockWrapper::Block(block) => block.hash(state), - BlockWrapper::BlockAndBlob(block_and_blob) => block_and_blob.beacon_block.hash(state), - } - } -} - impl From> for BlockWrapper { fn from(block: SignedBeaconBlock) -> Self { BlockWrapper::Block(Arc::new(block)) From 1dc0759f57be77bda73f7cbd2b384648cb4d8967 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 23 Dec 2022 12:53:59 -0500 Subject: [PATCH 42/59] impl hash correctly for the blob wrapper --- beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- beacon_node/beacon_chain/src/early_attester_cache.rs | 2 +- consensus/types/src/signed_block_and_blobs.rs | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index ab008171536..a8ed7056180 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2944,7 +2944,7 @@ impl BeaconChain { ops.push(StoreOp::PutBlock(block_root, signed_block.clone())); ops.push(StoreOp::PutState(block.state_root(), &state)); - if let Some(blobs) = blobs { + if let Some(blobs) = blobs? { //FIXME(sean) using this for debugging for now info!(self.log, "Writing blobs to store"; "block_root" => ?block_root); ops.push(StoreOp::PutBlobs(block_root, blobs)); diff --git a/beacon_node/beacon_chain/src/early_attester_cache.rs b/beacon_node/beacon_chain/src/early_attester_cache.rs index f7b69a0d783..9254a3eb3f0 100644 --- a/beacon_node/beacon_chain/src/early_attester_cache.rs +++ b/beacon_node/beacon_chain/src/early_attester_cache.rs @@ -77,7 +77,7 @@ impl EarlyAttesterCache { source, target, block, - blobs, + blobs: blobs?, proto_block, }; diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index 721fe59eca3..2c9955bdb8b 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -93,15 +93,17 @@ impl BlockWrapper { self.block().parent_root() } - pub fn deconstruct(self) -> (Arc>, Option>>) { + pub fn deconstruct(self) -> (Arc>, Result>>, BlobReconstructionError>) { match self { - BlockWrapper::Block(block) => (block, None), + BlockWrapper::Block(block) => (block, block + .reconstruct_empty_blobs(block_root) + .map(|blob_opt| blob_opt.map(Arc::new))), BlockWrapper::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, blobs_sidecar, } = block_sidecar_pair; - (beacon_block, Some(blobs_sidecar)) + (beacon_block, Ok(Some(blobs_sidecar))) } } } From adf5f462d5bea99bcc3d603398d295bcf6769319 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Fri, 23 Dec 2022 12:59:04 -0500 Subject: [PATCH 43/59] fix blob validation for empty blobs when using --- beacon_node/beacon_chain/src/attester_cache.rs | 1 + beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- beacon_node/beacon_chain/src/early_attester_cache.rs | 4 ++-- consensus/types/src/signed_block_and_blobs.rs | 11 +++++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/beacon_node/beacon_chain/src/attester_cache.rs b/beacon_node/beacon_chain/src/attester_cache.rs index 24963a125d2..8e2dfdab82c 100644 --- a/beacon_node/beacon_chain/src/attester_cache.rs +++ b/beacon_node/beacon_chain/src/attester_cache.rs @@ -42,6 +42,7 @@ pub enum Error { // Boxed to avoid an infinite-size recursion issue. BeaconChain(Box), MissingBeaconState(Hash256), + MissingBlobs, FailedToTransitionState(StateAdvanceError), CannotAttestToFutureState { state_slot: Slot, diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index a8ed7056180..3e2be9202b1 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2935,7 +2935,7 @@ impl BeaconChain { // If the write fails, revert fork choice to the version from disk, else we can // end up with blocks in fork choice that are missing from disk. // See https://github.com/sigp/lighthouse/issues/2028 - let (signed_block, blobs) = signed_block.deconstruct(); + let (signed_block, blobs) = signed_block.deconstruct(Some(block_root)); let block = signed_block.message(); let mut ops: Vec<_> = confirmed_state_roots .into_iter() diff --git a/beacon_node/beacon_chain/src/early_attester_cache.rs b/beacon_node/beacon_chain/src/early_attester_cache.rs index 9254a3eb3f0..d8382481f6f 100644 --- a/beacon_node/beacon_chain/src/early_attester_cache.rs +++ b/beacon_node/beacon_chain/src/early_attester_cache.rs @@ -69,7 +69,7 @@ impl EarlyAttesterCache { }, }; - let (block, blobs) = block.deconstruct(); + let (block, blobs) = block.deconstruct(Some(beacon_block_root)); let item = CacheItem { epoch, committee_lengths, @@ -77,7 +77,7 @@ impl EarlyAttesterCache { source, target, block, - blobs: blobs?, + blobs: blobs.map_err(|_|Error::MissingBlobs)?, proto_block, }; diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index 2c9955bdb8b..fead50f383d 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -93,11 +93,14 @@ impl BlockWrapper { self.block().parent_root() } - pub fn deconstruct(self) -> (Arc>, Result>>, BlobReconstructionError>) { + pub fn deconstruct(self, block_root: Option) -> (Arc>, Result>>, BlobReconstructionError>) { match self { - BlockWrapper::Block(block) => (block, block - .reconstruct_empty_blobs(block_root) - .map(|blob_opt| blob_opt.map(Arc::new))), + BlockWrapper::Block(block) => { + let blobs = block + .reconstruct_empty_blobs(block_root) + .map(|blob_opt| blob_opt.map(Arc::new)); + (block,blobs) + } , BlockWrapper::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, From 240854750c6622cec41db015c38a4fcce79803ea Mon Sep 17 00:00:00 2001 From: Divma <26765164+divagant-martian@users.noreply.github.com> Date: Fri, 23 Dec 2022 17:16:10 -0500 Subject: [PATCH 44/59] cleanup: remove unused imports, unusued fields (#3834) --- beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- beacon_node/beacon_chain/src/blob_cache.rs | 3 +-- beacon_node/beacon_chain/src/blob_verification.rs | 2 -- beacon_node/beacon_chain/src/block_verification.rs | 2 +- beacon_node/execution_layer/src/engines.rs | 2 +- beacon_node/http_api/src/publish_blocks.rs | 5 ++--- beacon_node/lighthouse_network/src/rpc/protocol.rs | 2 +- beacon_node/lighthouse_network/src/types/pubsub.rs | 12 ++++-------- .../src/beacon_processor/work_reprocessing_queue.rs | 3 +-- .../src/beacon_processor/worker/gossip_methods.rs | 6 ++---- .../src/beacon_processor/worker/rpc_methods.rs | 5 ++--- .../src/beacon_processor/worker/sync_methods.rs | 5 +---- beacon_node/network/src/sync/block_lookups/mod.rs | 5 +---- .../network/src/sync/block_lookups/parent_lookup.rs | 3 +-- .../src/sync/block_lookups/single_block_lookup.rs | 3 +-- beacon_node/network/src/sync/block_lookups/tests.rs | 4 ++-- beacon_node/network/src/sync/manager.rs | 4 ++-- beacon_node/network/src/sync/range_sync/chain.rs | 1 - beacon_node/network/src/sync/range_sync/range.rs | 5 ++--- beacon_node/store/src/lib.rs | 1 + consensus/state_processing/src/consensus_context.rs | 8 +------- .../state_processing/src/per_block_processing.rs | 2 -- consensus/types/src/blobs_sidecar.rs | 2 +- lcli/src/new_testnet.rs | 7 ++----- 24 files changed, 31 insertions(+), 63 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index ab008171536..d8c9c52c1c0 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -62,7 +62,7 @@ use crate::{metrics, BeaconChainError, BeaconForkChoiceStore, BeaconSnapshot, Ca use eth2::types::{EventKind, SseBlock, SyncDuty}; use execution_layer::{ BlockProposalContents, BuilderParams, ChainHealth, ExecutionLayer, FailedCondition, - PayloadAttributes, PayloadAttributesV2, PayloadStatus, + PayloadAttributes, PayloadStatus, }; pub use fork_choice::CountUnrealized; use fork_choice::{ diff --git a/beacon_node/beacon_chain/src/blob_cache.rs b/beacon_node/beacon_chain/src/blob_cache.rs index 7f057ad9ed1..d03e62ab646 100644 --- a/beacon_node/beacon_chain/src/blob_cache.rs +++ b/beacon_node/beacon_chain/src/blob_cache.rs @@ -1,7 +1,6 @@ use lru::LruCache; use parking_lot::Mutex; -use tree_hash::TreeHash; -use types::{BlobsSidecar, EthSpec, ExecutionPayload, Hash256}; +use types::{BlobsSidecar, EthSpec, Hash256}; pub const DEFAULT_BLOB_CACHE_SIZE: usize = 10; diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index 1b05c7d39f5..7b940f2912e 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -2,9 +2,7 @@ use slot_clock::SlotClock; use crate::beacon_chain::{BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY}; use crate::{kzg_utils, BeaconChainError}; -use bls::PublicKey; use state_processing::per_block_processing::eip4844::eip4844::verify_kzg_commitments_against_transactions; -use types::consts::eip4844::BLS_MODULUS; use types::{BeaconStateError, BlobsSidecar, Hash256, KzgCommitment, Slot, Transactions}; #[derive(Debug)] diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index b9e65bc0a23..9215af4baca 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -88,12 +88,12 @@ use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp}; use task_executor::JoinHandle; use tree_hash::TreeHash; use types::signed_block_and_blobs::BlockWrapper; +use types::ExecPayload; use types::{ BeaconBlockRef, BeaconState, BeaconStateError, BlindedPayload, ChainSpec, CloneConfig, Epoch, EthSpec, ExecutionBlockHash, Hash256, InconsistentFork, PublicKey, PublicKeyBytes, RelativeEpoch, SignedBeaconBlock, SignedBeaconBlockHeader, Slot, }; -use types::{BlobsSidecar, ExecPayload}; pub const POS_PANDA_BANNER: &str = r#" ,,, ,,, ,,, ,,, diff --git a/beacon_node/execution_layer/src/engines.rs b/beacon_node/execution_layer/src/engines.rs index 432cc85cd4e..e0b7c1dc3f9 100644 --- a/beacon_node/execution_layer/src/engines.rs +++ b/beacon_node/execution_layer/src/engines.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use task_executor::TaskExecutor; use tokio::sync::{watch, Mutex, RwLock}; use tokio_stream::wrappers::WatchStream; -use types::{Address, ExecutionBlockHash, ForkName, Hash256}; +use types::{ExecutionBlockHash, ForkName}; /// The number of payload IDs that will be stored for each `Engine`. /// diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index 085f5036f4f..4a6a584ca13 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -11,9 +11,8 @@ use tokio::sync::mpsc::UnboundedSender; use tree_hash::TreeHash; use types::signed_block_and_blobs::BlockWrapper; use types::{ - AbstractExecPayload, BlindedPayload, BlobsSidecar, EthSpec, ExecPayload, ExecutionBlockHash, - FullPayload, Hash256, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, - SignedBeaconBlockEip4844, + AbstractExecPayload, BlindedPayload, EthSpec, ExecPayload, ExecutionBlockHash, FullPayload, + Hash256, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, }; use warp::Rejection; diff --git a/beacon_node/lighthouse_network/src/rpc/protocol.rs b/beacon_node/lighthouse_network/src/rpc/protocol.rs index 8a3149fc517..1164688cda8 100644 --- a/beacon_node/lighthouse_network/src/rpc/protocol.rs +++ b/beacon_node/lighthouse_network/src/rpc/protocol.rs @@ -22,7 +22,7 @@ use tokio_util::{ }; use types::BlobsSidecar; use types::{ - BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, Blob, EmptyBlock, EthSpec, + BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, EmptyBlock, EthSpec, ForkContext, ForkName, Hash256, MainnetEthSpec, Signature, SignedBeaconBlock, }; diff --git a/beacon_node/lighthouse_network/src/types/pubsub.rs b/beacon_node/lighthouse_network/src/types/pubsub.rs index 7b9e6a7b47f..7951a072438 100644 --- a/beacon_node/lighthouse_network/src/types/pubsub.rs +++ b/beacon_node/lighthouse_network/src/types/pubsub.rs @@ -3,20 +3,16 @@ use crate::types::{GossipEncoding, GossipKind, GossipTopic}; use crate::TopicHash; use libp2p::gossipsub::{DataTransform, GossipsubMessage, RawGossipsubMessage}; -use serde_derive::{Deserialize, Serialize}; use snap::raw::{decompress_len, Decoder, Encoder}; use ssz::{Decode, Encode}; -use ssz_derive::{Decode, Encode}; use std::boxed::Box; use std::io::{Error, ErrorKind}; use std::sync::Arc; -use tree_hash_derive::TreeHash; use types::{ - Attestation, AttesterSlashing, BlobsSidecar, EthSpec, ForkContext, ForkName, - LightClientFinalityUpdate, LightClientOptimisticUpdate, ProposerSlashing, - SignedAggregateAndProof, SignedBeaconBlock, SignedBeaconBlockAltair, - SignedBeaconBlockAndBlobsSidecar, SignedBeaconBlockBase, SignedBeaconBlockCapella, - SignedBeaconBlockEip4844, SignedBeaconBlockMerge, SignedBlsToExecutionChange, + Attestation, AttesterSlashing, EthSpec, ForkContext, ForkName, LightClientFinalityUpdate, + LightClientOptimisticUpdate, ProposerSlashing, SignedAggregateAndProof, SignedBeaconBlock, + SignedBeaconBlockAltair, SignedBeaconBlockAndBlobsSidecar, SignedBeaconBlockBase, + SignedBeaconBlockCapella, SignedBeaconBlockMerge, SignedBlsToExecutionChange, SignedContributionAndProof, SignedVoluntaryExit, SubnetId, SyncCommitteeMessage, SyncSubnetId, }; diff --git a/beacon_node/network/src/beacon_processor/work_reprocessing_queue.rs b/beacon_node/network/src/beacon_processor/work_reprocessing_queue.rs index e0c93474512..6f433005558 100644 --- a/beacon_node/network/src/beacon_processor/work_reprocessing_queue.rs +++ b/beacon_node/network/src/beacon_processor/work_reprocessing_queue.rs @@ -23,7 +23,6 @@ use slog::{crit, debug, error, warn, Logger}; use slot_clock::SlotClock; use std::collections::{HashMap, HashSet}; use std::pin::Pin; -use std::sync::Arc; use std::task::Context; use std::time::Duration; use task_executor::TaskExecutor; @@ -31,7 +30,7 @@ use tokio::sync::mpsc::{self, Receiver, Sender}; use tokio::time::error::Error as TimeError; use tokio_util::time::delay_queue::{DelayQueue, Key as DelayKey}; use types::signed_block_and_blobs::BlockWrapper; -use types::{Attestation, EthSpec, Hash256, SignedAggregateAndProof, SignedBeaconBlock, SubnetId}; +use types::{Attestation, EthSpec, Hash256, SignedAggregateAndProof, SubnetId}; const TASK_NAME: &str = "beacon_processor_reprocess_queue"; const GOSSIP_BLOCKS: &str = "gossip_blocks"; diff --git a/beacon_node/network/src/beacon_processor/worker/gossip_methods.rs b/beacon_node/network/src/beacon_processor/worker/gossip_methods.rs index eac8175d511..2c7c94079e9 100644 --- a/beacon_node/network/src/beacon_processor/worker/gossip_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/gossip_methods.rs @@ -15,15 +15,13 @@ use lighthouse_network::{Client, MessageAcceptance, MessageId, PeerAction, PeerI use slog::{crit, debug, error, info, trace, warn}; use slot_clock::SlotClock; use ssz::Encode; -use std::sync::Arc; use std::time::{Duration, SystemTime, UNIX_EPOCH}; use store::hot_cold_store::HotColdDBError; use tokio::sync::mpsc; use types::signed_block_and_blobs::BlockWrapper; use types::{ - Attestation, AttesterSlashing, BlobsSidecar, EthSpec, Hash256, IndexedAttestation, - LightClientFinalityUpdate, LightClientOptimisticUpdate, ProposerSlashing, - SignedAggregateAndProof, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, + Attestation, AttesterSlashing, EthSpec, Hash256, IndexedAttestation, LightClientFinalityUpdate, + LightClientOptimisticUpdate, ProposerSlashing, SignedAggregateAndProof, SignedBlsToExecutionChange, SignedContributionAndProof, SignedVoluntaryExit, Slot, SubnetId, SyncCommitteeMessage, SyncSubnetId, }; diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 3494153a5b6..3ade1bb87b6 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -12,7 +12,6 @@ use lighthouse_network::rpc::*; use lighthouse_network::{PeerId, PeerRequestId, ReportSource, Response, SyncInfo}; use slog::{debug, error}; use slot_clock::SlotClock; -use ssz_types::VariableList; use std::sync::Arc; use task_executor::TaskExecutor; use types::light_client_bootstrap::LightClientBootstrap; @@ -581,7 +580,7 @@ impl Worker { /// Handle a `BlobsByRange` request from the peer. pub fn handle_blobs_by_range_request( self, - executor: TaskExecutor, + _executor: TaskExecutor, send_on_drop: SendOnDrop, peer_id: PeerId, request_id: PeerRequestId, @@ -656,7 +655,7 @@ impl Worker { let block_roots = block_roots.into_iter().flatten().collect::>(); let mut blobs_sent = 0; - let mut send_response = true; + let send_response = true; for root in block_roots { match self.chain.store.get_blobs(&root) { diff --git a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs index dafc00bddb9..717f2a09500 100644 --- a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs @@ -17,10 +17,7 @@ use slog::{debug, error, info, warn}; use std::sync::Arc; use tokio::sync::mpsc; use types::signed_block_and_blobs::BlockWrapper; -use types::{ - Epoch, Hash256, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, - SignedBeaconBlockAndBlobsSidecarDecode, -}; +use types::{Epoch, Hash256, SignedBeaconBlock}; /// Id associated to a batch processing request, either a sync batch or a parent lookup. #[derive(Clone, Debug, PartialEq)] diff --git a/beacon_node/network/src/sync/block_lookups/mod.rs b/beacon_node/network/src/sync/block_lookups/mod.rs index ca633ba7603..84b49e25f11 100644 --- a/beacon_node/network/src/sync/block_lookups/mod.rs +++ b/beacon_node/network/src/sync/block_lookups/mod.rs @@ -4,15 +4,12 @@ use std::time::Duration; use beacon_chain::{BeaconChainTypes, BlockError}; use fnv::FnvHashMap; -use futures::StreamExt; -use itertools::{Either, Itertools}; use lighthouse_network::rpc::{RPCError, RPCResponseErrorCode}; use lighthouse_network::{PeerAction, PeerId}; use lru_cache::LRUTimeCache; use slog::{debug, error, trace, warn, Logger}; use smallvec::SmallVec; -use std::sync::Arc; -use store::{Hash256, SignedBeaconBlock}; +use store::Hash256; use types::signed_block_and_blobs::BlockWrapper; use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent}; diff --git a/beacon_node/network/src/sync/block_lookups/parent_lookup.rs b/beacon_node/network/src/sync/block_lookups/parent_lookup.rs index fd17e18db58..2aabbb563d1 100644 --- a/beacon_node/network/src/sync/block_lookups/parent_lookup.rs +++ b/beacon_node/network/src/sync/block_lookups/parent_lookup.rs @@ -1,8 +1,7 @@ use super::RootBlockTuple; use beacon_chain::BeaconChainTypes; use lighthouse_network::PeerId; -use std::sync::Arc; -use store::{Hash256, SignedBeaconBlock}; +use store::Hash256; use strum::IntoStaticStr; use types::signed_block_and_blobs::BlockWrapper; diff --git a/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs b/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs index 0e84fb0bbc6..05df18a0dac 100644 --- a/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs +++ b/beacon_node/network/src/sync/block_lookups/single_block_lookup.rs @@ -4,8 +4,7 @@ use lighthouse_network::{rpc::BlocksByRootRequest, PeerId}; use rand::seq::IteratorRandom; use ssz_types::VariableList; use std::collections::HashSet; -use std::sync::Arc; -use store::{EthSpec, Hash256, SignedBeaconBlock}; +use store::{EthSpec, Hash256}; use strum::IntoStaticStr; use types::signed_block_and_blobs::BlockWrapper; diff --git a/beacon_node/network/src/sync/block_lookups/tests.rs b/beacon_node/network/src/sync/block_lookups/tests.rs index 21b6d6658d3..004d0479a41 100644 --- a/beacon_node/network/src/sync/block_lookups/tests.rs +++ b/beacon_node/network/src/sync/block_lookups/tests.rs @@ -10,11 +10,11 @@ use beacon_chain::builder::Witness; use beacon_chain::eth1_chain::CachingEth1Backend; use lighthouse_network::{NetworkGlobals, Request}; use slog::{Drain, Level}; -use slot_clock::{SlotClock, SystemTimeSlotClock}; +use slot_clock::SystemTimeSlotClock; use store::MemoryStore; use tokio::sync::mpsc; use types::test_utils::{SeedableRng, TestRandom, XorShiftRng}; -use types::{EthSpec, MainnetEthSpec, MinimalEthSpec as E, Slot}; +use types::MinimalEthSpec as E; type T = Witness, E, MemoryStore, MemoryStore>; diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 305f9f70691..8d08ed1b176 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -898,10 +898,10 @@ impl SyncManager { request_id: RequestId, peer_id: PeerId, maybe_sidecar: Option::EthSpec>>>, - seen_timestamp: Duration, + _seen_timestamp: Duration, ) { match request_id { - RequestId::SingleBlock { id } | RequestId::ParentLookup { id } => { + RequestId::SingleBlock { .. } | RequestId::ParentLookup { .. } => { unreachable!("There is no such thing as a singular 'by root' glob request that is not accompanied by the block") } RequestId::BackFillSync { .. } => { diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index 46b6d05d7d6..89e120050ed 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -1,5 +1,4 @@ use super::batch::{BatchInfo, BatchProcessingResult, BatchState}; -use super::BatchTy; use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent as BeaconWorkEvent}; use crate::sync::{ manager::Id, network_context::SyncNetworkContext, BatchOperationOutcome, BatchProcessResult, diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index a4869f75b73..1e3474fa5af 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -388,12 +388,11 @@ mod tests { use slog::{o, Drain}; use tokio::sync::mpsc; - use slot_clock::{SlotClock, SystemTimeSlotClock}; + use slot_clock::SystemTimeSlotClock; use std::collections::HashSet; use std::sync::Arc; - use std::time::Duration; use store::MemoryStore; - use types::{Hash256, MainnetEthSpec, MinimalEthSpec as E}; + use types::{Hash256, MinimalEthSpec as E}; #[derive(Debug)] struct FakeStorage { diff --git a/beacon_node/store/src/lib.rs b/beacon_node/store/src/lib.rs index d9041dd6361..e940c0f25ec 100644 --- a/beacon_node/store/src/lib.rs +++ b/beacon_node/store/src/lib.rs @@ -7,6 +7,7 @@ //! //! Provides a simple API for storing/retrieving all types that sometimes needs type-hints. See //! tests for implementation examples. +#![allow(dead_code)] #[macro_use] extern crate lazy_static; diff --git a/consensus/state_processing/src/consensus_context.rs b/consensus/state_processing/src/consensus_context.rs index f5585426ce9..23dd989f98b 100644 --- a/consensus/state_processing/src/consensus_context.rs +++ b/consensus/state_processing/src/consensus_context.rs @@ -1,13 +1,10 @@ use crate::common::get_indexed_attestation; use crate::per_block_processing::errors::{AttestationInvalid, BlockOperationError}; use std::collections::{hash_map::Entry, HashMap}; -use std::marker::PhantomData; -use std::sync::Arc; use tree_hash::TreeHash; use types::{ AbstractExecPayload, Attestation, AttestationData, BeaconState, BeaconStateError, BitList, - BlobsSidecar, ChainSpec, Epoch, EthSpec, ExecPayload, Hash256, IndexedAttestation, - SignedBeaconBlock, Slot, + ChainSpec, Epoch, EthSpec, Hash256, IndexedAttestation, SignedBeaconBlock, Slot, }; #[derive(Debug)] @@ -21,8 +18,6 @@ pub struct ConsensusContext { /// Cache of indexed attestations constructed during block processing. indexed_attestations: HashMap<(AttestationData, BitList), IndexedAttestation>, - /// Should only be populated if the sidecar has not been validated. - blobs_sidecar: Option>>, /// Whether `validate_blobs_sidecar` has successfully passed. blobs_sidecar_validated: bool, /// Whether `verify_kzg_commitments_against_transactions` has successfully passed. @@ -49,7 +44,6 @@ impl ConsensusContext { proposer_index: None, current_block_root: None, indexed_attestations: HashMap::new(), - blobs_sidecar: None, blobs_sidecar_validated: false, blobs_verified_vs_txs: false, } diff --git a/consensus/state_processing/src/per_block_processing.rs b/consensus/state_processing/src/per_block_processing.rs index 4fcf07c8a84..4b5e77e0a46 100644 --- a/consensus/state_processing/src/per_block_processing.rs +++ b/consensus/state_processing/src/per_block_processing.rs @@ -42,8 +42,6 @@ mod verify_deposit; mod verify_exit; mod verify_proposer_slashing; -use crate::common::decrease_balance; - #[cfg(feature = "arbitrary-fuzz")] use arbitrary::Arbitrary; diff --git a/consensus/types/src/blobs_sidecar.rs b/consensus/types/src/blobs_sidecar.rs index f1e2a4bb16b..1a31786b6f7 100644 --- a/consensus/types/src/blobs_sidecar.rs +++ b/consensus/types/src/blobs_sidecar.rs @@ -1,5 +1,5 @@ use crate::test_utils::TestRandom; -use crate::{Blob, EthSpec, Hash256, SignedBeaconBlock, SignedRoot, Slot}; +use crate::{Blob, EthSpec, Hash256, SignedRoot, Slot}; use kzg::KzgProof; use serde_derive::{Deserialize, Serialize}; use ssz::Encode; diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index d6e093c1733..d8973980feb 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -2,24 +2,21 @@ use clap::ArgMatches; use clap_utils::{parse_optional, parse_required, parse_ssz_optional}; use eth2_hashing::hash; use eth2_network_config::Eth2NetworkConfig; -use genesis::interop_genesis_state; use ssz::Decode; use ssz::Encode; use state_processing::process_activations; -use state_processing::upgrade::{ - upgrade_to_altair, upgrade_to_bellatrix, upgrade_to_capella, upgrade_to_eip4844, -}; +use state_processing::upgrade::{upgrade_to_altair, upgrade_to_bellatrix}; use std::fs::File; use std::io::Read; use std::path::PathBuf; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; +use types::ExecutionBlockHash; use types::{ test_utils::generate_deterministic_keypairs, Address, BeaconState, ChainSpec, Config, Eth1Data, EthSpec, ExecutionPayloadHeader, ExecutionPayloadHeaderMerge, Hash256, Keypair, PublicKey, Validator, }; -use types::{BeaconStateMerge, ExecutionBlockHash}; pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Result<(), String> { let deposit_contract_address: Address = parse_required(matches, "deposit-contract-address")?; From aeb243fe61492fc5edb0fd81bbbb42f0c592744f Mon Sep 17 00:00:00 2001 From: Diva M Date: Fri, 23 Dec 2022 17:44:50 -0500 Subject: [PATCH 45/59] fmt --- .../beacon_chain/src/early_attester_cache.rs | 2 +- consensus/types/src/blobs_sidecar.rs | 4 ++-- consensus/types/src/signed_block_and_blobs.rs | 14 ++++++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/beacon_node/beacon_chain/src/early_attester_cache.rs b/beacon_node/beacon_chain/src/early_attester_cache.rs index d8382481f6f..1216d5d4d84 100644 --- a/beacon_node/beacon_chain/src/early_attester_cache.rs +++ b/beacon_node/beacon_chain/src/early_attester_cache.rs @@ -77,7 +77,7 @@ impl EarlyAttesterCache { source, target, block, - blobs: blobs.map_err(|_|Error::MissingBlobs)?, + blobs: blobs.map_err(|_| Error::MissingBlobs)?, proto_block, }; diff --git a/consensus/types/src/blobs_sidecar.rs b/consensus/types/src/blobs_sidecar.rs index d51d35d1ccc..f43a2e65085 100644 --- a/consensus/types/src/blobs_sidecar.rs +++ b/consensus/types/src/blobs_sidecar.rs @@ -1,6 +1,6 @@ -use derivative::Derivative; use crate::test_utils::TestRandom; use crate::{Blob, EthSpec, Hash256, SignedRoot, Slot}; +use derivative::Derivative; use kzg::KzgProof; use serde_derive::{Deserialize, Serialize}; use ssz::Encode; @@ -11,7 +11,7 @@ use tree_hash_derive::TreeHash; #[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] #[derive( - Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, Default, TestRandom, Derivative + Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, Default, TestRandom, Derivative, )] #[serde(bound = "T: EthSpec")] #[derivative(PartialEq, Hash(bound = "T: EthSpec"))] diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index fead50f383d..f21545f2783 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -1,11 +1,11 @@ use crate::signed_beacon_block::BlobReconstructionError; use crate::{BlobsSidecar, EthSpec, Hash256, SignedBeaconBlock, SignedBeaconBlockEip4844, Slot}; +use derivative::Derivative; use serde_derive::{Deserialize, Serialize}; use ssz::{Decode, DecodeError}; use ssz_derive::{Decode, Encode}; use std::sync::Arc; use tree_hash_derive::TreeHash; -use derivative::Derivative; #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, PartialEq)] #[serde(bound = "T: EthSpec")] @@ -93,14 +93,20 @@ impl BlockWrapper { self.block().parent_root() } - pub fn deconstruct(self, block_root: Option) -> (Arc>, Result>>, BlobReconstructionError>) { + pub fn deconstruct( + self, + block_root: Option, + ) -> ( + Arc>, + Result>>, BlobReconstructionError>, + ) { match self { BlockWrapper::Block(block) => { let blobs = block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)); - (block,blobs) - } , + (block, blobs) + } BlockWrapper::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, From 96da8b938337256496d20f542fd98e7ee644cb7e Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Tue, 27 Dec 2022 15:55:43 -0600 Subject: [PATCH 46/59] Feature Guard V2 Engine API Methods --- beacon_node/execution_layer/src/engine_api/http.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/beacon_node/execution_layer/src/engine_api/http.rs b/beacon_node/execution_layer/src/engine_api/http.rs index 29f66393e5c..bf1da078e74 100644 --- a/beacon_node/execution_layer/src/engine_api/http.rs +++ b/beacon_node/execution_layer/src/engine_api/http.rs @@ -852,11 +852,11 @@ impl HttpJsonRpc { pub async fn supported_apis_v1(&self) -> Result { Ok(SupportedApis { new_payload_v1: true, - new_payload_v2: cfg!(not(test)), + new_payload_v2: cfg!(feature = "withdrawals-processing"), forkchoice_updated_v1: true, - forkchoice_updated_v2: cfg!(not(test)), + forkchoice_updated_v2: cfg!(feature = "withdrawals-processing"), get_payload_v1: true, - get_payload_v2: cfg!(not(test)), + get_payload_v2: cfg!(feature = "withdrawals-processing"), exchange_transition_configuration_v1: true, }) } From c922566fbc42d1795cd7e99f348931faeb641bc5 Mon Sep 17 00:00:00 2001 From: Mark Mackey Date: Tue, 27 Dec 2022 15:59:34 -0600 Subject: [PATCH 47/59] Fixed Some Tests --- .../http_api/tests/interactive_tests.rs | 20 +++++++++++-------- beacon_node/http_api/tests/tests.rs | 4 ++-- validator_client/src/http_api/tests.rs | 4 ++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index 17a3624afed..04d527d531c 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -5,7 +5,7 @@ use beacon_chain::{ test_utils::{AttestationStrategy, BlockStrategy}, }; use eth2::types::DepositContractData; -use execution_layer::{ForkChoiceState, PayloadAttributes}; +use execution_layer::{ForkchoiceState, PayloadAttributes}; use parking_lot::Mutex; use slot_clock::SlotClock; use state_processing::state_advance::complete_state_advance; @@ -55,7 +55,7 @@ struct ForkChoiceUpdates { #[derive(Debug, Clone)] struct ForkChoiceUpdateMetadata { received_at: Duration, - state: ForkChoiceState, + state: ForkchoiceState, payload_attributes: Option, } @@ -86,7 +86,7 @@ impl ForkChoiceUpdates { .payload_attributes .as_ref() .map_or(false, |payload_attributes| { - payload_attributes.timestamp == proposal_timestamp + payload_attributes.timestamp() == proposal_timestamp }) }) .cloned() @@ -342,7 +342,7 @@ pub async fn proposer_boost_re_org_test( .lock() .set_forkchoice_updated_hook(Box::new(move |state, payload_attributes| { let received_at = chain_inner.slot_clock.now_duration().unwrap(); - let state = ForkChoiceState::from(state); + let state = ForkchoiceState::from(state); let payload_attributes = payload_attributes.map(Into::into); let update = ForkChoiceUpdateMetadata { received_at, @@ -521,16 +521,20 @@ pub async fn proposer_boost_re_org_test( if !misprediction { assert_eq!( - lookahead, payload_lookahead, + lookahead, + payload_lookahead, "lookahead={lookahead:?}, timestamp={}, prev_randao={:?}", - payload_attribs.timestamp, payload_attribs.prev_randao, + payload_attribs.timestamp(), + payload_attribs.prev_randao(), ); } else { // On a misprediction we issue the first fcU 500ms before creating a block! assert_eq!( - lookahead, fork_choice_lookahead, + lookahead, + fork_choice_lookahead, "timestamp={}, prev_randao={:?}", - payload_attribs.timestamp, payload_attribs.prev_randao, + payload_attribs.timestamp(), + payload_attribs.prev_randao(), ); } } diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 8644dcbf1ad..86733cf63ad 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -1372,9 +1372,9 @@ impl ApiTester { pub async fn test_get_config_spec(self) -> Self { let result = self .client - .get_config_spec::() + .get_config_spec::() .await - .map(|res| ConfigAndPreset::Bellatrix(res.data)) + .map(|res| ConfigAndPreset::Capella(res.data)) .unwrap(); let expected = ConfigAndPreset::from_chain_spec::(&self.chain.spec, None); diff --git a/validator_client/src/http_api/tests.rs b/validator_client/src/http_api/tests.rs index 5aa24a2b022..d453d7038ad 100644 --- a/validator_client/src/http_api/tests.rs +++ b/validator_client/src/http_api/tests.rs @@ -212,9 +212,9 @@ impl ApiTester { pub async fn test_get_lighthouse_spec(self) -> Self { let result = self .client - .get_lighthouse_spec::() + .get_lighthouse_spec::() .await - .map(|res| ConfigAndPreset::Bellatrix(res.data)) + .map(|res| ConfigAndPreset::Capella(res.data)) .unwrap(); let expected = ConfigAndPreset::from_chain_spec::(&E::default_spec(), None); From 502b5e5bf0bb2030d304ee54d677d63f1ae4d601 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 28 Dec 2022 09:32:29 -0500 Subject: [PATCH 48/59] unused error lint --- beacon_node/network/src/sync/range_sync/batch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/network/src/sync/range_sync/batch.rs b/beacon_node/network/src/sync/range_sync/batch.rs index 93d5e3e19d1..80f34f8b44f 100644 --- a/beacon_node/network/src/sync/range_sync/batch.rs +++ b/beacon_node/network/src/sync/range_sync/batch.rs @@ -559,7 +559,7 @@ impl slog::KV for BatchInfo { serializer.emit_usize("processed", self.failed_processing_attempts.len())?; serializer.emit_u8("processed_no_penalty", self.non_faulty_processing_attempts)?; serializer.emit_arguments("state", &format_args!("{:?}", self.state))?; - serializer.emit_arguments("batch_ty", &format_args!("{}", self.batch_type)); + serializer.emit_arguments("batch_ty", &format_args!("{}", self.batch_type))?; slog::Result::Ok(()) } } From 5b3b34a9d75aa837cbaaf41104ed35641dfbd504 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 28 Dec 2022 10:28:45 -0500 Subject: [PATCH 49/59] renames, remove , wrap BlockWrapper enum to make descontruction private --- .../beacon_chain/src/block_verification.rs | 2 +- beacon_node/http_api/src/publish_blocks.rs | 41 +++--- .../src/rpc/codec/ssz_snappy.rs | 13 +- .../lighthouse_network/src/rpc/methods.rs | 8 +- .../src/service/api_types.rs | 4 +- .../lighthouse_network/src/service/mod.rs | 2 +- .../network/src/beacon_processor/mod.rs | 4 +- .../beacon_processor/worker/rpc_methods.rs | 4 +- .../beacon_processor/worker/sync_methods.rs | 9 +- beacon_node/network/src/router/processor.rs | 30 ++--- .../network/src/sync/backfill_sync/mod.rs | 2 +- .../src/sync/block_sidecar_coupling.rs | 20 +-- beacon_node/network/src/sync/manager.rs | 118 ++++++++---------- .../network/src/sync/network_context.rs | 97 +++++++------- .../network/src/sync/range_sync/batch.rs | 62 ++------- .../network/src/sync/range_sync/chain.rs | 2 +- .../network/src/sync/range_sync/mod.rs | 4 +- .../network/src/sync/range_sync/range.rs | 6 +- consensus/types/src/signed_block_and_blobs.rs | 71 +++++++---- 19 files changed, 231 insertions(+), 268 deletions(-) diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index c8d3aed7961..2b759e4ad96 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -1141,7 +1141,7 @@ impl IntoExecutionPendingBlock for Arc( // Send the block, regardless of whether or not it is valid. The API // specification is very clear that this is the desired behaviour. - let wrapped_block = if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { - if let Some(sidecar) = chain.blob_cache.pop(&block_root) { - let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { - beacon_block: block, - blobs_sidecar: Arc::new(sidecar), - }; - crate::publish_pubsub_message( - network_tx, - PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), - )?; - BlockWrapper::BlockAndBlob(block_and_blobs) + let wrapped_block: BlockWrapper = + if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { + if let Some(sidecar) = chain.blob_cache.pop(&block_root) { + let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { + beacon_block: block, + blobs_sidecar: Arc::new(sidecar), + }; + crate::publish_pubsub_message( + network_tx, + PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), + )?; + block_and_blobs.into() + } else { + //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required + return Err(warp_utils::reject::broadcast_without_import(format!( + "no blob cached for block" + ))); + } } else { - //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required - return Err(warp_utils::reject::broadcast_without_import(format!( - "no blob cached for block" - ))); - } - } else { - crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; - BlockWrapper::Block(block) - }; + crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; + block.into() + }; // Determine the delay after the start of the slot, register it with metrics. let block = wrapped_block.block(); diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index df5350d9494..eb5cc7f27fa 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -73,7 +73,7 @@ impl Encoder> for SSZSnappyInboundCodec< RPCResponse::BlocksByRange(res) => res.as_ssz_bytes(), RPCResponse::BlocksByRoot(res) => res.as_ssz_bytes(), RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(), - RPCResponse::BlobsByRoot(res) => res.as_ssz_bytes(), + RPCResponse::BlockAndBlobsByRoot(res) => res.as_ssz_bytes(), RPCResponse::LightClientBootstrap(res) => res.as_ssz_bytes(), RPCResponse::Pong(res) => res.data.as_ssz_bytes(), RPCResponse::MetaData(res) => @@ -439,7 +439,8 @@ fn context_bytes( SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()), }; } - if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant { + if let RPCResponse::BlobsByRange(_) | RPCResponse::BlockAndBlobsByRoot(_) = rpc_variant + { return fork_context.to_context_bytes(ForkName::Eip4844); } } @@ -585,7 +586,7 @@ fn handle_v1_response( )))), _ => Err(RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - "Invalid forkname for blobsbyrange".to_string(), + "Invalid fork name for blobs by range".to_string(), )), } } @@ -597,12 +598,12 @@ fn handle_v1_response( ) })?; match fork_name { - ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRoot(Arc::new( + ForkName::Eip4844 => Ok(Some(RPCResponse::BlockAndBlobsByRoot( SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, - )))), + ))), _ => Err(RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - "Invalid forkname for blobsbyroot".to_string(), + "Invalid fork name for block and blobs by root".to_string(), )), } } diff --git a/beacon_node/lighthouse_network/src/rpc/methods.rs b/beacon_node/lighthouse_network/src/rpc/methods.rs index 53e6b675990..02e24d8e1d1 100644 --- a/beacon_node/lighthouse_network/src/rpc/methods.rs +++ b/beacon_node/lighthouse_network/src/rpc/methods.rs @@ -281,7 +281,7 @@ pub enum RPCResponse { LightClientBootstrap(LightClientBootstrap), /// A response to a get BLOBS_BY_ROOT request. - BlobsByRoot(Arc>), + BlockAndBlobsByRoot(SignedBeaconBlockAndBlobsSidecar), /// A PONG response to a PING request. Pong(Ping), @@ -372,7 +372,7 @@ impl RPCCodedResponse { RPCResponse::BlocksByRange(_) => true, RPCResponse::BlocksByRoot(_) => true, RPCResponse::BlobsByRange(_) => true, - RPCResponse::BlobsByRoot(_) => true, + RPCResponse::BlockAndBlobsByRoot(_) => true, RPCResponse::Pong(_) => false, RPCResponse::MetaData(_) => false, RPCResponse::LightClientBootstrap(_) => false, @@ -409,7 +409,7 @@ impl RPCResponse { RPCResponse::BlocksByRange(_) => Protocol::BlocksByRange, RPCResponse::BlocksByRoot(_) => Protocol::BlocksByRoot, RPCResponse::BlobsByRange(_) => Protocol::BlobsByRange, - RPCResponse::BlobsByRoot(_) => Protocol::BlobsByRoot, + RPCResponse::BlockAndBlobsByRoot(_) => Protocol::BlobsByRoot, RPCResponse::Pong(_) => Protocol::Ping, RPCResponse::MetaData(_) => Protocol::MetaData, RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap, @@ -449,7 +449,7 @@ impl std::fmt::Display for RPCResponse { RPCResponse::BlobsByRange(blob) => { write!(f, "BlobsByRange: Blob slot: {}", blob.beacon_block_slot) } - RPCResponse::BlobsByRoot(blob) => { + RPCResponse::BlockAndBlobsByRoot(blob) => { write!( f, "BlobsByRoot: Blob slot: {}", diff --git a/beacon_node/lighthouse_network/src/service/api_types.rs b/beacon_node/lighthouse_network/src/service/api_types.rs index b6a03302008..c9c239d8cf4 100644 --- a/beacon_node/lighthouse_network/src/service/api_types.rs +++ b/beacon_node/lighthouse_network/src/service/api_types.rs @@ -83,7 +83,7 @@ pub enum Response { /// A response to a LightClientUpdate request. LightClientBootstrap(LightClientBootstrap), /// A response to a get BLOBS_BY_ROOT request. - BlobsByRoot(Option>>), + BlobsByRoot(Option>), } impl std::convert::From> for RPCCodedResponse { @@ -98,7 +98,7 @@ impl std::convert::From> for RPCCodedResponse RPCCodedResponse::StreamTermination(ResponseTermination::BlocksByRange), }, Response::BlobsByRoot(r) => match r { - Some(b) => RPCCodedResponse::Success(RPCResponse::BlobsByRoot(b)), + Some(b) => RPCCodedResponse::Success(RPCResponse::BlockAndBlobsByRoot(b)), None => RPCCodedResponse::StreamTermination(ResponseTermination::BlobsByRoot), }, Response::BlobsByRange(r) => match r { diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index 9adf7699bc2..d59bc4bfd6c 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -1315,7 +1315,7 @@ impl Network { RPCResponse::BlocksByRoot(resp) => { self.build_response(id, peer_id, Response::BlocksByRoot(Some(resp))) } - RPCResponse::BlobsByRoot(resp) => { + RPCResponse::BlockAndBlobsByRoot(resp) => { self.build_response(id, peer_id, Response::BlobsByRoot(Some(resp))) } // Should never be reached diff --git a/beacon_node/network/src/beacon_processor/mod.rs b/beacon_node/network/src/beacon_processor/mod.rs index 9de006c84f5..37d6edef82f 100644 --- a/beacon_node/network/src/beacon_processor/mod.rs +++ b/beacon_node/network/src/beacon_processor/mod.rs @@ -1699,7 +1699,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - BlockWrapper::Block(block), + block.into(), work_reprocessing_tx, duplicate_cache, seen_timestamp, @@ -1721,7 +1721,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - BlockWrapper::BlockAndBlob(block_sidecar_pair), + block_sidecar_pair.into(), work_reprocessing_tx, duplicate_cache, seen_timestamp, diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 3ade1bb87b6..69bd7da11c6 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -230,10 +230,10 @@ impl Worker { Ok((Some(block), Some(blobs))) => { self.send_response( peer_id, - Response::BlobsByRoot(Some(Arc::new(SignedBeaconBlockAndBlobsSidecar { + Response::BlobsByRoot(Some(SignedBeaconBlockAndBlobsSidecar { beacon_block: block, blobs_sidecar: blobs, - }))), + })), request_id, ); send_block_count += 1; diff --git a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs index 5af62c37de0..b3465c56dc5 100644 --- a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs @@ -188,14 +188,7 @@ impl Worker { let end_slot = downloaded_blocks.last().map(|b| b.slot().as_u64()); let sent_blocks = downloaded_blocks.len(); - let unwrapped = downloaded_blocks - .into_iter() - .map(|block| match block { - BlockWrapper::Block(block) => block, - //FIXME(sean) handle blobs in backfill - BlockWrapper::BlockAndBlob(_) => todo!(), - }) - .collect(); + let unwrapped = downloaded_blocks.into_iter().map(|_| todo!()).collect(); match self.process_backfill_blocks(unwrapped) { (_, Ok(_)) => { diff --git a/beacon_node/network/src/router/processor.rs b/beacon_node/network/src/router/processor.rs index 5ee0e367b68..d0879babacb 100644 --- a/beacon_node/network/src/router/processor.rs +++ b/beacon_node/network/src/router/processor.rs @@ -223,10 +223,10 @@ impl Processor { SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. } => { unreachable!("Block lookups do not request BBRange requests") } - id @ (SyncId::BackFillSync { .. } - | SyncId::RangeSync { .. } - | SyncId::BackFillSidecarPair { .. } - | SyncId::RangeSidecarPair { .. }) => id, + id @ (SyncId::BackFillBlocks { .. } + | SyncId::RangeBlocks { .. } + | SyncId::BackFillBlobs { .. } + | SyncId::RangeBlobs { .. }) => id, }, RequestId::Router => unreachable!("All BBRange requests belong to sync"), }; @@ -258,7 +258,7 @@ impl Processor { ); if let RequestId::Sync(id) = request_id { - self.send_to_sync(SyncMessage::RpcGlob { + self.send_to_sync(SyncMessage::RpcBlobs { peer_id, request_id: id, blob_sidecar, @@ -282,10 +282,10 @@ impl Processor { let request_id = match request_id { RequestId::Sync(sync_id) => match sync_id { id @ (SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. }) => id, - SyncId::BackFillSync { .. } - | SyncId::RangeSync { .. } - | SyncId::RangeSidecarPair { .. } - | SyncId::BackFillSidecarPair { .. } => { + SyncId::BackFillBlocks { .. } + | SyncId::RangeBlocks { .. } + | SyncId::RangeBlobs { .. } + | SyncId::BackFillBlobs { .. } => { unreachable!("Batch syncing do not request BBRoot requests") } }, @@ -310,15 +310,15 @@ impl Processor { &mut self, peer_id: PeerId, request_id: RequestId, - block_and_blobs: Option>>, + block_and_blobs: Option>, ) { let request_id = match request_id { RequestId::Sync(sync_id) => match sync_id { id @ (SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. }) => id, - SyncId::BackFillSync { .. } - | SyncId::RangeSync { .. } - | SyncId::RangeSidecarPair { .. } - | SyncId::BackFillSidecarPair { .. } => { + SyncId::BackFillBlocks { .. } + | SyncId::RangeBlocks { .. } + | SyncId::RangeBlobs { .. } + | SyncId::BackFillBlobs { .. } => { unreachable!("Batch syncing does not request BBRoot requests") } }, @@ -330,7 +330,7 @@ impl Processor { "Received BlockAndBlobssByRoot Response"; "peer" => %peer_id, ); - self.send_to_sync(SyncMessage::RpcBlockAndGlob { + self.send_to_sync(SyncMessage::RpcBlockAndBlobs { peer_id, request_id, block_and_blobs, diff --git a/beacon_node/network/src/sync/backfill_sync/mod.rs b/beacon_node/network/src/sync/backfill_sync/mod.rs index 56ed551530c..ad1bfb1d42d 100644 --- a/beacon_node/network/src/sync/backfill_sync/mod.rs +++ b/beacon_node/network/src/sync/backfill_sync/mod.rs @@ -536,7 +536,7 @@ impl BackFillSync { let process_id = ChainSegmentProcessId::BackSyncBatchId(batch_id); self.current_processing_batch = Some(batch_id); - let work_event = BeaconWorkEvent::chain_segment(process_id, blocks.into_wrapped_blocks()); + let work_event = BeaconWorkEvent::chain_segment(process_id, blocks); if let Err(e) = network.processor_channel().try_send(work_event) { crit!(self.log, "Failed to send backfill segment to processor."; "msg" => "process_batch", "error" => %e, "batch" => self.processing_target); diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index f82417db3a1..46ac5bd0fbd 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -1,12 +1,9 @@ use std::{collections::VecDeque, sync::Arc}; -use types::{ - signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock, - SignedBeaconBlockAndBlobsSidecar, -}; +use types::{signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock}; #[derive(Debug, Default)] -pub struct BlockBlobRequestInfo { +pub struct BlocksAndBlobsRequestInfo { /// Blocks we have received awaiting for their corresponding sidecar. accumulated_blocks: VecDeque>>, /// Sidecars we have received awaiting for their corresponding block. @@ -17,7 +14,7 @@ pub struct BlockBlobRequestInfo { is_sidecars_stream_terminated: bool, } -impl BlockBlobRequestInfo { +impl BlocksAndBlobsRequestInfo { pub fn add_block_response(&mut self, maybe_block: Option>>) { match maybe_block { Some(block) => self.accumulated_blocks.push_back(block), @@ -33,7 +30,7 @@ impl BlockBlobRequestInfo { } pub fn into_responses(self) -> Result>, &'static str> { - let BlockBlobRequestInfo { + let BlocksAndBlobsRequestInfo { accumulated_blocks, mut accumulated_sidecars, .. @@ -51,14 +48,9 @@ impl BlockBlobRequestInfo { { let blobs_sidecar = accumulated_sidecars.pop_front().ok_or("missing sidecar")?; - Ok(BlockWrapper::BlockAndBlob( - SignedBeaconBlockAndBlobsSidecar { - beacon_block, - blobs_sidecar, - }, - )) + Ok(BlockWrapper::new_with_blobs(beacon_block, blobs_sidecar)) } else { - Ok(BlockWrapper::Block(beacon_block)) + Ok(beacon_block.into()) } }) .collect::, _>>(); diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 29838bde713..5da203e0e77 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -35,13 +35,13 @@ use super::backfill_sync::{BackFillSync, ProcessResult, SyncStart}; use super::block_lookups::BlockLookups; -use super::network_context::{BlockOrBlob, SyncNetworkContext}; +use super::network_context::{BlockOrBlobs, SyncNetworkContext}; use super::peer_sync_info::{remote_sync_type, PeerSyncType}; use super::range_sync::{RangeSync, RangeSyncType, EPOCHS_PER_BATCH}; use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent as BeaconWorkEvent}; use crate::service::NetworkMessage; use crate::status::ToStatusMessage; -use crate::sync::range_sync::ExpectedBatchTy; +use crate::sync::range_sync::ByRangeRequestType; use beacon_chain::{BeaconChain, BeaconChainTypes, BlockError, EngineState}; use futures::StreamExt; use lighthouse_network::rpc::methods::MAX_REQUEST_BLOCKS; @@ -79,13 +79,13 @@ pub enum RequestId { /// Request searching for a block's parent. The id is the chain ParentLookup { id: Id }, /// Request was from the backfill sync algorithm. - BackFillSync { id: Id }, - /// Backfill request for blocks and sidecars. - BackFillSidecarPair { id: Id }, + BackFillBlocks { id: Id }, + /// Backfill request for blob sidecars. + BackFillBlobs { id: Id }, /// The request was from a chain in the range sync algorithm. - RangeSync { id: Id }, - /// The request was from a chain in range, asking for ranges of blocks and sidecars. - RangeSidecarPair { id: Id }, + RangeBlocks { id: Id }, + /// The request was from a chain in range, asking for ranges blob sidecars. + RangeBlobs { id: Id }, } #[derive(Debug)] @@ -103,7 +103,7 @@ pub enum SyncMessage { }, /// A blob has been received from the RPC. - RpcGlob { + RpcBlobs { request_id: RequestId, peer_id: PeerId, blob_sidecar: Option>>, @@ -111,10 +111,10 @@ pub enum SyncMessage { }, /// A block and blobs have been received from the RPC. - RpcBlockAndGlob { + RpcBlockAndBlobs { request_id: RequestId, peer_id: PeerId, - block_and_blobs: Option>>, + block_and_blobs: Option>, seen_timestamp: Duration, }, @@ -295,10 +295,10 @@ impl SyncManager { self.block_lookups .parent_lookup_failed(id, peer_id, &mut self.network, error); } - RequestId::BackFillSync { id } => { + RequestId::BackFillBlocks { id } => { if let Some(batch_id) = self .network - .backfill_request_failed(id, ExpectedBatchTy::OnlyBlock) + .backfill_request_failed(id, ByRangeRequestType::Blocks) { match self .backfill_sync @@ -310,10 +310,10 @@ impl SyncManager { } } - RequestId::BackFillSidecarPair { id } => { + RequestId::BackFillBlobs { id } => { if let Some(batch_id) = self .network - .backfill_request_failed(id, ExpectedBatchTy::OnlyBlockBlobs) + .backfill_request_failed(id, ByRangeRequestType::BlocksAndBlobs) { match self .backfill_sync @@ -324,10 +324,10 @@ impl SyncManager { } } } - RequestId::RangeSync { id } => { + RequestId::RangeBlocks { id } => { if let Some((chain_id, batch_id)) = self .network - .range_sync_request_failed(id, ExpectedBatchTy::OnlyBlock) + .range_sync_request_failed(id, ByRangeRequestType::Blocks) { self.range_sync.inject_error( &mut self.network, @@ -339,10 +339,10 @@ impl SyncManager { self.update_sync_state() } } - RequestId::RangeSidecarPair { id } => { + RequestId::RangeBlobs { id } => { if let Some((chain_id, batch_id)) = self .network - .range_sync_request_failed(id, ExpectedBatchTy::OnlyBlockBlobs) + .range_sync_request_failed(id, ByRangeRequestType::BlocksAndBlobs) { self.range_sync.inject_error( &mut self.network, @@ -648,18 +648,18 @@ impl SyncManager { .block_lookups .parent_chain_processed(chain_hash, result, &mut self.network), }, - SyncMessage::RpcGlob { + SyncMessage::RpcBlobs { request_id, peer_id, blob_sidecar, seen_timestamp, - } => self.rpc_sidecar_received(request_id, peer_id, blob_sidecar, seen_timestamp), - SyncMessage::RpcBlockAndGlob { + } => self.rpc_blobs_received(request_id, peer_id, blob_sidecar, seen_timestamp), + SyncMessage::RpcBlockAndBlobs { request_id, peer_id, block_and_blobs, seen_timestamp, - } => self.rpc_block_sidecar_pair_received( + } => self.rpc_block_block_and_blobs_received( request_id, peer_id, block_and_blobs, @@ -734,18 +734,18 @@ impl SyncManager { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), seen_timestamp, &mut self.network, ), - RequestId::BackFillSync { id } => { + RequestId::BackFillBlocks { id } => { let is_stream_terminator = beacon_block.is_none(); if let Some(batch_id) = self .network @@ -756,7 +756,7 @@ impl SyncManager { batch_id, &peer_id, id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), ) { Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), Ok(ProcessResult::Successful) => {} @@ -768,7 +768,7 @@ impl SyncManager { } } } - RequestId::RangeSync { id } => { + RequestId::RangeBlocks { id } => { let is_stream_terminator = beacon_block.is_none(); if let Some((chain_id, batch_id)) = self .network @@ -780,28 +780,28 @@ impl SyncManager { chain_id, batch_id, id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), ); self.update_sync_state(); } } - RequestId::BackFillSidecarPair { id } => { - self.block_blob_backfill_response(id, peer_id, beacon_block.into()) + RequestId::BackFillBlobs { id } => { + self.blobs_backfill_response(id, peer_id, beacon_block.into()) } - RequestId::RangeSidecarPair { id } => { - self.block_blob_range_response(id, peer_id, beacon_block.into()) + RequestId::RangeBlobs { id } => { + self.blobs_range_response(id, peer_id, beacon_block.into()) } } } /// Handles receiving a response for a range sync request that should have both blocks and /// blobs. - fn block_blob_range_response( + fn blobs_range_response( &mut self, id: Id, peer_id: PeerId, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) { if let Some((chain_id, batch_id, block_responses)) = self .network @@ -834,7 +834,7 @@ impl SyncManager { "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy - let id = RequestId::RangeSidecarPair { id }; + let id = RequestId::RangeBlobs { id }; self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } @@ -843,11 +843,11 @@ impl SyncManager { /// Handles receiving a response for a Backfill sync request that should have both blocks and /// blobs. - fn block_blob_backfill_response( + fn blobs_backfill_response( &mut self, id: Id, peer_id: PeerId, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) { if let Some((batch_id, block_responses)) = self .network @@ -886,14 +886,14 @@ impl SyncManager { "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy - let id = RequestId::BackFillSidecarPair { id }; + let id = RequestId::BackFillBlobs { id }; self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } } } - fn rpc_sidecar_received( + fn rpc_blobs_received( &mut self, request_id: RequestId, peer_id: PeerId, @@ -904,57 +904,47 @@ impl SyncManager { RequestId::SingleBlock { .. } | RequestId::ParentLookup { .. } => { unreachable!("There is no such thing as a singular 'by root' glob request that is not accompanied by the block") } - RequestId::BackFillSync { .. } => { + RequestId::BackFillBlocks { .. } => { unreachable!("An only blocks request does not receive sidecars") } - RequestId::BackFillSidecarPair { id } => { - self.block_blob_backfill_response(id, peer_id, maybe_sidecar.into()) + RequestId::BackFillBlobs { id } => { + self.blobs_backfill_response(id, peer_id, maybe_sidecar.into()) } - RequestId::RangeSync { .. } => { + RequestId::RangeBlocks { .. } => { unreachable!("Only-blocks range requests don't receive sidecars") } - RequestId::RangeSidecarPair { id } => { - self.block_blob_range_response(id, peer_id, maybe_sidecar.into()) + RequestId::RangeBlobs { id } => { + self.blobs_range_response(id, peer_id, maybe_sidecar.into()) } } } - fn rpc_block_sidecar_pair_received( + fn rpc_block_block_and_blobs_received( &mut self, request_id: RequestId, peer_id: PeerId, - block_sidecar_pair: Option>>, + block_sidecar_pair: Option>, seen_timestamp: Duration, ) { match request_id { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| { - BlockWrapper::BlockAndBlob( - // TODO: why is this in an arc - (*block_sidecar_pair).clone(), - ) - }), + block_sidecar_pair.map(|block_sidecar_pair| block_sidecar_pair.into()), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| { - BlockWrapper::BlockAndBlob( - // TODO: why is this in an arc - (*block_sidecar_pair).clone(), - ) - }), + block_sidecar_pair.map(|block_sidecar_pair| block_sidecar_pair.into()), seen_timestamp, &mut self.network, ), - RequestId::BackFillSync { .. } - | RequestId::BackFillSidecarPair { .. } - | RequestId::RangeSync { .. } - | RequestId::RangeSidecarPair { .. } => unreachable!( + RequestId::BackFillBlocks { .. } + | RequestId::BackFillBlobs { .. } + | RequestId::RangeBlocks { .. } + | RequestId::RangeBlobs { .. } => unreachable!( "since range requests are not block-glob coupled, this should never be reachable" ), } diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 36da3bf8213..c54b3b1a983 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -1,9 +1,9 @@ //! Provides network functionality for the Syncing thread. This fundamentally wraps a network //! channel and stores a global RPC ID to perform requests. -use super::block_sidecar_coupling::BlockBlobRequestInfo; +use super::block_sidecar_coupling::BlocksAndBlobsRequestInfo; use super::manager::{Id, RequestId as SyncRequestId}; -use super::range_sync::{BatchId, ChainId, ExpectedBatchTy}; +use super::range_sync::{BatchId, ByRangeRequestType, ChainId}; use crate::beacon_processor::WorkEvent; use crate::service::{NetworkMessage, RequestId}; use crate::status::ToStatusMessage; @@ -38,11 +38,12 @@ pub struct SyncNetworkContext { backfill_requests: FnvHashMap, /// BlocksByRange requests paired with BlobsByRange requests made by the range. - range_sidecar_pair_requests: - FnvHashMap)>, + range_blocks_and_blobs_requests: + FnvHashMap)>, /// BlocksByRange requests paired with BlobsByRange requests made by the backfill sync. - backfill_sidecar_pair_requests: FnvHashMap)>, + backfill_blocks_and_blobs_requests: + FnvHashMap)>, /// Whether the ee is online. If it's not, we don't allow access to the /// `beacon_processor_send`. @@ -58,20 +59,20 @@ pub struct SyncNetworkContext { } /// Small enumeration to make dealing with block and blob requests easier. -pub enum BlockOrBlob { +pub enum BlockOrBlobs { Block(Option>>), - Blob(Option>>), + Blobs(Option>>), } -impl From>>> for BlockOrBlob { +impl From>>> for BlockOrBlobs { fn from(block: Option>>) -> Self { - BlockOrBlob::Block(block) + BlockOrBlobs::Block(block) } } -impl From>>> for BlockOrBlob { +impl From>>> for BlockOrBlobs { fn from(blob: Option>>) -> Self { - BlockOrBlob::Blob(blob) + BlockOrBlobs::Blobs(blob) } } @@ -89,8 +90,8 @@ impl SyncNetworkContext { request_id: 1, range_requests: Default::default(), backfill_requests: Default::default(), - range_sidecar_pair_requests: Default::default(), - backfill_sidecar_pair_requests: Default::default(), + range_blocks_and_blobs_requests: Default::default(), + backfill_blocks_and_blobs_requests: Default::default(), execution_engine_state: EngineState::Online, // always assume `Online` at the start beacon_processor_send, chain, @@ -140,13 +141,13 @@ impl SyncNetworkContext { pub fn blocks_by_range_request( &mut self, peer_id: PeerId, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, request: BlocksByRangeRequest, chain_id: ChainId, batch_id: BatchId, ) -> Result { match batch_type { - ExpectedBatchTy::OnlyBlock => { + ByRangeRequestType::Blocks => { trace!( self.log, "Sending BlocksByRange request"; @@ -156,7 +157,7 @@ impl SyncNetworkContext { ); let request = Request::BlocksByRange(request); let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeSync { id }); + let request_id = RequestId::Sync(SyncRequestId::RangeBlocks { id }); self.send_network_msg(NetworkMessage::SendRequest { peer_id, request, @@ -165,7 +166,7 @@ impl SyncNetworkContext { self.range_requests.insert(id, (chain_id, batch_id)); Ok(id) } - ExpectedBatchTy::OnlyBlockBlobs => { + ByRangeRequestType::BlocksAndBlobs => { debug!( self.log, "Sending BlocksByRange and BlobsByRange requests"; @@ -176,7 +177,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeSidecarPair { id }); + let request_id = RequestId::Sync(SyncRequestId::RangeBlobs { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { @@ -196,8 +197,8 @@ impl SyncNetworkContext { request: blobs_request, request_id, })?; - let block_blob_info = BlockBlobRequestInfo::default(); - self.range_sidecar_pair_requests + let block_blob_info = BlocksAndBlobsRequestInfo::default(); + self.range_blocks_and_blobs_requests .insert(id, (chain_id, batch_id, block_blob_info)); Ok(id) } @@ -208,12 +209,12 @@ impl SyncNetworkContext { pub fn backfill_blocks_by_range_request( &mut self, peer_id: PeerId, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, request: BlocksByRangeRequest, batch_id: BatchId, ) -> Result { match batch_type { - ExpectedBatchTy::OnlyBlock => { + ByRangeRequestType::Blocks => { trace!( self.log, "Sending backfill BlocksByRange request"; @@ -223,7 +224,7 @@ impl SyncNetworkContext { ); let request = Request::BlocksByRange(request); let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::BackFillSync { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillBlocks { id }); self.send_network_msg(NetworkMessage::SendRequest { peer_id, request, @@ -232,7 +233,7 @@ impl SyncNetworkContext { self.backfill_requests.insert(id, batch_id); Ok(id) } - ExpectedBatchTy::OnlyBlockBlobs => { + ByRangeRequestType::BlocksAndBlobs => { debug!( self.log, "Sending backfill BlocksByRange and BlobsByRange requests"; @@ -243,7 +244,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::BackFillSidecarPair { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillBlobs { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { @@ -263,8 +264,8 @@ impl SyncNetworkContext { request: blobs_request, request_id, })?; - let block_blob_info = BlockBlobRequestInfo::default(); - self.backfill_sidecar_pair_requests + let block_blob_info = BlocksAndBlobsRequestInfo::default(); + self.backfill_blocks_and_blobs_requests .insert(id, (batch_id, block_blob_info)); Ok(id) } @@ -288,18 +289,18 @@ impl SyncNetworkContext { pub fn range_sync_block_and_blob_response( &mut self, request_id: Id, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) -> Option<( ChainId, BatchId, Result>, &'static str>, )> { - match self.range_sidecar_pair_requests.entry(request_id) { + match self.range_blocks_and_blobs_requests.entry(request_id) { Entry::Occupied(mut entry) => { let (_, _, info) = entry.get_mut(); match block_or_blob { - BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), - BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + BlockOrBlobs::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlobs::Blobs(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { // If the request is finished, dequeue everything @@ -316,28 +317,28 @@ impl SyncNetworkContext { pub fn range_sync_request_failed( &mut self, request_id: Id, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, ) -> Option<(ChainId, BatchId)> { match batch_type { - ExpectedBatchTy::OnlyBlockBlobs => self - .range_sidecar_pair_requests + ByRangeRequestType::BlocksAndBlobs => self + .range_blocks_and_blobs_requests .remove(&request_id) .map(|(chain_id, batch_id, _info)| (chain_id, batch_id)), - ExpectedBatchTy::OnlyBlock => self.range_requests.remove(&request_id), + ByRangeRequestType::Blocks => self.range_requests.remove(&request_id), } } pub fn backfill_request_failed( &mut self, request_id: Id, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, ) -> Option { match batch_type { - ExpectedBatchTy::OnlyBlockBlobs => self - .backfill_sidecar_pair_requests + ByRangeRequestType::BlocksAndBlobs => self + .backfill_blocks_and_blobs_requests .remove(&request_id) .map(|(batch_id, _info)| batch_id), - ExpectedBatchTy::OnlyBlock => self.backfill_requests.remove(&request_id), + ByRangeRequestType::Blocks => self.backfill_requests.remove(&request_id), } } @@ -360,14 +361,14 @@ impl SyncNetworkContext { pub fn backfill_sync_block_and_blob_response( &mut self, request_id: Id, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) -> Option<(BatchId, Result>, &'static str>)> { - match self.backfill_sidecar_pair_requests.entry(request_id) { + match self.backfill_blocks_and_blobs_requests.entry(request_id) { Entry::Occupied(mut entry) => { let (_, info) = entry.get_mut(); match block_or_blob { - BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), - BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + BlockOrBlobs::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlobs::Blobs(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { // If the request is finished, dequeue everything @@ -533,7 +534,7 @@ impl SyncNetworkContext { /// Check whether a batch for this epoch (and only this epoch) should request just blocks or /// blocks and blobs. - pub fn batch_type(&self, epoch: types::Epoch) -> ExpectedBatchTy { + pub fn batch_type(&self, epoch: types::Epoch) -> ByRangeRequestType { const _: () = assert!( super::backfill_sync::BACKFILL_EPOCHS_PER_BATCH == 1 && super::range_sync::EPOCHS_PER_BATCH == 1, @@ -542,18 +543,18 @@ impl SyncNetworkContext { #[cfg(test)] { // Keep tests only for blocks. - return ExpectedBatchTy::OnlyBlock; + return ByRangeRequestType::Blocks; } #[cfg(not(test))] { if let Some(data_availability_boundary) = self.chain.data_availability_boundary() { if epoch >= data_availability_boundary { - ExpectedBatchTy::OnlyBlockBlobs + ByRangeRequestType::BlocksAndBlobs } else { - ExpectedBatchTy::OnlyBlock + ByRangeRequestType::Blocks } } else { - ExpectedBatchTy::OnlyBlock + ByRangeRequestType::Blocks } } } diff --git a/beacon_node/network/src/sync/range_sync/batch.rs b/beacon_node/network/src/sync/range_sync/batch.rs index 80f34f8b44f..184dcffc47d 100644 --- a/beacon_node/network/src/sync/range_sync/batch.rs +++ b/beacon_node/network/src/sync/range_sync/batch.rs @@ -4,10 +4,9 @@ use lighthouse_network::PeerId; use std::collections::HashSet; use std::hash::{Hash, Hasher}; use std::ops::Sub; -use std::sync::Arc; use strum::Display; use types::signed_block_and_blobs::BlockWrapper; -use types::{Epoch, EthSpec, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, Slot}; +use types::{Epoch, EthSpec, Slot}; /// The number of times to retry a batch before it is considered failed. const MAX_BATCH_DOWNLOAD_ATTEMPTS: u8 = 5; @@ -16,36 +15,12 @@ const MAX_BATCH_DOWNLOAD_ATTEMPTS: u8 = 5; /// after `MAX_BATCH_PROCESSING_ATTEMPTS` times, it is considered faulty. const MAX_BATCH_PROCESSING_ATTEMPTS: u8 = 3; -pub enum BatchTy { - Blocks(Vec>>), - BlocksAndBlobs(Vec>), -} - -impl BatchTy { - pub fn into_wrapped_blocks(self) -> Vec> { - match self { - BatchTy::Blocks(blocks) => blocks - .into_iter() - .map(|block| BlockWrapper::Block(block)) - .collect(), - BatchTy::BlocksAndBlobs(block_sidecar_pair) => block_sidecar_pair - .into_iter() - .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob(block_sidecar_pair)) - .collect(), - } - } -} - -/// Error representing a batch with mixed block types. -#[derive(Debug)] -pub struct MixedBlockTyErr; - /// Type of expected batch. #[derive(Debug, Copy, Clone, Display)] #[strum(serialize_all = "snake_case")] -pub enum ExpectedBatchTy { - OnlyBlockBlobs, - OnlyBlock, +pub enum ByRangeRequestType { + BlocksAndBlobs, + Blocks, } /// Allows customisation of the above constants used in other sync methods such as BackFillSync. @@ -131,7 +106,7 @@ pub struct BatchInfo { /// State of the batch. state: BatchState, /// Whether this batch contains all blocks or all blocks and blobs. - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, /// Pin the generic marker: std::marker::PhantomData, } @@ -180,7 +155,7 @@ impl BatchInfo { /// fork boundary will be of mixed type (all blocks and one last blockblob), and I don't want to /// deal with this for now. /// This means finalization might be slower in eip4844 - pub fn new(start_epoch: &Epoch, num_of_epochs: u64, batch_type: ExpectedBatchTy) -> Self { + pub fn new(start_epoch: &Epoch, num_of_epochs: u64, batch_type: ByRangeRequestType) -> Self { let start_slot = start_epoch.start_slot(T::slots_per_epoch()); let end_slot = start_slot + num_of_epochs * T::slots_per_epoch(); BatchInfo { @@ -243,7 +218,7 @@ impl BatchInfo { } /// Returns a BlocksByRange request associated with the batch. - pub fn to_blocks_by_range_request(&self) -> (BlocksByRangeRequest, ExpectedBatchTy) { + pub fn to_blocks_by_range_request(&self) -> (BlocksByRangeRequest, ByRangeRequestType) { ( BlocksByRangeRequest { start_slot: self.start_slot.into(), @@ -408,30 +383,11 @@ impl BatchInfo { } } - pub fn start_processing(&mut self) -> Result, WrongState> { + pub fn start_processing(&mut self) -> Result>, WrongState> { match self.state.poison() { BatchState::AwaitingProcessing(peer, blocks) => { self.state = BatchState::Processing(Attempt::new::(peer, &blocks)); - match self.batch_type { - ExpectedBatchTy::OnlyBlockBlobs => { - let blocks = blocks.into_iter().map(|block| { - let BlockWrapper::BlockAndBlob(block_and_blob) = block else { - panic!("Batches should never have a mixed type. This is a bug. Contact D") - }; - block_and_blob - }).collect(); - Ok(BatchTy::BlocksAndBlobs(blocks)) - } - ExpectedBatchTy::OnlyBlock => { - let blocks = blocks.into_iter().map(|block| { - let BlockWrapper::Block(block) = block else { - panic!("Batches should never have a mixed type. This is a bug. Contact D") - }; - block - }).collect(); - Ok(BatchTy::Blocks(blocks)) - } - } + Ok(blocks) } BatchState::Poisoned => unreachable!("Poisoned batch"), other => { diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index 89e120050ed..d60de322467 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -332,7 +332,7 @@ impl SyncingChain { let process_id = ChainSegmentProcessId::RangeBatchId(self.id, batch_id, count_unrealized); self.current_processing_batch = Some(batch_id); - let work_event = BeaconWorkEvent::chain_segment(process_id, blocks.into_wrapped_blocks()); + let work_event = BeaconWorkEvent::chain_segment(process_id, blocks); if let Err(e) = beacon_processor_send.try_send(work_event) { crit!(self.log, "Failed to send chain segment to processor."; "msg" => "process_batch", diff --git a/beacon_node/network/src/sync/range_sync/mod.rs b/beacon_node/network/src/sync/range_sync/mod.rs index 28426032191..d0f2f9217eb 100644 --- a/beacon_node/network/src/sync/range_sync/mod.rs +++ b/beacon_node/network/src/sync/range_sync/mod.rs @@ -9,8 +9,8 @@ mod range; mod sync_type; pub use batch::{ - BatchConfig, BatchInfo, BatchOperationOutcome, BatchProcessingResult, BatchState, BatchTy, - ExpectedBatchTy, + BatchConfig, BatchInfo, BatchOperationOutcome, BatchProcessingResult, BatchState, + ByRangeRequestType, }; pub use chain::{BatchId, ChainId, EPOCHS_PER_BATCH}; pub use range::RangeSync; diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index 1e3474fa5af..09d93b0e8f3 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -373,7 +373,7 @@ where #[cfg(test)] mod tests { use crate::service::RequestId; - use crate::sync::range_sync::ExpectedBatchTy; + use crate::sync::range_sync::ByRangeRequestType; use crate::NetworkMessage; use super::*; @@ -686,7 +686,7 @@ mod tests { let (peer1, local_info, head_info) = rig.head_peer(); range.add_peer(&mut rig.cx, local_info, peer1, head_info); let ((chain1, batch1), id1) = match rig.grab_request(&peer1).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { + RequestId::Sync(crate::sync::manager::RequestId::RangeBlocks { id }) => { (rig.cx.range_sync_response(id, true).unwrap(), id) } other => panic!("unexpected request {:?}", other), @@ -705,7 +705,7 @@ mod tests { let (peer2, local_info, finalized_info) = rig.finalized_peer(); range.add_peer(&mut rig.cx, local_info, peer2, finalized_info); let ((chain2, batch2), id2) = match rig.grab_request(&peer2).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { + RequestId::Sync(crate::sync::manager::RequestId::RangeBlocks { id }) => { (rig.cx.range_sync_response(id, true).unwrap(), id) } other => panic!("unexpected request {:?}", other), diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index f21545f2783..c589fbcfeb9 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -34,33 +34,56 @@ impl SignedBeaconBlockAndBlobsSidecar { } } +/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. This newtype +/// wraps the `BlockWrapperInner` to ensure blobs cannot be accessed via an enum match. This would +/// circumvent empty blob reconstruction when accessing blobs. +#[derive(Clone, Debug, Derivative)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +pub struct BlockWrapper(BlockWrapperInner); + /// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. #[derive(Clone, Debug, Derivative)] #[derivative(PartialEq, Hash(bound = "T: EthSpec"))] -pub enum BlockWrapper { +pub enum BlockWrapperInner { Block(Arc>), BlockAndBlob(SignedBeaconBlockAndBlobsSidecar), } impl BlockWrapper { + pub fn new(block: Arc>) -> Self { + Self(BlockWrapperInner::Block(block)) + } + + pub fn new_with_blobs( + beacon_block: Arc>, + blobs_sidecar: Arc>, + ) -> Self { + Self(BlockWrapperInner::BlockAndBlob( + SignedBeaconBlockAndBlobsSidecar { + beacon_block, + blobs_sidecar, + }, + )) + } + pub fn slot(&self) -> Slot { - match self { - BlockWrapper::Block(block) => block.slot(), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + match &self.0 { + BlockWrapperInner::Block(block) => block.slot(), + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.slot() } } } pub fn block(&self) -> &SignedBeaconBlock { - match self { - BlockWrapper::Block(block) => &block, - BlockWrapper::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, + match &self.0 { + BlockWrapperInner::Block(block) => &block, + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, } } pub fn block_cloned(&self) -> Arc> { - match self { - BlockWrapper::Block(block) => block.clone(), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + match &self.0 { + BlockWrapperInner::Block(block) => block.clone(), + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.clone() } } @@ -70,20 +93,20 @@ impl BlockWrapper { &self, block_root: Option, ) -> Result>>, BlobReconstructionError> { - match self { - BlockWrapper::Block(block) => block + match &self.0 { + BlockWrapperInner::Block(block) => block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { Ok(Some(block_sidecar_pair.blobs_sidecar.clone())) } } } pub fn message(&self) -> crate::BeaconBlockRef { - match self { - BlockWrapper::Block(block) => block.message(), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + match &self.0 { + BlockWrapperInner::Block(block) => block.message(), + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.message() } } @@ -100,14 +123,14 @@ impl BlockWrapper { Arc>, Result>>, BlobReconstructionError>, ) { - match self { - BlockWrapper::Block(block) => { + match self.0 { + BlockWrapperInner::Block(block) => { let blobs = block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)); (block, blobs) } - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, blobs_sidecar, @@ -120,12 +143,18 @@ impl BlockWrapper { impl From> for BlockWrapper { fn from(block: SignedBeaconBlock) -> Self { - BlockWrapper::Block(Arc::new(block)) + BlockWrapper(BlockWrapperInner::Block(Arc::new(block))) } } impl From>> for BlockWrapper { fn from(block: Arc>) -> Self { - BlockWrapper::Block(block) + BlockWrapper(BlockWrapperInner::Block(block)) + } +} + +impl From> for BlockWrapper { + fn from(block: SignedBeaconBlockAndBlobsSidecar) -> Self { + BlockWrapper(BlockWrapperInner::BlockAndBlob(block)) } } From 1931a442dc004d8664e4d6811d2e8c5bbc259ceb Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 28 Dec 2022 10:30:36 -0500 Subject: [PATCH 50/59] Revert "renames, remove , wrap BlockWrapper enum to make descontruction private" This reverts commit 5b3b34a9d75aa837cbaaf41104ed35641dfbd504. --- .../beacon_chain/src/block_verification.rs | 2 +- beacon_node/http_api/src/publish_blocks.rs | 41 +++--- .../src/rpc/codec/ssz_snappy.rs | 13 +- .../lighthouse_network/src/rpc/methods.rs | 8 +- .../src/service/api_types.rs | 4 +- .../lighthouse_network/src/service/mod.rs | 2 +- .../network/src/beacon_processor/mod.rs | 4 +- .../beacon_processor/worker/rpc_methods.rs | 4 +- .../beacon_processor/worker/sync_methods.rs | 9 +- beacon_node/network/src/router/processor.rs | 30 ++--- .../network/src/sync/backfill_sync/mod.rs | 2 +- .../src/sync/block_sidecar_coupling.rs | 20 ++- beacon_node/network/src/sync/manager.rs | 118 ++++++++++-------- .../network/src/sync/network_context.rs | 97 +++++++------- .../network/src/sync/range_sync/batch.rs | 62 +++++++-- .../network/src/sync/range_sync/chain.rs | 2 +- .../network/src/sync/range_sync/mod.rs | 4 +- .../network/src/sync/range_sync/range.rs | 6 +- consensus/types/src/signed_block_and_blobs.rs | 71 ++++------- 19 files changed, 268 insertions(+), 231 deletions(-) diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 2b759e4ad96..c8d3aed7961 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -1141,7 +1141,7 @@ impl IntoExecutionPendingBlock for Arc( // Send the block, regardless of whether or not it is valid. The API // specification is very clear that this is the desired behaviour. - let wrapped_block: BlockWrapper = - if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { - if let Some(sidecar) = chain.blob_cache.pop(&block_root) { - let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { - beacon_block: block, - blobs_sidecar: Arc::new(sidecar), - }; - crate::publish_pubsub_message( - network_tx, - PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), - )?; - block_and_blobs.into() - } else { - //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required - return Err(warp_utils::reject::broadcast_without_import(format!( - "no blob cached for block" - ))); - } + let wrapped_block = if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { + if let Some(sidecar) = chain.blob_cache.pop(&block_root) { + let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { + beacon_block: block, + blobs_sidecar: Arc::new(sidecar), + }; + crate::publish_pubsub_message( + network_tx, + PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), + )?; + BlockWrapper::BlockAndBlob(block_and_blobs) } else { - crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; - block.into() - }; + //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required + return Err(warp_utils::reject::broadcast_without_import(format!( + "no blob cached for block" + ))); + } + } else { + crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; + BlockWrapper::Block(block) + }; // Determine the delay after the start of the slot, register it with metrics. let block = wrapped_block.block(); diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index eb5cc7f27fa..df5350d9494 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -73,7 +73,7 @@ impl Encoder> for SSZSnappyInboundCodec< RPCResponse::BlocksByRange(res) => res.as_ssz_bytes(), RPCResponse::BlocksByRoot(res) => res.as_ssz_bytes(), RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(), - RPCResponse::BlockAndBlobsByRoot(res) => res.as_ssz_bytes(), + RPCResponse::BlobsByRoot(res) => res.as_ssz_bytes(), RPCResponse::LightClientBootstrap(res) => res.as_ssz_bytes(), RPCResponse::Pong(res) => res.data.as_ssz_bytes(), RPCResponse::MetaData(res) => @@ -439,8 +439,7 @@ fn context_bytes( SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()), }; } - if let RPCResponse::BlobsByRange(_) | RPCResponse::BlockAndBlobsByRoot(_) = rpc_variant - { + if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant { return fork_context.to_context_bytes(ForkName::Eip4844); } } @@ -586,7 +585,7 @@ fn handle_v1_response( )))), _ => Err(RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - "Invalid fork name for blobs by range".to_string(), + "Invalid forkname for blobsbyrange".to_string(), )), } } @@ -598,12 +597,12 @@ fn handle_v1_response( ) })?; match fork_name { - ForkName::Eip4844 => Ok(Some(RPCResponse::BlockAndBlobsByRoot( + ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRoot(Arc::new( SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, - ))), + )))), _ => Err(RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - "Invalid fork name for block and blobs by root".to_string(), + "Invalid forkname for blobsbyroot".to_string(), )), } } diff --git a/beacon_node/lighthouse_network/src/rpc/methods.rs b/beacon_node/lighthouse_network/src/rpc/methods.rs index 02e24d8e1d1..53e6b675990 100644 --- a/beacon_node/lighthouse_network/src/rpc/methods.rs +++ b/beacon_node/lighthouse_network/src/rpc/methods.rs @@ -281,7 +281,7 @@ pub enum RPCResponse { LightClientBootstrap(LightClientBootstrap), /// A response to a get BLOBS_BY_ROOT request. - BlockAndBlobsByRoot(SignedBeaconBlockAndBlobsSidecar), + BlobsByRoot(Arc>), /// A PONG response to a PING request. Pong(Ping), @@ -372,7 +372,7 @@ impl RPCCodedResponse { RPCResponse::BlocksByRange(_) => true, RPCResponse::BlocksByRoot(_) => true, RPCResponse::BlobsByRange(_) => true, - RPCResponse::BlockAndBlobsByRoot(_) => true, + RPCResponse::BlobsByRoot(_) => true, RPCResponse::Pong(_) => false, RPCResponse::MetaData(_) => false, RPCResponse::LightClientBootstrap(_) => false, @@ -409,7 +409,7 @@ impl RPCResponse { RPCResponse::BlocksByRange(_) => Protocol::BlocksByRange, RPCResponse::BlocksByRoot(_) => Protocol::BlocksByRoot, RPCResponse::BlobsByRange(_) => Protocol::BlobsByRange, - RPCResponse::BlockAndBlobsByRoot(_) => Protocol::BlobsByRoot, + RPCResponse::BlobsByRoot(_) => Protocol::BlobsByRoot, RPCResponse::Pong(_) => Protocol::Ping, RPCResponse::MetaData(_) => Protocol::MetaData, RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap, @@ -449,7 +449,7 @@ impl std::fmt::Display for RPCResponse { RPCResponse::BlobsByRange(blob) => { write!(f, "BlobsByRange: Blob slot: {}", blob.beacon_block_slot) } - RPCResponse::BlockAndBlobsByRoot(blob) => { + RPCResponse::BlobsByRoot(blob) => { write!( f, "BlobsByRoot: Blob slot: {}", diff --git a/beacon_node/lighthouse_network/src/service/api_types.rs b/beacon_node/lighthouse_network/src/service/api_types.rs index c9c239d8cf4..b6a03302008 100644 --- a/beacon_node/lighthouse_network/src/service/api_types.rs +++ b/beacon_node/lighthouse_network/src/service/api_types.rs @@ -83,7 +83,7 @@ pub enum Response { /// A response to a LightClientUpdate request. LightClientBootstrap(LightClientBootstrap), /// A response to a get BLOBS_BY_ROOT request. - BlobsByRoot(Option>), + BlobsByRoot(Option>>), } impl std::convert::From> for RPCCodedResponse { @@ -98,7 +98,7 @@ impl std::convert::From> for RPCCodedResponse RPCCodedResponse::StreamTermination(ResponseTermination::BlocksByRange), }, Response::BlobsByRoot(r) => match r { - Some(b) => RPCCodedResponse::Success(RPCResponse::BlockAndBlobsByRoot(b)), + Some(b) => RPCCodedResponse::Success(RPCResponse::BlobsByRoot(b)), None => RPCCodedResponse::StreamTermination(ResponseTermination::BlobsByRoot), }, Response::BlobsByRange(r) => match r { diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index d59bc4bfd6c..9adf7699bc2 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -1315,7 +1315,7 @@ impl Network { RPCResponse::BlocksByRoot(resp) => { self.build_response(id, peer_id, Response::BlocksByRoot(Some(resp))) } - RPCResponse::BlockAndBlobsByRoot(resp) => { + RPCResponse::BlobsByRoot(resp) => { self.build_response(id, peer_id, Response::BlobsByRoot(Some(resp))) } // Should never be reached diff --git a/beacon_node/network/src/beacon_processor/mod.rs b/beacon_node/network/src/beacon_processor/mod.rs index 37d6edef82f..9de006c84f5 100644 --- a/beacon_node/network/src/beacon_processor/mod.rs +++ b/beacon_node/network/src/beacon_processor/mod.rs @@ -1699,7 +1699,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - block.into(), + BlockWrapper::Block(block), work_reprocessing_tx, duplicate_cache, seen_timestamp, @@ -1721,7 +1721,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - block_sidecar_pair.into(), + BlockWrapper::BlockAndBlob(block_sidecar_pair), work_reprocessing_tx, duplicate_cache, seen_timestamp, diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 69bd7da11c6..3ade1bb87b6 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -230,10 +230,10 @@ impl Worker { Ok((Some(block), Some(blobs))) => { self.send_response( peer_id, - Response::BlobsByRoot(Some(SignedBeaconBlockAndBlobsSidecar { + Response::BlobsByRoot(Some(Arc::new(SignedBeaconBlockAndBlobsSidecar { beacon_block: block, blobs_sidecar: blobs, - })), + }))), request_id, ); send_block_count += 1; diff --git a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs index b3465c56dc5..5af62c37de0 100644 --- a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs @@ -188,7 +188,14 @@ impl Worker { let end_slot = downloaded_blocks.last().map(|b| b.slot().as_u64()); let sent_blocks = downloaded_blocks.len(); - let unwrapped = downloaded_blocks.into_iter().map(|_| todo!()).collect(); + let unwrapped = downloaded_blocks + .into_iter() + .map(|block| match block { + BlockWrapper::Block(block) => block, + //FIXME(sean) handle blobs in backfill + BlockWrapper::BlockAndBlob(_) => todo!(), + }) + .collect(); match self.process_backfill_blocks(unwrapped) { (_, Ok(_)) => { diff --git a/beacon_node/network/src/router/processor.rs b/beacon_node/network/src/router/processor.rs index d0879babacb..5ee0e367b68 100644 --- a/beacon_node/network/src/router/processor.rs +++ b/beacon_node/network/src/router/processor.rs @@ -223,10 +223,10 @@ impl Processor { SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. } => { unreachable!("Block lookups do not request BBRange requests") } - id @ (SyncId::BackFillBlocks { .. } - | SyncId::RangeBlocks { .. } - | SyncId::BackFillBlobs { .. } - | SyncId::RangeBlobs { .. }) => id, + id @ (SyncId::BackFillSync { .. } + | SyncId::RangeSync { .. } + | SyncId::BackFillSidecarPair { .. } + | SyncId::RangeSidecarPair { .. }) => id, }, RequestId::Router => unreachable!("All BBRange requests belong to sync"), }; @@ -258,7 +258,7 @@ impl Processor { ); if let RequestId::Sync(id) = request_id { - self.send_to_sync(SyncMessage::RpcBlobs { + self.send_to_sync(SyncMessage::RpcGlob { peer_id, request_id: id, blob_sidecar, @@ -282,10 +282,10 @@ impl Processor { let request_id = match request_id { RequestId::Sync(sync_id) => match sync_id { id @ (SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. }) => id, - SyncId::BackFillBlocks { .. } - | SyncId::RangeBlocks { .. } - | SyncId::RangeBlobs { .. } - | SyncId::BackFillBlobs { .. } => { + SyncId::BackFillSync { .. } + | SyncId::RangeSync { .. } + | SyncId::RangeSidecarPair { .. } + | SyncId::BackFillSidecarPair { .. } => { unreachable!("Batch syncing do not request BBRoot requests") } }, @@ -310,15 +310,15 @@ impl Processor { &mut self, peer_id: PeerId, request_id: RequestId, - block_and_blobs: Option>, + block_and_blobs: Option>>, ) { let request_id = match request_id { RequestId::Sync(sync_id) => match sync_id { id @ (SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. }) => id, - SyncId::BackFillBlocks { .. } - | SyncId::RangeBlocks { .. } - | SyncId::RangeBlobs { .. } - | SyncId::BackFillBlobs { .. } => { + SyncId::BackFillSync { .. } + | SyncId::RangeSync { .. } + | SyncId::RangeSidecarPair { .. } + | SyncId::BackFillSidecarPair { .. } => { unreachable!("Batch syncing does not request BBRoot requests") } }, @@ -330,7 +330,7 @@ impl Processor { "Received BlockAndBlobssByRoot Response"; "peer" => %peer_id, ); - self.send_to_sync(SyncMessage::RpcBlockAndBlobs { + self.send_to_sync(SyncMessage::RpcBlockAndGlob { peer_id, request_id, block_and_blobs, diff --git a/beacon_node/network/src/sync/backfill_sync/mod.rs b/beacon_node/network/src/sync/backfill_sync/mod.rs index ad1bfb1d42d..56ed551530c 100644 --- a/beacon_node/network/src/sync/backfill_sync/mod.rs +++ b/beacon_node/network/src/sync/backfill_sync/mod.rs @@ -536,7 +536,7 @@ impl BackFillSync { let process_id = ChainSegmentProcessId::BackSyncBatchId(batch_id); self.current_processing_batch = Some(batch_id); - let work_event = BeaconWorkEvent::chain_segment(process_id, blocks); + let work_event = BeaconWorkEvent::chain_segment(process_id, blocks.into_wrapped_blocks()); if let Err(e) = network.processor_channel().try_send(work_event) { crit!(self.log, "Failed to send backfill segment to processor."; "msg" => "process_batch", "error" => %e, "batch" => self.processing_target); diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index 46ac5bd0fbd..f82417db3a1 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -1,9 +1,12 @@ use std::{collections::VecDeque, sync::Arc}; -use types::{signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock}; +use types::{ + signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock, + SignedBeaconBlockAndBlobsSidecar, +}; #[derive(Debug, Default)] -pub struct BlocksAndBlobsRequestInfo { +pub struct BlockBlobRequestInfo { /// Blocks we have received awaiting for their corresponding sidecar. accumulated_blocks: VecDeque>>, /// Sidecars we have received awaiting for their corresponding block. @@ -14,7 +17,7 @@ pub struct BlocksAndBlobsRequestInfo { is_sidecars_stream_terminated: bool, } -impl BlocksAndBlobsRequestInfo { +impl BlockBlobRequestInfo { pub fn add_block_response(&mut self, maybe_block: Option>>) { match maybe_block { Some(block) => self.accumulated_blocks.push_back(block), @@ -30,7 +33,7 @@ impl BlocksAndBlobsRequestInfo { } pub fn into_responses(self) -> Result>, &'static str> { - let BlocksAndBlobsRequestInfo { + let BlockBlobRequestInfo { accumulated_blocks, mut accumulated_sidecars, .. @@ -48,9 +51,14 @@ impl BlocksAndBlobsRequestInfo { { let blobs_sidecar = accumulated_sidecars.pop_front().ok_or("missing sidecar")?; - Ok(BlockWrapper::new_with_blobs(beacon_block, blobs_sidecar)) + Ok(BlockWrapper::BlockAndBlob( + SignedBeaconBlockAndBlobsSidecar { + beacon_block, + blobs_sidecar, + }, + )) } else { - Ok(beacon_block.into()) + Ok(BlockWrapper::Block(beacon_block)) } }) .collect::, _>>(); diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 5da203e0e77..29838bde713 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -35,13 +35,13 @@ use super::backfill_sync::{BackFillSync, ProcessResult, SyncStart}; use super::block_lookups::BlockLookups; -use super::network_context::{BlockOrBlobs, SyncNetworkContext}; +use super::network_context::{BlockOrBlob, SyncNetworkContext}; use super::peer_sync_info::{remote_sync_type, PeerSyncType}; use super::range_sync::{RangeSync, RangeSyncType, EPOCHS_PER_BATCH}; use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent as BeaconWorkEvent}; use crate::service::NetworkMessage; use crate::status::ToStatusMessage; -use crate::sync::range_sync::ByRangeRequestType; +use crate::sync::range_sync::ExpectedBatchTy; use beacon_chain::{BeaconChain, BeaconChainTypes, BlockError, EngineState}; use futures::StreamExt; use lighthouse_network::rpc::methods::MAX_REQUEST_BLOCKS; @@ -79,13 +79,13 @@ pub enum RequestId { /// Request searching for a block's parent. The id is the chain ParentLookup { id: Id }, /// Request was from the backfill sync algorithm. - BackFillBlocks { id: Id }, - /// Backfill request for blob sidecars. - BackFillBlobs { id: Id }, + BackFillSync { id: Id }, + /// Backfill request for blocks and sidecars. + BackFillSidecarPair { id: Id }, /// The request was from a chain in the range sync algorithm. - RangeBlocks { id: Id }, - /// The request was from a chain in range, asking for ranges blob sidecars. - RangeBlobs { id: Id }, + RangeSync { id: Id }, + /// The request was from a chain in range, asking for ranges of blocks and sidecars. + RangeSidecarPair { id: Id }, } #[derive(Debug)] @@ -103,7 +103,7 @@ pub enum SyncMessage { }, /// A blob has been received from the RPC. - RpcBlobs { + RpcGlob { request_id: RequestId, peer_id: PeerId, blob_sidecar: Option>>, @@ -111,10 +111,10 @@ pub enum SyncMessage { }, /// A block and blobs have been received from the RPC. - RpcBlockAndBlobs { + RpcBlockAndGlob { request_id: RequestId, peer_id: PeerId, - block_and_blobs: Option>, + block_and_blobs: Option>>, seen_timestamp: Duration, }, @@ -295,10 +295,10 @@ impl SyncManager { self.block_lookups .parent_lookup_failed(id, peer_id, &mut self.network, error); } - RequestId::BackFillBlocks { id } => { + RequestId::BackFillSync { id } => { if let Some(batch_id) = self .network - .backfill_request_failed(id, ByRangeRequestType::Blocks) + .backfill_request_failed(id, ExpectedBatchTy::OnlyBlock) { match self .backfill_sync @@ -310,10 +310,10 @@ impl SyncManager { } } - RequestId::BackFillBlobs { id } => { + RequestId::BackFillSidecarPair { id } => { if let Some(batch_id) = self .network - .backfill_request_failed(id, ByRangeRequestType::BlocksAndBlobs) + .backfill_request_failed(id, ExpectedBatchTy::OnlyBlockBlobs) { match self .backfill_sync @@ -324,10 +324,10 @@ impl SyncManager { } } } - RequestId::RangeBlocks { id } => { + RequestId::RangeSync { id } => { if let Some((chain_id, batch_id)) = self .network - .range_sync_request_failed(id, ByRangeRequestType::Blocks) + .range_sync_request_failed(id, ExpectedBatchTy::OnlyBlock) { self.range_sync.inject_error( &mut self.network, @@ -339,10 +339,10 @@ impl SyncManager { self.update_sync_state() } } - RequestId::RangeBlobs { id } => { + RequestId::RangeSidecarPair { id } => { if let Some((chain_id, batch_id)) = self .network - .range_sync_request_failed(id, ByRangeRequestType::BlocksAndBlobs) + .range_sync_request_failed(id, ExpectedBatchTy::OnlyBlockBlobs) { self.range_sync.inject_error( &mut self.network, @@ -648,18 +648,18 @@ impl SyncManager { .block_lookups .parent_chain_processed(chain_hash, result, &mut self.network), }, - SyncMessage::RpcBlobs { + SyncMessage::RpcGlob { request_id, peer_id, blob_sidecar, seen_timestamp, - } => self.rpc_blobs_received(request_id, peer_id, blob_sidecar, seen_timestamp), - SyncMessage::RpcBlockAndBlobs { + } => self.rpc_sidecar_received(request_id, peer_id, blob_sidecar, seen_timestamp), + SyncMessage::RpcBlockAndGlob { request_id, peer_id, block_and_blobs, seen_timestamp, - } => self.rpc_block_block_and_blobs_received( + } => self.rpc_block_sidecar_pair_received( request_id, peer_id, block_and_blobs, @@ -734,18 +734,18 @@ impl SyncManager { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - beacon_block.map(|block| block.into()), + beacon_block.map(|block| BlockWrapper::Block(block)), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - beacon_block.map(|block| block.into()), + beacon_block.map(|block| BlockWrapper::Block(block)), seen_timestamp, &mut self.network, ), - RequestId::BackFillBlocks { id } => { + RequestId::BackFillSync { id } => { let is_stream_terminator = beacon_block.is_none(); if let Some(batch_id) = self .network @@ -756,7 +756,7 @@ impl SyncManager { batch_id, &peer_id, id, - beacon_block.map(|block| block.into()), + beacon_block.map(|block| BlockWrapper::Block(block)), ) { Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), Ok(ProcessResult::Successful) => {} @@ -768,7 +768,7 @@ impl SyncManager { } } } - RequestId::RangeBlocks { id } => { + RequestId::RangeSync { id } => { let is_stream_terminator = beacon_block.is_none(); if let Some((chain_id, batch_id)) = self .network @@ -780,28 +780,28 @@ impl SyncManager { chain_id, batch_id, id, - beacon_block.map(|block| block.into()), + beacon_block.map(|block| BlockWrapper::Block(block)), ); self.update_sync_state(); } } - RequestId::BackFillBlobs { id } => { - self.blobs_backfill_response(id, peer_id, beacon_block.into()) + RequestId::BackFillSidecarPair { id } => { + self.block_blob_backfill_response(id, peer_id, beacon_block.into()) } - RequestId::RangeBlobs { id } => { - self.blobs_range_response(id, peer_id, beacon_block.into()) + RequestId::RangeSidecarPair { id } => { + self.block_blob_range_response(id, peer_id, beacon_block.into()) } } } /// Handles receiving a response for a range sync request that should have both blocks and /// blobs. - fn blobs_range_response( + fn block_blob_range_response( &mut self, id: Id, peer_id: PeerId, - block_or_blob: BlockOrBlobs, + block_or_blob: BlockOrBlob, ) { if let Some((chain_id, batch_id, block_responses)) = self .network @@ -834,7 +834,7 @@ impl SyncManager { "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy - let id = RequestId::RangeBlobs { id }; + let id = RequestId::RangeSidecarPair { id }; self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } @@ -843,11 +843,11 @@ impl SyncManager { /// Handles receiving a response for a Backfill sync request that should have both blocks and /// blobs. - fn blobs_backfill_response( + fn block_blob_backfill_response( &mut self, id: Id, peer_id: PeerId, - block_or_blob: BlockOrBlobs, + block_or_blob: BlockOrBlob, ) { if let Some((batch_id, block_responses)) = self .network @@ -886,14 +886,14 @@ impl SyncManager { "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy - let id = RequestId::BackFillBlobs { id }; + let id = RequestId::BackFillSidecarPair { id }; self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } } } - fn rpc_blobs_received( + fn rpc_sidecar_received( &mut self, request_id: RequestId, peer_id: PeerId, @@ -904,47 +904,57 @@ impl SyncManager { RequestId::SingleBlock { .. } | RequestId::ParentLookup { .. } => { unreachable!("There is no such thing as a singular 'by root' glob request that is not accompanied by the block") } - RequestId::BackFillBlocks { .. } => { + RequestId::BackFillSync { .. } => { unreachable!("An only blocks request does not receive sidecars") } - RequestId::BackFillBlobs { id } => { - self.blobs_backfill_response(id, peer_id, maybe_sidecar.into()) + RequestId::BackFillSidecarPair { id } => { + self.block_blob_backfill_response(id, peer_id, maybe_sidecar.into()) } - RequestId::RangeBlocks { .. } => { + RequestId::RangeSync { .. } => { unreachable!("Only-blocks range requests don't receive sidecars") } - RequestId::RangeBlobs { id } => { - self.blobs_range_response(id, peer_id, maybe_sidecar.into()) + RequestId::RangeSidecarPair { id } => { + self.block_blob_range_response(id, peer_id, maybe_sidecar.into()) } } } - fn rpc_block_block_and_blobs_received( + fn rpc_block_sidecar_pair_received( &mut self, request_id: RequestId, peer_id: PeerId, - block_sidecar_pair: Option>, + block_sidecar_pair: Option>>, seen_timestamp: Duration, ) { match request_id { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| block_sidecar_pair.into()), + block_sidecar_pair.map(|block_sidecar_pair| { + BlockWrapper::BlockAndBlob( + // TODO: why is this in an arc + (*block_sidecar_pair).clone(), + ) + }), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| block_sidecar_pair.into()), + block_sidecar_pair.map(|block_sidecar_pair| { + BlockWrapper::BlockAndBlob( + // TODO: why is this in an arc + (*block_sidecar_pair).clone(), + ) + }), seen_timestamp, &mut self.network, ), - RequestId::BackFillBlocks { .. } - | RequestId::BackFillBlobs { .. } - | RequestId::RangeBlocks { .. } - | RequestId::RangeBlobs { .. } => unreachable!( + RequestId::BackFillSync { .. } + | RequestId::BackFillSidecarPair { .. } + | RequestId::RangeSync { .. } + | RequestId::RangeSidecarPair { .. } => unreachable!( "since range requests are not block-glob coupled, this should never be reachable" ), } diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index c54b3b1a983..36da3bf8213 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -1,9 +1,9 @@ //! Provides network functionality for the Syncing thread. This fundamentally wraps a network //! channel and stores a global RPC ID to perform requests. -use super::block_sidecar_coupling::BlocksAndBlobsRequestInfo; +use super::block_sidecar_coupling::BlockBlobRequestInfo; use super::manager::{Id, RequestId as SyncRequestId}; -use super::range_sync::{BatchId, ByRangeRequestType, ChainId}; +use super::range_sync::{BatchId, ChainId, ExpectedBatchTy}; use crate::beacon_processor::WorkEvent; use crate::service::{NetworkMessage, RequestId}; use crate::status::ToStatusMessage; @@ -38,12 +38,11 @@ pub struct SyncNetworkContext { backfill_requests: FnvHashMap, /// BlocksByRange requests paired with BlobsByRange requests made by the range. - range_blocks_and_blobs_requests: - FnvHashMap)>, + range_sidecar_pair_requests: + FnvHashMap)>, /// BlocksByRange requests paired with BlobsByRange requests made by the backfill sync. - backfill_blocks_and_blobs_requests: - FnvHashMap)>, + backfill_sidecar_pair_requests: FnvHashMap)>, /// Whether the ee is online. If it's not, we don't allow access to the /// `beacon_processor_send`. @@ -59,20 +58,20 @@ pub struct SyncNetworkContext { } /// Small enumeration to make dealing with block and blob requests easier. -pub enum BlockOrBlobs { +pub enum BlockOrBlob { Block(Option>>), - Blobs(Option>>), + Blob(Option>>), } -impl From>>> for BlockOrBlobs { +impl From>>> for BlockOrBlob { fn from(block: Option>>) -> Self { - BlockOrBlobs::Block(block) + BlockOrBlob::Block(block) } } -impl From>>> for BlockOrBlobs { +impl From>>> for BlockOrBlob { fn from(blob: Option>>) -> Self { - BlockOrBlobs::Blobs(blob) + BlockOrBlob::Blob(blob) } } @@ -90,8 +89,8 @@ impl SyncNetworkContext { request_id: 1, range_requests: Default::default(), backfill_requests: Default::default(), - range_blocks_and_blobs_requests: Default::default(), - backfill_blocks_and_blobs_requests: Default::default(), + range_sidecar_pair_requests: Default::default(), + backfill_sidecar_pair_requests: Default::default(), execution_engine_state: EngineState::Online, // always assume `Online` at the start beacon_processor_send, chain, @@ -141,13 +140,13 @@ impl SyncNetworkContext { pub fn blocks_by_range_request( &mut self, peer_id: PeerId, - batch_type: ByRangeRequestType, + batch_type: ExpectedBatchTy, request: BlocksByRangeRequest, chain_id: ChainId, batch_id: BatchId, ) -> Result { match batch_type { - ByRangeRequestType::Blocks => { + ExpectedBatchTy::OnlyBlock => { trace!( self.log, "Sending BlocksByRange request"; @@ -157,7 +156,7 @@ impl SyncNetworkContext { ); let request = Request::BlocksByRange(request); let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeBlocks { id }); + let request_id = RequestId::Sync(SyncRequestId::RangeSync { id }); self.send_network_msg(NetworkMessage::SendRequest { peer_id, request, @@ -166,7 +165,7 @@ impl SyncNetworkContext { self.range_requests.insert(id, (chain_id, batch_id)); Ok(id) } - ByRangeRequestType::BlocksAndBlobs => { + ExpectedBatchTy::OnlyBlockBlobs => { debug!( self.log, "Sending BlocksByRange and BlobsByRange requests"; @@ -177,7 +176,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeBlobs { id }); + let request_id = RequestId::Sync(SyncRequestId::RangeSidecarPair { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { @@ -197,8 +196,8 @@ impl SyncNetworkContext { request: blobs_request, request_id, })?; - let block_blob_info = BlocksAndBlobsRequestInfo::default(); - self.range_blocks_and_blobs_requests + let block_blob_info = BlockBlobRequestInfo::default(); + self.range_sidecar_pair_requests .insert(id, (chain_id, batch_id, block_blob_info)); Ok(id) } @@ -209,12 +208,12 @@ impl SyncNetworkContext { pub fn backfill_blocks_by_range_request( &mut self, peer_id: PeerId, - batch_type: ByRangeRequestType, + batch_type: ExpectedBatchTy, request: BlocksByRangeRequest, batch_id: BatchId, ) -> Result { match batch_type { - ByRangeRequestType::Blocks => { + ExpectedBatchTy::OnlyBlock => { trace!( self.log, "Sending backfill BlocksByRange request"; @@ -224,7 +223,7 @@ impl SyncNetworkContext { ); let request = Request::BlocksByRange(request); let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::BackFillBlocks { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillSync { id }); self.send_network_msg(NetworkMessage::SendRequest { peer_id, request, @@ -233,7 +232,7 @@ impl SyncNetworkContext { self.backfill_requests.insert(id, batch_id); Ok(id) } - ByRangeRequestType::BlocksAndBlobs => { + ExpectedBatchTy::OnlyBlockBlobs => { debug!( self.log, "Sending backfill BlocksByRange and BlobsByRange requests"; @@ -244,7 +243,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::BackFillBlobs { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillSidecarPair { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { @@ -264,8 +263,8 @@ impl SyncNetworkContext { request: blobs_request, request_id, })?; - let block_blob_info = BlocksAndBlobsRequestInfo::default(); - self.backfill_blocks_and_blobs_requests + let block_blob_info = BlockBlobRequestInfo::default(); + self.backfill_sidecar_pair_requests .insert(id, (batch_id, block_blob_info)); Ok(id) } @@ -289,18 +288,18 @@ impl SyncNetworkContext { pub fn range_sync_block_and_blob_response( &mut self, request_id: Id, - block_or_blob: BlockOrBlobs, + block_or_blob: BlockOrBlob, ) -> Option<( ChainId, BatchId, Result>, &'static str>, )> { - match self.range_blocks_and_blobs_requests.entry(request_id) { + match self.range_sidecar_pair_requests.entry(request_id) { Entry::Occupied(mut entry) => { let (_, _, info) = entry.get_mut(); match block_or_blob { - BlockOrBlobs::Block(maybe_block) => info.add_block_response(maybe_block), - BlockOrBlobs::Blobs(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { // If the request is finished, dequeue everything @@ -317,28 +316,28 @@ impl SyncNetworkContext { pub fn range_sync_request_failed( &mut self, request_id: Id, - batch_type: ByRangeRequestType, + batch_type: ExpectedBatchTy, ) -> Option<(ChainId, BatchId)> { match batch_type { - ByRangeRequestType::BlocksAndBlobs => self - .range_blocks_and_blobs_requests + ExpectedBatchTy::OnlyBlockBlobs => self + .range_sidecar_pair_requests .remove(&request_id) .map(|(chain_id, batch_id, _info)| (chain_id, batch_id)), - ByRangeRequestType::Blocks => self.range_requests.remove(&request_id), + ExpectedBatchTy::OnlyBlock => self.range_requests.remove(&request_id), } } pub fn backfill_request_failed( &mut self, request_id: Id, - batch_type: ByRangeRequestType, + batch_type: ExpectedBatchTy, ) -> Option { match batch_type { - ByRangeRequestType::BlocksAndBlobs => self - .backfill_blocks_and_blobs_requests + ExpectedBatchTy::OnlyBlockBlobs => self + .backfill_sidecar_pair_requests .remove(&request_id) .map(|(batch_id, _info)| batch_id), - ByRangeRequestType::Blocks => self.backfill_requests.remove(&request_id), + ExpectedBatchTy::OnlyBlock => self.backfill_requests.remove(&request_id), } } @@ -361,14 +360,14 @@ impl SyncNetworkContext { pub fn backfill_sync_block_and_blob_response( &mut self, request_id: Id, - block_or_blob: BlockOrBlobs, + block_or_blob: BlockOrBlob, ) -> Option<(BatchId, Result>, &'static str>)> { - match self.backfill_blocks_and_blobs_requests.entry(request_id) { + match self.backfill_sidecar_pair_requests.entry(request_id) { Entry::Occupied(mut entry) => { let (_, info) = entry.get_mut(); match block_or_blob { - BlockOrBlobs::Block(maybe_block) => info.add_block_response(maybe_block), - BlockOrBlobs::Blobs(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { // If the request is finished, dequeue everything @@ -534,7 +533,7 @@ impl SyncNetworkContext { /// Check whether a batch for this epoch (and only this epoch) should request just blocks or /// blocks and blobs. - pub fn batch_type(&self, epoch: types::Epoch) -> ByRangeRequestType { + pub fn batch_type(&self, epoch: types::Epoch) -> ExpectedBatchTy { const _: () = assert!( super::backfill_sync::BACKFILL_EPOCHS_PER_BATCH == 1 && super::range_sync::EPOCHS_PER_BATCH == 1, @@ -543,18 +542,18 @@ impl SyncNetworkContext { #[cfg(test)] { // Keep tests only for blocks. - return ByRangeRequestType::Blocks; + return ExpectedBatchTy::OnlyBlock; } #[cfg(not(test))] { if let Some(data_availability_boundary) = self.chain.data_availability_boundary() { if epoch >= data_availability_boundary { - ByRangeRequestType::BlocksAndBlobs + ExpectedBatchTy::OnlyBlockBlobs } else { - ByRangeRequestType::Blocks + ExpectedBatchTy::OnlyBlock } } else { - ByRangeRequestType::Blocks + ExpectedBatchTy::OnlyBlock } } } diff --git a/beacon_node/network/src/sync/range_sync/batch.rs b/beacon_node/network/src/sync/range_sync/batch.rs index 184dcffc47d..80f34f8b44f 100644 --- a/beacon_node/network/src/sync/range_sync/batch.rs +++ b/beacon_node/network/src/sync/range_sync/batch.rs @@ -4,9 +4,10 @@ use lighthouse_network::PeerId; use std::collections::HashSet; use std::hash::{Hash, Hasher}; use std::ops::Sub; +use std::sync::Arc; use strum::Display; use types::signed_block_and_blobs::BlockWrapper; -use types::{Epoch, EthSpec, Slot}; +use types::{Epoch, EthSpec, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, Slot}; /// The number of times to retry a batch before it is considered failed. const MAX_BATCH_DOWNLOAD_ATTEMPTS: u8 = 5; @@ -15,12 +16,36 @@ const MAX_BATCH_DOWNLOAD_ATTEMPTS: u8 = 5; /// after `MAX_BATCH_PROCESSING_ATTEMPTS` times, it is considered faulty. const MAX_BATCH_PROCESSING_ATTEMPTS: u8 = 3; +pub enum BatchTy { + Blocks(Vec>>), + BlocksAndBlobs(Vec>), +} + +impl BatchTy { + pub fn into_wrapped_blocks(self) -> Vec> { + match self { + BatchTy::Blocks(blocks) => blocks + .into_iter() + .map(|block| BlockWrapper::Block(block)) + .collect(), + BatchTy::BlocksAndBlobs(block_sidecar_pair) => block_sidecar_pair + .into_iter() + .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob(block_sidecar_pair)) + .collect(), + } + } +} + +/// Error representing a batch with mixed block types. +#[derive(Debug)] +pub struct MixedBlockTyErr; + /// Type of expected batch. #[derive(Debug, Copy, Clone, Display)] #[strum(serialize_all = "snake_case")] -pub enum ByRangeRequestType { - BlocksAndBlobs, - Blocks, +pub enum ExpectedBatchTy { + OnlyBlockBlobs, + OnlyBlock, } /// Allows customisation of the above constants used in other sync methods such as BackFillSync. @@ -106,7 +131,7 @@ pub struct BatchInfo { /// State of the batch. state: BatchState, /// Whether this batch contains all blocks or all blocks and blobs. - batch_type: ByRangeRequestType, + batch_type: ExpectedBatchTy, /// Pin the generic marker: std::marker::PhantomData, } @@ -155,7 +180,7 @@ impl BatchInfo { /// fork boundary will be of mixed type (all blocks and one last blockblob), and I don't want to /// deal with this for now. /// This means finalization might be slower in eip4844 - pub fn new(start_epoch: &Epoch, num_of_epochs: u64, batch_type: ByRangeRequestType) -> Self { + pub fn new(start_epoch: &Epoch, num_of_epochs: u64, batch_type: ExpectedBatchTy) -> Self { let start_slot = start_epoch.start_slot(T::slots_per_epoch()); let end_slot = start_slot + num_of_epochs * T::slots_per_epoch(); BatchInfo { @@ -218,7 +243,7 @@ impl BatchInfo { } /// Returns a BlocksByRange request associated with the batch. - pub fn to_blocks_by_range_request(&self) -> (BlocksByRangeRequest, ByRangeRequestType) { + pub fn to_blocks_by_range_request(&self) -> (BlocksByRangeRequest, ExpectedBatchTy) { ( BlocksByRangeRequest { start_slot: self.start_slot.into(), @@ -383,11 +408,30 @@ impl BatchInfo { } } - pub fn start_processing(&mut self) -> Result>, WrongState> { + pub fn start_processing(&mut self) -> Result, WrongState> { match self.state.poison() { BatchState::AwaitingProcessing(peer, blocks) => { self.state = BatchState::Processing(Attempt::new::(peer, &blocks)); - Ok(blocks) + match self.batch_type { + ExpectedBatchTy::OnlyBlockBlobs => { + let blocks = blocks.into_iter().map(|block| { + let BlockWrapper::BlockAndBlob(block_and_blob) = block else { + panic!("Batches should never have a mixed type. This is a bug. Contact D") + }; + block_and_blob + }).collect(); + Ok(BatchTy::BlocksAndBlobs(blocks)) + } + ExpectedBatchTy::OnlyBlock => { + let blocks = blocks.into_iter().map(|block| { + let BlockWrapper::Block(block) = block else { + panic!("Batches should never have a mixed type. This is a bug. Contact D") + }; + block + }).collect(); + Ok(BatchTy::Blocks(blocks)) + } + } } BatchState::Poisoned => unreachable!("Poisoned batch"), other => { diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index d60de322467..89e120050ed 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -332,7 +332,7 @@ impl SyncingChain { let process_id = ChainSegmentProcessId::RangeBatchId(self.id, batch_id, count_unrealized); self.current_processing_batch = Some(batch_id); - let work_event = BeaconWorkEvent::chain_segment(process_id, blocks); + let work_event = BeaconWorkEvent::chain_segment(process_id, blocks.into_wrapped_blocks()); if let Err(e) = beacon_processor_send.try_send(work_event) { crit!(self.log, "Failed to send chain segment to processor."; "msg" => "process_batch", diff --git a/beacon_node/network/src/sync/range_sync/mod.rs b/beacon_node/network/src/sync/range_sync/mod.rs index d0f2f9217eb..28426032191 100644 --- a/beacon_node/network/src/sync/range_sync/mod.rs +++ b/beacon_node/network/src/sync/range_sync/mod.rs @@ -9,8 +9,8 @@ mod range; mod sync_type; pub use batch::{ - BatchConfig, BatchInfo, BatchOperationOutcome, BatchProcessingResult, BatchState, - ByRangeRequestType, + BatchConfig, BatchInfo, BatchOperationOutcome, BatchProcessingResult, BatchState, BatchTy, + ExpectedBatchTy, }; pub use chain::{BatchId, ChainId, EPOCHS_PER_BATCH}; pub use range::RangeSync; diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index 09d93b0e8f3..1e3474fa5af 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -373,7 +373,7 @@ where #[cfg(test)] mod tests { use crate::service::RequestId; - use crate::sync::range_sync::ByRangeRequestType; + use crate::sync::range_sync::ExpectedBatchTy; use crate::NetworkMessage; use super::*; @@ -686,7 +686,7 @@ mod tests { let (peer1, local_info, head_info) = rig.head_peer(); range.add_peer(&mut rig.cx, local_info, peer1, head_info); let ((chain1, batch1), id1) = match rig.grab_request(&peer1).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeBlocks { id }) => { + RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { (rig.cx.range_sync_response(id, true).unwrap(), id) } other => panic!("unexpected request {:?}", other), @@ -705,7 +705,7 @@ mod tests { let (peer2, local_info, finalized_info) = rig.finalized_peer(); range.add_peer(&mut rig.cx, local_info, peer2, finalized_info); let ((chain2, batch2), id2) = match rig.grab_request(&peer2).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeBlocks { id }) => { + RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { (rig.cx.range_sync_response(id, true).unwrap(), id) } other => panic!("unexpected request {:?}", other), diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index c589fbcfeb9..f21545f2783 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -34,56 +34,33 @@ impl SignedBeaconBlockAndBlobsSidecar { } } -/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. This newtype -/// wraps the `BlockWrapperInner` to ensure blobs cannot be accessed via an enum match. This would -/// circumvent empty blob reconstruction when accessing blobs. -#[derive(Clone, Debug, Derivative)] -#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] -pub struct BlockWrapper(BlockWrapperInner); - /// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. #[derive(Clone, Debug, Derivative)] #[derivative(PartialEq, Hash(bound = "T: EthSpec"))] -pub enum BlockWrapperInner { +pub enum BlockWrapper { Block(Arc>), BlockAndBlob(SignedBeaconBlockAndBlobsSidecar), } impl BlockWrapper { - pub fn new(block: Arc>) -> Self { - Self(BlockWrapperInner::Block(block)) - } - - pub fn new_with_blobs( - beacon_block: Arc>, - blobs_sidecar: Arc>, - ) -> Self { - Self(BlockWrapperInner::BlockAndBlob( - SignedBeaconBlockAndBlobsSidecar { - beacon_block, - blobs_sidecar, - }, - )) - } - pub fn slot(&self) -> Slot { - match &self.0 { - BlockWrapperInner::Block(block) => block.slot(), - BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { + match self { + BlockWrapper::Block(block) => block.slot(), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.slot() } } } pub fn block(&self) -> &SignedBeaconBlock { - match &self.0 { - BlockWrapperInner::Block(block) => &block, - BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, + match self { + BlockWrapper::Block(block) => &block, + BlockWrapper::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, } } pub fn block_cloned(&self) -> Arc> { - match &self.0 { - BlockWrapperInner::Block(block) => block.clone(), - BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { + match self { + BlockWrapper::Block(block) => block.clone(), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.clone() } } @@ -93,20 +70,20 @@ impl BlockWrapper { &self, block_root: Option, ) -> Result>>, BlobReconstructionError> { - match &self.0 { - BlockWrapperInner::Block(block) => block + match self { + BlockWrapper::Block(block) => block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)), - BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { Ok(Some(block_sidecar_pair.blobs_sidecar.clone())) } } } pub fn message(&self) -> crate::BeaconBlockRef { - match &self.0 { - BlockWrapperInner::Block(block) => block.message(), - BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { + match self { + BlockWrapper::Block(block) => block.message(), + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.message() } } @@ -123,14 +100,14 @@ impl BlockWrapper { Arc>, Result>>, BlobReconstructionError>, ) { - match self.0 { - BlockWrapperInner::Block(block) => { + match self { + BlockWrapper::Block(block) => { let blobs = block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)); (block, blobs) } - BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { + BlockWrapper::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, blobs_sidecar, @@ -143,18 +120,12 @@ impl BlockWrapper { impl From> for BlockWrapper { fn from(block: SignedBeaconBlock) -> Self { - BlockWrapper(BlockWrapperInner::Block(Arc::new(block))) + BlockWrapper::Block(Arc::new(block)) } } impl From>> for BlockWrapper { fn from(block: Arc>) -> Self { - BlockWrapper(BlockWrapperInner::Block(block)) - } -} - -impl From> for BlockWrapper { - fn from(block: SignedBeaconBlockAndBlobsSidecar) -> Self { - BlockWrapper(BlockWrapperInner::BlockAndBlob(block)) + BlockWrapper::Block(block) } } From 8a70d80a2f55a03fb09e7f5450aeaed699d88f2c Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 28 Dec 2022 10:31:18 -0500 Subject: [PATCH 51/59] Revert "Revert "renames, remove , wrap BlockWrapper enum to make descontruction private"" This reverts commit 1931a442dc004d8664e4d6811d2e8c5bbc259ceb. --- .../beacon_chain/src/block_verification.rs | 2 +- beacon_node/http_api/src/publish_blocks.rs | 41 +++--- .../src/rpc/codec/ssz_snappy.rs | 13 +- .../lighthouse_network/src/rpc/methods.rs | 8 +- .../src/service/api_types.rs | 4 +- .../lighthouse_network/src/service/mod.rs | 2 +- .../network/src/beacon_processor/mod.rs | 4 +- .../beacon_processor/worker/rpc_methods.rs | 4 +- .../beacon_processor/worker/sync_methods.rs | 9 +- beacon_node/network/src/router/processor.rs | 30 ++--- .../network/src/sync/backfill_sync/mod.rs | 2 +- .../src/sync/block_sidecar_coupling.rs | 20 +-- beacon_node/network/src/sync/manager.rs | 118 ++++++++---------- .../network/src/sync/network_context.rs | 97 +++++++------- .../network/src/sync/range_sync/batch.rs | 62 ++------- .../network/src/sync/range_sync/chain.rs | 2 +- .../network/src/sync/range_sync/mod.rs | 4 +- .../network/src/sync/range_sync/range.rs | 6 +- consensus/types/src/signed_block_and_blobs.rs | 71 +++++++---- 19 files changed, 231 insertions(+), 268 deletions(-) diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index c8d3aed7961..2b759e4ad96 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -1141,7 +1141,7 @@ impl IntoExecutionPendingBlock for Arc( // Send the block, regardless of whether or not it is valid. The API // specification is very clear that this is the desired behaviour. - let wrapped_block = if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { - if let Some(sidecar) = chain.blob_cache.pop(&block_root) { - let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { - beacon_block: block, - blobs_sidecar: Arc::new(sidecar), - }; - crate::publish_pubsub_message( - network_tx, - PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), - )?; - BlockWrapper::BlockAndBlob(block_and_blobs) + let wrapped_block: BlockWrapper = + if matches!(block.as_ref(), &SignedBeaconBlock::Eip4844(_)) { + if let Some(sidecar) = chain.blob_cache.pop(&block_root) { + let block_and_blobs = SignedBeaconBlockAndBlobsSidecar { + beacon_block: block, + blobs_sidecar: Arc::new(sidecar), + }; + crate::publish_pubsub_message( + network_tx, + PubsubMessage::BeaconBlockAndBlobsSidecars(block_and_blobs.clone()), + )?; + block_and_blobs.into() + } else { + //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required + return Err(warp_utils::reject::broadcast_without_import(format!( + "no blob cached for block" + ))); + } } else { - //FIXME(sean): This should probably return a specific no-blob-cached error code, beacon API coordination required - return Err(warp_utils::reject::broadcast_without_import(format!( - "no blob cached for block" - ))); - } - } else { - crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; - BlockWrapper::Block(block) - }; + crate::publish_pubsub_message(network_tx, PubsubMessage::BeaconBlock(block.clone()))?; + block.into() + }; // Determine the delay after the start of the slot, register it with metrics. let block = wrapped_block.block(); diff --git a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs index df5350d9494..eb5cc7f27fa 100644 --- a/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs +++ b/beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs @@ -73,7 +73,7 @@ impl Encoder> for SSZSnappyInboundCodec< RPCResponse::BlocksByRange(res) => res.as_ssz_bytes(), RPCResponse::BlocksByRoot(res) => res.as_ssz_bytes(), RPCResponse::BlobsByRange(res) => res.as_ssz_bytes(), - RPCResponse::BlobsByRoot(res) => res.as_ssz_bytes(), + RPCResponse::BlockAndBlobsByRoot(res) => res.as_ssz_bytes(), RPCResponse::LightClientBootstrap(res) => res.as_ssz_bytes(), RPCResponse::Pong(res) => res.data.as_ssz_bytes(), RPCResponse::MetaData(res) => @@ -439,7 +439,8 @@ fn context_bytes( SignedBeaconBlock::Base { .. } => Some(fork_context.genesis_context_bytes()), }; } - if let RPCResponse::BlobsByRange(_) | RPCResponse::BlobsByRoot(_) = rpc_variant { + if let RPCResponse::BlobsByRange(_) | RPCResponse::BlockAndBlobsByRoot(_) = rpc_variant + { return fork_context.to_context_bytes(ForkName::Eip4844); } } @@ -585,7 +586,7 @@ fn handle_v1_response( )))), _ => Err(RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - "Invalid forkname for blobsbyrange".to_string(), + "Invalid fork name for blobs by range".to_string(), )), } } @@ -597,12 +598,12 @@ fn handle_v1_response( ) })?; match fork_name { - ForkName::Eip4844 => Ok(Some(RPCResponse::BlobsByRoot(Arc::new( + ForkName::Eip4844 => Ok(Some(RPCResponse::BlockAndBlobsByRoot( SignedBeaconBlockAndBlobsSidecar::from_ssz_bytes(decoded_buffer)?, - )))), + ))), _ => Err(RPCError::ErrorResponse( RPCResponseErrorCode::InvalidRequest, - "Invalid forkname for blobsbyroot".to_string(), + "Invalid fork name for block and blobs by root".to_string(), )), } } diff --git a/beacon_node/lighthouse_network/src/rpc/methods.rs b/beacon_node/lighthouse_network/src/rpc/methods.rs index 53e6b675990..02e24d8e1d1 100644 --- a/beacon_node/lighthouse_network/src/rpc/methods.rs +++ b/beacon_node/lighthouse_network/src/rpc/methods.rs @@ -281,7 +281,7 @@ pub enum RPCResponse { LightClientBootstrap(LightClientBootstrap), /// A response to a get BLOBS_BY_ROOT request. - BlobsByRoot(Arc>), + BlockAndBlobsByRoot(SignedBeaconBlockAndBlobsSidecar), /// A PONG response to a PING request. Pong(Ping), @@ -372,7 +372,7 @@ impl RPCCodedResponse { RPCResponse::BlocksByRange(_) => true, RPCResponse::BlocksByRoot(_) => true, RPCResponse::BlobsByRange(_) => true, - RPCResponse::BlobsByRoot(_) => true, + RPCResponse::BlockAndBlobsByRoot(_) => true, RPCResponse::Pong(_) => false, RPCResponse::MetaData(_) => false, RPCResponse::LightClientBootstrap(_) => false, @@ -409,7 +409,7 @@ impl RPCResponse { RPCResponse::BlocksByRange(_) => Protocol::BlocksByRange, RPCResponse::BlocksByRoot(_) => Protocol::BlocksByRoot, RPCResponse::BlobsByRange(_) => Protocol::BlobsByRange, - RPCResponse::BlobsByRoot(_) => Protocol::BlobsByRoot, + RPCResponse::BlockAndBlobsByRoot(_) => Protocol::BlobsByRoot, RPCResponse::Pong(_) => Protocol::Ping, RPCResponse::MetaData(_) => Protocol::MetaData, RPCResponse::LightClientBootstrap(_) => Protocol::LightClientBootstrap, @@ -449,7 +449,7 @@ impl std::fmt::Display for RPCResponse { RPCResponse::BlobsByRange(blob) => { write!(f, "BlobsByRange: Blob slot: {}", blob.beacon_block_slot) } - RPCResponse::BlobsByRoot(blob) => { + RPCResponse::BlockAndBlobsByRoot(blob) => { write!( f, "BlobsByRoot: Blob slot: {}", diff --git a/beacon_node/lighthouse_network/src/service/api_types.rs b/beacon_node/lighthouse_network/src/service/api_types.rs index b6a03302008..c9c239d8cf4 100644 --- a/beacon_node/lighthouse_network/src/service/api_types.rs +++ b/beacon_node/lighthouse_network/src/service/api_types.rs @@ -83,7 +83,7 @@ pub enum Response { /// A response to a LightClientUpdate request. LightClientBootstrap(LightClientBootstrap), /// A response to a get BLOBS_BY_ROOT request. - BlobsByRoot(Option>>), + BlobsByRoot(Option>), } impl std::convert::From> for RPCCodedResponse { @@ -98,7 +98,7 @@ impl std::convert::From> for RPCCodedResponse RPCCodedResponse::StreamTermination(ResponseTermination::BlocksByRange), }, Response::BlobsByRoot(r) => match r { - Some(b) => RPCCodedResponse::Success(RPCResponse::BlobsByRoot(b)), + Some(b) => RPCCodedResponse::Success(RPCResponse::BlockAndBlobsByRoot(b)), None => RPCCodedResponse::StreamTermination(ResponseTermination::BlobsByRoot), }, Response::BlobsByRange(r) => match r { diff --git a/beacon_node/lighthouse_network/src/service/mod.rs b/beacon_node/lighthouse_network/src/service/mod.rs index 9adf7699bc2..d59bc4bfd6c 100644 --- a/beacon_node/lighthouse_network/src/service/mod.rs +++ b/beacon_node/lighthouse_network/src/service/mod.rs @@ -1315,7 +1315,7 @@ impl Network { RPCResponse::BlocksByRoot(resp) => { self.build_response(id, peer_id, Response::BlocksByRoot(Some(resp))) } - RPCResponse::BlobsByRoot(resp) => { + RPCResponse::BlockAndBlobsByRoot(resp) => { self.build_response(id, peer_id, Response::BlobsByRoot(Some(resp))) } // Should never be reached diff --git a/beacon_node/network/src/beacon_processor/mod.rs b/beacon_node/network/src/beacon_processor/mod.rs index 9de006c84f5..37d6edef82f 100644 --- a/beacon_node/network/src/beacon_processor/mod.rs +++ b/beacon_node/network/src/beacon_processor/mod.rs @@ -1699,7 +1699,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - BlockWrapper::Block(block), + block.into(), work_reprocessing_tx, duplicate_cache, seen_timestamp, @@ -1721,7 +1721,7 @@ impl BeaconProcessor { message_id, peer_id, peer_client, - BlockWrapper::BlockAndBlob(block_sidecar_pair), + block_sidecar_pair.into(), work_reprocessing_tx, duplicate_cache, seen_timestamp, diff --git a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs index 3ade1bb87b6..69bd7da11c6 100644 --- a/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/rpc_methods.rs @@ -230,10 +230,10 @@ impl Worker { Ok((Some(block), Some(blobs))) => { self.send_response( peer_id, - Response::BlobsByRoot(Some(Arc::new(SignedBeaconBlockAndBlobsSidecar { + Response::BlobsByRoot(Some(SignedBeaconBlockAndBlobsSidecar { beacon_block: block, blobs_sidecar: blobs, - }))), + })), request_id, ); send_block_count += 1; diff --git a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs index 5af62c37de0..b3465c56dc5 100644 --- a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs @@ -188,14 +188,7 @@ impl Worker { let end_slot = downloaded_blocks.last().map(|b| b.slot().as_u64()); let sent_blocks = downloaded_blocks.len(); - let unwrapped = downloaded_blocks - .into_iter() - .map(|block| match block { - BlockWrapper::Block(block) => block, - //FIXME(sean) handle blobs in backfill - BlockWrapper::BlockAndBlob(_) => todo!(), - }) - .collect(); + let unwrapped = downloaded_blocks.into_iter().map(|_| todo!()).collect(); match self.process_backfill_blocks(unwrapped) { (_, Ok(_)) => { diff --git a/beacon_node/network/src/router/processor.rs b/beacon_node/network/src/router/processor.rs index 5ee0e367b68..d0879babacb 100644 --- a/beacon_node/network/src/router/processor.rs +++ b/beacon_node/network/src/router/processor.rs @@ -223,10 +223,10 @@ impl Processor { SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. } => { unreachable!("Block lookups do not request BBRange requests") } - id @ (SyncId::BackFillSync { .. } - | SyncId::RangeSync { .. } - | SyncId::BackFillSidecarPair { .. } - | SyncId::RangeSidecarPair { .. }) => id, + id @ (SyncId::BackFillBlocks { .. } + | SyncId::RangeBlocks { .. } + | SyncId::BackFillBlobs { .. } + | SyncId::RangeBlobs { .. }) => id, }, RequestId::Router => unreachable!("All BBRange requests belong to sync"), }; @@ -258,7 +258,7 @@ impl Processor { ); if let RequestId::Sync(id) = request_id { - self.send_to_sync(SyncMessage::RpcGlob { + self.send_to_sync(SyncMessage::RpcBlobs { peer_id, request_id: id, blob_sidecar, @@ -282,10 +282,10 @@ impl Processor { let request_id = match request_id { RequestId::Sync(sync_id) => match sync_id { id @ (SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. }) => id, - SyncId::BackFillSync { .. } - | SyncId::RangeSync { .. } - | SyncId::RangeSidecarPair { .. } - | SyncId::BackFillSidecarPair { .. } => { + SyncId::BackFillBlocks { .. } + | SyncId::RangeBlocks { .. } + | SyncId::RangeBlobs { .. } + | SyncId::BackFillBlobs { .. } => { unreachable!("Batch syncing do not request BBRoot requests") } }, @@ -310,15 +310,15 @@ impl Processor { &mut self, peer_id: PeerId, request_id: RequestId, - block_and_blobs: Option>>, + block_and_blobs: Option>, ) { let request_id = match request_id { RequestId::Sync(sync_id) => match sync_id { id @ (SyncId::SingleBlock { .. } | SyncId::ParentLookup { .. }) => id, - SyncId::BackFillSync { .. } - | SyncId::RangeSync { .. } - | SyncId::RangeSidecarPair { .. } - | SyncId::BackFillSidecarPair { .. } => { + SyncId::BackFillBlocks { .. } + | SyncId::RangeBlocks { .. } + | SyncId::RangeBlobs { .. } + | SyncId::BackFillBlobs { .. } => { unreachable!("Batch syncing does not request BBRoot requests") } }, @@ -330,7 +330,7 @@ impl Processor { "Received BlockAndBlobssByRoot Response"; "peer" => %peer_id, ); - self.send_to_sync(SyncMessage::RpcBlockAndGlob { + self.send_to_sync(SyncMessage::RpcBlockAndBlobs { peer_id, request_id, block_and_blobs, diff --git a/beacon_node/network/src/sync/backfill_sync/mod.rs b/beacon_node/network/src/sync/backfill_sync/mod.rs index 56ed551530c..ad1bfb1d42d 100644 --- a/beacon_node/network/src/sync/backfill_sync/mod.rs +++ b/beacon_node/network/src/sync/backfill_sync/mod.rs @@ -536,7 +536,7 @@ impl BackFillSync { let process_id = ChainSegmentProcessId::BackSyncBatchId(batch_id); self.current_processing_batch = Some(batch_id); - let work_event = BeaconWorkEvent::chain_segment(process_id, blocks.into_wrapped_blocks()); + let work_event = BeaconWorkEvent::chain_segment(process_id, blocks); if let Err(e) = network.processor_channel().try_send(work_event) { crit!(self.log, "Failed to send backfill segment to processor."; "msg" => "process_batch", "error" => %e, "batch" => self.processing_target); diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index f82417db3a1..46ac5bd0fbd 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -1,12 +1,9 @@ use std::{collections::VecDeque, sync::Arc}; -use types::{ - signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock, - SignedBeaconBlockAndBlobsSidecar, -}; +use types::{signed_block_and_blobs::BlockWrapper, BlobsSidecar, EthSpec, SignedBeaconBlock}; #[derive(Debug, Default)] -pub struct BlockBlobRequestInfo { +pub struct BlocksAndBlobsRequestInfo { /// Blocks we have received awaiting for their corresponding sidecar. accumulated_blocks: VecDeque>>, /// Sidecars we have received awaiting for their corresponding block. @@ -17,7 +14,7 @@ pub struct BlockBlobRequestInfo { is_sidecars_stream_terminated: bool, } -impl BlockBlobRequestInfo { +impl BlocksAndBlobsRequestInfo { pub fn add_block_response(&mut self, maybe_block: Option>>) { match maybe_block { Some(block) => self.accumulated_blocks.push_back(block), @@ -33,7 +30,7 @@ impl BlockBlobRequestInfo { } pub fn into_responses(self) -> Result>, &'static str> { - let BlockBlobRequestInfo { + let BlocksAndBlobsRequestInfo { accumulated_blocks, mut accumulated_sidecars, .. @@ -51,14 +48,9 @@ impl BlockBlobRequestInfo { { let blobs_sidecar = accumulated_sidecars.pop_front().ok_or("missing sidecar")?; - Ok(BlockWrapper::BlockAndBlob( - SignedBeaconBlockAndBlobsSidecar { - beacon_block, - blobs_sidecar, - }, - )) + Ok(BlockWrapper::new_with_blobs(beacon_block, blobs_sidecar)) } else { - Ok(BlockWrapper::Block(beacon_block)) + Ok(beacon_block.into()) } }) .collect::, _>>(); diff --git a/beacon_node/network/src/sync/manager.rs b/beacon_node/network/src/sync/manager.rs index 29838bde713..5da203e0e77 100644 --- a/beacon_node/network/src/sync/manager.rs +++ b/beacon_node/network/src/sync/manager.rs @@ -35,13 +35,13 @@ use super::backfill_sync::{BackFillSync, ProcessResult, SyncStart}; use super::block_lookups::BlockLookups; -use super::network_context::{BlockOrBlob, SyncNetworkContext}; +use super::network_context::{BlockOrBlobs, SyncNetworkContext}; use super::peer_sync_info::{remote_sync_type, PeerSyncType}; use super::range_sync::{RangeSync, RangeSyncType, EPOCHS_PER_BATCH}; use crate::beacon_processor::{ChainSegmentProcessId, WorkEvent as BeaconWorkEvent}; use crate::service::NetworkMessage; use crate::status::ToStatusMessage; -use crate::sync::range_sync::ExpectedBatchTy; +use crate::sync::range_sync::ByRangeRequestType; use beacon_chain::{BeaconChain, BeaconChainTypes, BlockError, EngineState}; use futures::StreamExt; use lighthouse_network::rpc::methods::MAX_REQUEST_BLOCKS; @@ -79,13 +79,13 @@ pub enum RequestId { /// Request searching for a block's parent. The id is the chain ParentLookup { id: Id }, /// Request was from the backfill sync algorithm. - BackFillSync { id: Id }, - /// Backfill request for blocks and sidecars. - BackFillSidecarPair { id: Id }, + BackFillBlocks { id: Id }, + /// Backfill request for blob sidecars. + BackFillBlobs { id: Id }, /// The request was from a chain in the range sync algorithm. - RangeSync { id: Id }, - /// The request was from a chain in range, asking for ranges of blocks and sidecars. - RangeSidecarPair { id: Id }, + RangeBlocks { id: Id }, + /// The request was from a chain in range, asking for ranges blob sidecars. + RangeBlobs { id: Id }, } #[derive(Debug)] @@ -103,7 +103,7 @@ pub enum SyncMessage { }, /// A blob has been received from the RPC. - RpcGlob { + RpcBlobs { request_id: RequestId, peer_id: PeerId, blob_sidecar: Option>>, @@ -111,10 +111,10 @@ pub enum SyncMessage { }, /// A block and blobs have been received from the RPC. - RpcBlockAndGlob { + RpcBlockAndBlobs { request_id: RequestId, peer_id: PeerId, - block_and_blobs: Option>>, + block_and_blobs: Option>, seen_timestamp: Duration, }, @@ -295,10 +295,10 @@ impl SyncManager { self.block_lookups .parent_lookup_failed(id, peer_id, &mut self.network, error); } - RequestId::BackFillSync { id } => { + RequestId::BackFillBlocks { id } => { if let Some(batch_id) = self .network - .backfill_request_failed(id, ExpectedBatchTy::OnlyBlock) + .backfill_request_failed(id, ByRangeRequestType::Blocks) { match self .backfill_sync @@ -310,10 +310,10 @@ impl SyncManager { } } - RequestId::BackFillSidecarPair { id } => { + RequestId::BackFillBlobs { id } => { if let Some(batch_id) = self .network - .backfill_request_failed(id, ExpectedBatchTy::OnlyBlockBlobs) + .backfill_request_failed(id, ByRangeRequestType::BlocksAndBlobs) { match self .backfill_sync @@ -324,10 +324,10 @@ impl SyncManager { } } } - RequestId::RangeSync { id } => { + RequestId::RangeBlocks { id } => { if let Some((chain_id, batch_id)) = self .network - .range_sync_request_failed(id, ExpectedBatchTy::OnlyBlock) + .range_sync_request_failed(id, ByRangeRequestType::Blocks) { self.range_sync.inject_error( &mut self.network, @@ -339,10 +339,10 @@ impl SyncManager { self.update_sync_state() } } - RequestId::RangeSidecarPair { id } => { + RequestId::RangeBlobs { id } => { if let Some((chain_id, batch_id)) = self .network - .range_sync_request_failed(id, ExpectedBatchTy::OnlyBlockBlobs) + .range_sync_request_failed(id, ByRangeRequestType::BlocksAndBlobs) { self.range_sync.inject_error( &mut self.network, @@ -648,18 +648,18 @@ impl SyncManager { .block_lookups .parent_chain_processed(chain_hash, result, &mut self.network), }, - SyncMessage::RpcGlob { + SyncMessage::RpcBlobs { request_id, peer_id, blob_sidecar, seen_timestamp, - } => self.rpc_sidecar_received(request_id, peer_id, blob_sidecar, seen_timestamp), - SyncMessage::RpcBlockAndGlob { + } => self.rpc_blobs_received(request_id, peer_id, blob_sidecar, seen_timestamp), + SyncMessage::RpcBlockAndBlobs { request_id, peer_id, block_and_blobs, seen_timestamp, - } => self.rpc_block_sidecar_pair_received( + } => self.rpc_block_block_and_blobs_received( request_id, peer_id, block_and_blobs, @@ -734,18 +734,18 @@ impl SyncManager { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), seen_timestamp, &mut self.network, ), - RequestId::BackFillSync { id } => { + RequestId::BackFillBlocks { id } => { let is_stream_terminator = beacon_block.is_none(); if let Some(batch_id) = self .network @@ -756,7 +756,7 @@ impl SyncManager { batch_id, &peer_id, id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), ) { Ok(ProcessResult::SyncCompleted) => self.update_sync_state(), Ok(ProcessResult::Successful) => {} @@ -768,7 +768,7 @@ impl SyncManager { } } } - RequestId::RangeSync { id } => { + RequestId::RangeBlocks { id } => { let is_stream_terminator = beacon_block.is_none(); if let Some((chain_id, batch_id)) = self .network @@ -780,28 +780,28 @@ impl SyncManager { chain_id, batch_id, id, - beacon_block.map(|block| BlockWrapper::Block(block)), + beacon_block.map(|block| block.into()), ); self.update_sync_state(); } } - RequestId::BackFillSidecarPair { id } => { - self.block_blob_backfill_response(id, peer_id, beacon_block.into()) + RequestId::BackFillBlobs { id } => { + self.blobs_backfill_response(id, peer_id, beacon_block.into()) } - RequestId::RangeSidecarPair { id } => { - self.block_blob_range_response(id, peer_id, beacon_block.into()) + RequestId::RangeBlobs { id } => { + self.blobs_range_response(id, peer_id, beacon_block.into()) } } } /// Handles receiving a response for a range sync request that should have both blocks and /// blobs. - fn block_blob_range_response( + fn blobs_range_response( &mut self, id: Id, peer_id: PeerId, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) { if let Some((chain_id, batch_id, block_responses)) = self .network @@ -834,7 +834,7 @@ impl SyncManager { "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy - let id = RequestId::RangeSidecarPair { id }; + let id = RequestId::RangeBlobs { id }; self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } @@ -843,11 +843,11 @@ impl SyncManager { /// Handles receiving a response for a Backfill sync request that should have both blocks and /// blobs. - fn block_blob_backfill_response( + fn blobs_backfill_response( &mut self, id: Id, peer_id: PeerId, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) { if let Some((batch_id, block_responses)) = self .network @@ -886,14 +886,14 @@ impl SyncManager { "peer_id" => %peer_id, "batch_id" => batch_id, "error" => e ); // TODO: penalize the peer for being a bad boy - let id = RequestId::BackFillSidecarPair { id }; + let id = RequestId::BackFillBlobs { id }; self.inject_error(peer_id, id, RPCError::InvalidData(e.into())) } } } } - fn rpc_sidecar_received( + fn rpc_blobs_received( &mut self, request_id: RequestId, peer_id: PeerId, @@ -904,57 +904,47 @@ impl SyncManager { RequestId::SingleBlock { .. } | RequestId::ParentLookup { .. } => { unreachable!("There is no such thing as a singular 'by root' glob request that is not accompanied by the block") } - RequestId::BackFillSync { .. } => { + RequestId::BackFillBlocks { .. } => { unreachable!("An only blocks request does not receive sidecars") } - RequestId::BackFillSidecarPair { id } => { - self.block_blob_backfill_response(id, peer_id, maybe_sidecar.into()) + RequestId::BackFillBlobs { id } => { + self.blobs_backfill_response(id, peer_id, maybe_sidecar.into()) } - RequestId::RangeSync { .. } => { + RequestId::RangeBlocks { .. } => { unreachable!("Only-blocks range requests don't receive sidecars") } - RequestId::RangeSidecarPair { id } => { - self.block_blob_range_response(id, peer_id, maybe_sidecar.into()) + RequestId::RangeBlobs { id } => { + self.blobs_range_response(id, peer_id, maybe_sidecar.into()) } } } - fn rpc_block_sidecar_pair_received( + fn rpc_block_block_and_blobs_received( &mut self, request_id: RequestId, peer_id: PeerId, - block_sidecar_pair: Option>>, + block_sidecar_pair: Option>, seen_timestamp: Duration, ) { match request_id { RequestId::SingleBlock { id } => self.block_lookups.single_block_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| { - BlockWrapper::BlockAndBlob( - // TODO: why is this in an arc - (*block_sidecar_pair).clone(), - ) - }), + block_sidecar_pair.map(|block_sidecar_pair| block_sidecar_pair.into()), seen_timestamp, &mut self.network, ), RequestId::ParentLookup { id } => self.block_lookups.parent_lookup_response( id, peer_id, - block_sidecar_pair.map(|block_sidecar_pair| { - BlockWrapper::BlockAndBlob( - // TODO: why is this in an arc - (*block_sidecar_pair).clone(), - ) - }), + block_sidecar_pair.map(|block_sidecar_pair| block_sidecar_pair.into()), seen_timestamp, &mut self.network, ), - RequestId::BackFillSync { .. } - | RequestId::BackFillSidecarPair { .. } - | RequestId::RangeSync { .. } - | RequestId::RangeSidecarPair { .. } => unreachable!( + RequestId::BackFillBlocks { .. } + | RequestId::BackFillBlobs { .. } + | RequestId::RangeBlocks { .. } + | RequestId::RangeBlobs { .. } => unreachable!( "since range requests are not block-glob coupled, this should never be reachable" ), } diff --git a/beacon_node/network/src/sync/network_context.rs b/beacon_node/network/src/sync/network_context.rs index 36da3bf8213..c54b3b1a983 100644 --- a/beacon_node/network/src/sync/network_context.rs +++ b/beacon_node/network/src/sync/network_context.rs @@ -1,9 +1,9 @@ //! Provides network functionality for the Syncing thread. This fundamentally wraps a network //! channel and stores a global RPC ID to perform requests. -use super::block_sidecar_coupling::BlockBlobRequestInfo; +use super::block_sidecar_coupling::BlocksAndBlobsRequestInfo; use super::manager::{Id, RequestId as SyncRequestId}; -use super::range_sync::{BatchId, ChainId, ExpectedBatchTy}; +use super::range_sync::{BatchId, ByRangeRequestType, ChainId}; use crate::beacon_processor::WorkEvent; use crate::service::{NetworkMessage, RequestId}; use crate::status::ToStatusMessage; @@ -38,11 +38,12 @@ pub struct SyncNetworkContext { backfill_requests: FnvHashMap, /// BlocksByRange requests paired with BlobsByRange requests made by the range. - range_sidecar_pair_requests: - FnvHashMap)>, + range_blocks_and_blobs_requests: + FnvHashMap)>, /// BlocksByRange requests paired with BlobsByRange requests made by the backfill sync. - backfill_sidecar_pair_requests: FnvHashMap)>, + backfill_blocks_and_blobs_requests: + FnvHashMap)>, /// Whether the ee is online. If it's not, we don't allow access to the /// `beacon_processor_send`. @@ -58,20 +59,20 @@ pub struct SyncNetworkContext { } /// Small enumeration to make dealing with block and blob requests easier. -pub enum BlockOrBlob { +pub enum BlockOrBlobs { Block(Option>>), - Blob(Option>>), + Blobs(Option>>), } -impl From>>> for BlockOrBlob { +impl From>>> for BlockOrBlobs { fn from(block: Option>>) -> Self { - BlockOrBlob::Block(block) + BlockOrBlobs::Block(block) } } -impl From>>> for BlockOrBlob { +impl From>>> for BlockOrBlobs { fn from(blob: Option>>) -> Self { - BlockOrBlob::Blob(blob) + BlockOrBlobs::Blobs(blob) } } @@ -89,8 +90,8 @@ impl SyncNetworkContext { request_id: 1, range_requests: Default::default(), backfill_requests: Default::default(), - range_sidecar_pair_requests: Default::default(), - backfill_sidecar_pair_requests: Default::default(), + range_blocks_and_blobs_requests: Default::default(), + backfill_blocks_and_blobs_requests: Default::default(), execution_engine_state: EngineState::Online, // always assume `Online` at the start beacon_processor_send, chain, @@ -140,13 +141,13 @@ impl SyncNetworkContext { pub fn blocks_by_range_request( &mut self, peer_id: PeerId, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, request: BlocksByRangeRequest, chain_id: ChainId, batch_id: BatchId, ) -> Result { match batch_type { - ExpectedBatchTy::OnlyBlock => { + ByRangeRequestType::Blocks => { trace!( self.log, "Sending BlocksByRange request"; @@ -156,7 +157,7 @@ impl SyncNetworkContext { ); let request = Request::BlocksByRange(request); let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeSync { id }); + let request_id = RequestId::Sync(SyncRequestId::RangeBlocks { id }); self.send_network_msg(NetworkMessage::SendRequest { peer_id, request, @@ -165,7 +166,7 @@ impl SyncNetworkContext { self.range_requests.insert(id, (chain_id, batch_id)); Ok(id) } - ExpectedBatchTy::OnlyBlockBlobs => { + ByRangeRequestType::BlocksAndBlobs => { debug!( self.log, "Sending BlocksByRange and BlobsByRange requests"; @@ -176,7 +177,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::RangeSidecarPair { id }); + let request_id = RequestId::Sync(SyncRequestId::RangeBlobs { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { @@ -196,8 +197,8 @@ impl SyncNetworkContext { request: blobs_request, request_id, })?; - let block_blob_info = BlockBlobRequestInfo::default(); - self.range_sidecar_pair_requests + let block_blob_info = BlocksAndBlobsRequestInfo::default(); + self.range_blocks_and_blobs_requests .insert(id, (chain_id, batch_id, block_blob_info)); Ok(id) } @@ -208,12 +209,12 @@ impl SyncNetworkContext { pub fn backfill_blocks_by_range_request( &mut self, peer_id: PeerId, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, request: BlocksByRangeRequest, batch_id: BatchId, ) -> Result { match batch_type { - ExpectedBatchTy::OnlyBlock => { + ByRangeRequestType::Blocks => { trace!( self.log, "Sending backfill BlocksByRange request"; @@ -223,7 +224,7 @@ impl SyncNetworkContext { ); let request = Request::BlocksByRange(request); let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::BackFillSync { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillBlocks { id }); self.send_network_msg(NetworkMessage::SendRequest { peer_id, request, @@ -232,7 +233,7 @@ impl SyncNetworkContext { self.backfill_requests.insert(id, batch_id); Ok(id) } - ExpectedBatchTy::OnlyBlockBlobs => { + ByRangeRequestType::BlocksAndBlobs => { debug!( self.log, "Sending backfill BlocksByRange and BlobsByRange requests"; @@ -243,7 +244,7 @@ impl SyncNetworkContext { // create the shared request id. This is fine since the rpc handles substream ids. let id = self.next_id(); - let request_id = RequestId::Sync(SyncRequestId::BackFillSidecarPair { id }); + let request_id = RequestId::Sync(SyncRequestId::BackFillBlobs { id }); // Create the blob request based on the blob request. let blobs_request = Request::BlobsByRange(BlobsByRangeRequest { @@ -263,8 +264,8 @@ impl SyncNetworkContext { request: blobs_request, request_id, })?; - let block_blob_info = BlockBlobRequestInfo::default(); - self.backfill_sidecar_pair_requests + let block_blob_info = BlocksAndBlobsRequestInfo::default(); + self.backfill_blocks_and_blobs_requests .insert(id, (batch_id, block_blob_info)); Ok(id) } @@ -288,18 +289,18 @@ impl SyncNetworkContext { pub fn range_sync_block_and_blob_response( &mut self, request_id: Id, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) -> Option<( ChainId, BatchId, Result>, &'static str>, )> { - match self.range_sidecar_pair_requests.entry(request_id) { + match self.range_blocks_and_blobs_requests.entry(request_id) { Entry::Occupied(mut entry) => { let (_, _, info) = entry.get_mut(); match block_or_blob { - BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), - BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + BlockOrBlobs::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlobs::Blobs(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { // If the request is finished, dequeue everything @@ -316,28 +317,28 @@ impl SyncNetworkContext { pub fn range_sync_request_failed( &mut self, request_id: Id, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, ) -> Option<(ChainId, BatchId)> { match batch_type { - ExpectedBatchTy::OnlyBlockBlobs => self - .range_sidecar_pair_requests + ByRangeRequestType::BlocksAndBlobs => self + .range_blocks_and_blobs_requests .remove(&request_id) .map(|(chain_id, batch_id, _info)| (chain_id, batch_id)), - ExpectedBatchTy::OnlyBlock => self.range_requests.remove(&request_id), + ByRangeRequestType::Blocks => self.range_requests.remove(&request_id), } } pub fn backfill_request_failed( &mut self, request_id: Id, - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, ) -> Option { match batch_type { - ExpectedBatchTy::OnlyBlockBlobs => self - .backfill_sidecar_pair_requests + ByRangeRequestType::BlocksAndBlobs => self + .backfill_blocks_and_blobs_requests .remove(&request_id) .map(|(batch_id, _info)| batch_id), - ExpectedBatchTy::OnlyBlock => self.backfill_requests.remove(&request_id), + ByRangeRequestType::Blocks => self.backfill_requests.remove(&request_id), } } @@ -360,14 +361,14 @@ impl SyncNetworkContext { pub fn backfill_sync_block_and_blob_response( &mut self, request_id: Id, - block_or_blob: BlockOrBlob, + block_or_blob: BlockOrBlobs, ) -> Option<(BatchId, Result>, &'static str>)> { - match self.backfill_sidecar_pair_requests.entry(request_id) { + match self.backfill_blocks_and_blobs_requests.entry(request_id) { Entry::Occupied(mut entry) => { let (_, info) = entry.get_mut(); match block_or_blob { - BlockOrBlob::Block(maybe_block) => info.add_block_response(maybe_block), - BlockOrBlob::Blob(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), + BlockOrBlobs::Block(maybe_block) => info.add_block_response(maybe_block), + BlockOrBlobs::Blobs(maybe_sidecar) => info.add_sidecar_response(maybe_sidecar), } if info.is_finished() { // If the request is finished, dequeue everything @@ -533,7 +534,7 @@ impl SyncNetworkContext { /// Check whether a batch for this epoch (and only this epoch) should request just blocks or /// blocks and blobs. - pub fn batch_type(&self, epoch: types::Epoch) -> ExpectedBatchTy { + pub fn batch_type(&self, epoch: types::Epoch) -> ByRangeRequestType { const _: () = assert!( super::backfill_sync::BACKFILL_EPOCHS_PER_BATCH == 1 && super::range_sync::EPOCHS_PER_BATCH == 1, @@ -542,18 +543,18 @@ impl SyncNetworkContext { #[cfg(test)] { // Keep tests only for blocks. - return ExpectedBatchTy::OnlyBlock; + return ByRangeRequestType::Blocks; } #[cfg(not(test))] { if let Some(data_availability_boundary) = self.chain.data_availability_boundary() { if epoch >= data_availability_boundary { - ExpectedBatchTy::OnlyBlockBlobs + ByRangeRequestType::BlocksAndBlobs } else { - ExpectedBatchTy::OnlyBlock + ByRangeRequestType::Blocks } } else { - ExpectedBatchTy::OnlyBlock + ByRangeRequestType::Blocks } } } diff --git a/beacon_node/network/src/sync/range_sync/batch.rs b/beacon_node/network/src/sync/range_sync/batch.rs index 80f34f8b44f..184dcffc47d 100644 --- a/beacon_node/network/src/sync/range_sync/batch.rs +++ b/beacon_node/network/src/sync/range_sync/batch.rs @@ -4,10 +4,9 @@ use lighthouse_network::PeerId; use std::collections::HashSet; use std::hash::{Hash, Hasher}; use std::ops::Sub; -use std::sync::Arc; use strum::Display; use types::signed_block_and_blobs::BlockWrapper; -use types::{Epoch, EthSpec, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, Slot}; +use types::{Epoch, EthSpec, Slot}; /// The number of times to retry a batch before it is considered failed. const MAX_BATCH_DOWNLOAD_ATTEMPTS: u8 = 5; @@ -16,36 +15,12 @@ const MAX_BATCH_DOWNLOAD_ATTEMPTS: u8 = 5; /// after `MAX_BATCH_PROCESSING_ATTEMPTS` times, it is considered faulty. const MAX_BATCH_PROCESSING_ATTEMPTS: u8 = 3; -pub enum BatchTy { - Blocks(Vec>>), - BlocksAndBlobs(Vec>), -} - -impl BatchTy { - pub fn into_wrapped_blocks(self) -> Vec> { - match self { - BatchTy::Blocks(blocks) => blocks - .into_iter() - .map(|block| BlockWrapper::Block(block)) - .collect(), - BatchTy::BlocksAndBlobs(block_sidecar_pair) => block_sidecar_pair - .into_iter() - .map(|block_sidecar_pair| BlockWrapper::BlockAndBlob(block_sidecar_pair)) - .collect(), - } - } -} - -/// Error representing a batch with mixed block types. -#[derive(Debug)] -pub struct MixedBlockTyErr; - /// Type of expected batch. #[derive(Debug, Copy, Clone, Display)] #[strum(serialize_all = "snake_case")] -pub enum ExpectedBatchTy { - OnlyBlockBlobs, - OnlyBlock, +pub enum ByRangeRequestType { + BlocksAndBlobs, + Blocks, } /// Allows customisation of the above constants used in other sync methods such as BackFillSync. @@ -131,7 +106,7 @@ pub struct BatchInfo { /// State of the batch. state: BatchState, /// Whether this batch contains all blocks or all blocks and blobs. - batch_type: ExpectedBatchTy, + batch_type: ByRangeRequestType, /// Pin the generic marker: std::marker::PhantomData, } @@ -180,7 +155,7 @@ impl BatchInfo { /// fork boundary will be of mixed type (all blocks and one last blockblob), and I don't want to /// deal with this for now. /// This means finalization might be slower in eip4844 - pub fn new(start_epoch: &Epoch, num_of_epochs: u64, batch_type: ExpectedBatchTy) -> Self { + pub fn new(start_epoch: &Epoch, num_of_epochs: u64, batch_type: ByRangeRequestType) -> Self { let start_slot = start_epoch.start_slot(T::slots_per_epoch()); let end_slot = start_slot + num_of_epochs * T::slots_per_epoch(); BatchInfo { @@ -243,7 +218,7 @@ impl BatchInfo { } /// Returns a BlocksByRange request associated with the batch. - pub fn to_blocks_by_range_request(&self) -> (BlocksByRangeRequest, ExpectedBatchTy) { + pub fn to_blocks_by_range_request(&self) -> (BlocksByRangeRequest, ByRangeRequestType) { ( BlocksByRangeRequest { start_slot: self.start_slot.into(), @@ -408,30 +383,11 @@ impl BatchInfo { } } - pub fn start_processing(&mut self) -> Result, WrongState> { + pub fn start_processing(&mut self) -> Result>, WrongState> { match self.state.poison() { BatchState::AwaitingProcessing(peer, blocks) => { self.state = BatchState::Processing(Attempt::new::(peer, &blocks)); - match self.batch_type { - ExpectedBatchTy::OnlyBlockBlobs => { - let blocks = blocks.into_iter().map(|block| { - let BlockWrapper::BlockAndBlob(block_and_blob) = block else { - panic!("Batches should never have a mixed type. This is a bug. Contact D") - }; - block_and_blob - }).collect(); - Ok(BatchTy::BlocksAndBlobs(blocks)) - } - ExpectedBatchTy::OnlyBlock => { - let blocks = blocks.into_iter().map(|block| { - let BlockWrapper::Block(block) = block else { - panic!("Batches should never have a mixed type. This is a bug. Contact D") - }; - block - }).collect(); - Ok(BatchTy::Blocks(blocks)) - } - } + Ok(blocks) } BatchState::Poisoned => unreachable!("Poisoned batch"), other => { diff --git a/beacon_node/network/src/sync/range_sync/chain.rs b/beacon_node/network/src/sync/range_sync/chain.rs index 89e120050ed..d60de322467 100644 --- a/beacon_node/network/src/sync/range_sync/chain.rs +++ b/beacon_node/network/src/sync/range_sync/chain.rs @@ -332,7 +332,7 @@ impl SyncingChain { let process_id = ChainSegmentProcessId::RangeBatchId(self.id, batch_id, count_unrealized); self.current_processing_batch = Some(batch_id); - let work_event = BeaconWorkEvent::chain_segment(process_id, blocks.into_wrapped_blocks()); + let work_event = BeaconWorkEvent::chain_segment(process_id, blocks); if let Err(e) = beacon_processor_send.try_send(work_event) { crit!(self.log, "Failed to send chain segment to processor."; "msg" => "process_batch", diff --git a/beacon_node/network/src/sync/range_sync/mod.rs b/beacon_node/network/src/sync/range_sync/mod.rs index 28426032191..d0f2f9217eb 100644 --- a/beacon_node/network/src/sync/range_sync/mod.rs +++ b/beacon_node/network/src/sync/range_sync/mod.rs @@ -9,8 +9,8 @@ mod range; mod sync_type; pub use batch::{ - BatchConfig, BatchInfo, BatchOperationOutcome, BatchProcessingResult, BatchState, BatchTy, - ExpectedBatchTy, + BatchConfig, BatchInfo, BatchOperationOutcome, BatchProcessingResult, BatchState, + ByRangeRequestType, }; pub use chain::{BatchId, ChainId, EPOCHS_PER_BATCH}; pub use range::RangeSync; diff --git a/beacon_node/network/src/sync/range_sync/range.rs b/beacon_node/network/src/sync/range_sync/range.rs index 1e3474fa5af..09d93b0e8f3 100644 --- a/beacon_node/network/src/sync/range_sync/range.rs +++ b/beacon_node/network/src/sync/range_sync/range.rs @@ -373,7 +373,7 @@ where #[cfg(test)] mod tests { use crate::service::RequestId; - use crate::sync::range_sync::ExpectedBatchTy; + use crate::sync::range_sync::ByRangeRequestType; use crate::NetworkMessage; use super::*; @@ -686,7 +686,7 @@ mod tests { let (peer1, local_info, head_info) = rig.head_peer(); range.add_peer(&mut rig.cx, local_info, peer1, head_info); let ((chain1, batch1), id1) = match rig.grab_request(&peer1).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { + RequestId::Sync(crate::sync::manager::RequestId::RangeBlocks { id }) => { (rig.cx.range_sync_response(id, true).unwrap(), id) } other => panic!("unexpected request {:?}", other), @@ -705,7 +705,7 @@ mod tests { let (peer2, local_info, finalized_info) = rig.finalized_peer(); range.add_peer(&mut rig.cx, local_info, peer2, finalized_info); let ((chain2, batch2), id2) = match rig.grab_request(&peer2).0 { - RequestId::Sync(crate::sync::manager::RequestId::RangeSync { id }) => { + RequestId::Sync(crate::sync::manager::RequestId::RangeBlocks { id }) => { (rig.cx.range_sync_response(id, true).unwrap(), id) } other => panic!("unexpected request {:?}", other), diff --git a/consensus/types/src/signed_block_and_blobs.rs b/consensus/types/src/signed_block_and_blobs.rs index f21545f2783..c589fbcfeb9 100644 --- a/consensus/types/src/signed_block_and_blobs.rs +++ b/consensus/types/src/signed_block_and_blobs.rs @@ -34,33 +34,56 @@ impl SignedBeaconBlockAndBlobsSidecar { } } +/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. This newtype +/// wraps the `BlockWrapperInner` to ensure blobs cannot be accessed via an enum match. This would +/// circumvent empty blob reconstruction when accessing blobs. +#[derive(Clone, Debug, Derivative)] +#[derivative(PartialEq, Hash(bound = "T: EthSpec"))] +pub struct BlockWrapper(BlockWrapperInner); + /// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. #[derive(Clone, Debug, Derivative)] #[derivative(PartialEq, Hash(bound = "T: EthSpec"))] -pub enum BlockWrapper { +pub enum BlockWrapperInner { Block(Arc>), BlockAndBlob(SignedBeaconBlockAndBlobsSidecar), } impl BlockWrapper { + pub fn new(block: Arc>) -> Self { + Self(BlockWrapperInner::Block(block)) + } + + pub fn new_with_blobs( + beacon_block: Arc>, + blobs_sidecar: Arc>, + ) -> Self { + Self(BlockWrapperInner::BlockAndBlob( + SignedBeaconBlockAndBlobsSidecar { + beacon_block, + blobs_sidecar, + }, + )) + } + pub fn slot(&self) -> Slot { - match self { - BlockWrapper::Block(block) => block.slot(), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + match &self.0 { + BlockWrapperInner::Block(block) => block.slot(), + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.slot() } } } pub fn block(&self) -> &SignedBeaconBlock { - match self { - BlockWrapper::Block(block) => &block, - BlockWrapper::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, + match &self.0 { + BlockWrapperInner::Block(block) => &block, + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block, } } pub fn block_cloned(&self) -> Arc> { - match self { - BlockWrapper::Block(block) => block.clone(), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + match &self.0 { + BlockWrapperInner::Block(block) => block.clone(), + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.clone() } } @@ -70,20 +93,20 @@ impl BlockWrapper { &self, block_root: Option, ) -> Result>>, BlobReconstructionError> { - match self { - BlockWrapper::Block(block) => block + match &self.0 { + BlockWrapperInner::Block(block) => block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { Ok(Some(block_sidecar_pair.blobs_sidecar.clone())) } } } pub fn message(&self) -> crate::BeaconBlockRef { - match self { - BlockWrapper::Block(block) => block.message(), - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + match &self.0 { + BlockWrapperInner::Block(block) => block.message(), + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { block_sidecar_pair.beacon_block.message() } } @@ -100,14 +123,14 @@ impl BlockWrapper { Arc>, Result>>, BlobReconstructionError>, ) { - match self { - BlockWrapper::Block(block) => { + match self.0 { + BlockWrapperInner::Block(block) => { let blobs = block .reconstruct_empty_blobs(block_root) .map(|blob_opt| blob_opt.map(Arc::new)); (block, blobs) } - BlockWrapper::BlockAndBlob(block_sidecar_pair) => { + BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => { let SignedBeaconBlockAndBlobsSidecar { beacon_block, blobs_sidecar, @@ -120,12 +143,18 @@ impl BlockWrapper { impl From> for BlockWrapper { fn from(block: SignedBeaconBlock) -> Self { - BlockWrapper::Block(Arc::new(block)) + BlockWrapper(BlockWrapperInner::Block(Arc::new(block))) } } impl From>> for BlockWrapper { fn from(block: Arc>) -> Self { - BlockWrapper::Block(block) + BlockWrapper(BlockWrapperInner::Block(block)) + } +} + +impl From> for BlockWrapper { + fn from(block: SignedBeaconBlockAndBlobsSidecar) -> Self { + BlockWrapper(BlockWrapperInner::BlockAndBlob(block)) } } From 6d859305201a85c7a4faa372869cc115eaa18a72 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Wed, 28 Dec 2022 11:11:17 -0500 Subject: [PATCH 52/59] create automatic docker build for eip4844 --- .github/workflows/docker.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c0a02adf4ed..ffd15c789f9 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -6,6 +6,7 @@ on: - unstable - stable - capella + - eip4844 tags: - v* @@ -40,6 +41,11 @@ jobs: run: | echo "VERSION=capella" >> $GITHUB_ENV echo "VERSION_SUFFIX=" >> $GITHUB_ENV + - name: Extract version (if eip4844) + if: github.event.ref == 'refs/heads/eip4844' + run: | + echo "VERSION=eip4844" >> $GITHUB_ENV + echo "VERSION_SUFFIX=" >> $GITHUB_ENV - name: Extract version (if tagged release) if: startsWith(github.event.ref, 'refs/tags') run: | From 40c6daa34b44924864f72ce63f1b9826557e2873 Mon Sep 17 00:00:00 2001 From: sean Date: Wed, 28 Dec 2022 18:27:21 +0000 Subject: [PATCH 53/59] add pawan's suggestsion --- .../network/src/beacon_processor/worker/sync_methods.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs index b3465c56dc5..284f96da7ca 100644 --- a/beacon_node/network/src/beacon_processor/worker/sync_methods.rs +++ b/beacon_node/network/src/beacon_processor/worker/sync_methods.rs @@ -188,7 +188,11 @@ impl Worker { let end_slot = downloaded_blocks.last().map(|b| b.slot().as_u64()); let sent_blocks = downloaded_blocks.len(); - let unwrapped = downloaded_blocks.into_iter().map(|_| todo!()).collect(); + let unwrapped = downloaded_blocks + .into_iter() + //FIXME(sean) handle blobs in backfill + .map(|block| block.block_cloned()) + .collect(); match self.process_backfill_blocks(unwrapped) { (_, Ok(_)) => { From 31ba05187922239ae315f13acbd4c45b6be15b48 Mon Sep 17 00:00:00 2001 From: sean Date: Wed, 28 Dec 2022 18:34:28 +0000 Subject: [PATCH 54/59] add clang to dockerfile --- Dockerfile | 2 +- lcli/Dockerfile | 2 +- testing/antithesis/Dockerfile.libvoidstar | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7a0602a2213..a4779447be5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM rust:1.65.0-bullseye AS builder -RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake libclang-dev protobuf-compiler +RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake clang libclang-dev protobuf-compiler COPY . lighthouse ARG FEATURES ENV FEATURES $FEATURES diff --git a/lcli/Dockerfile b/lcli/Dockerfile index feda81d0302..5a83a9dc85a 100644 --- a/lcli/Dockerfile +++ b/lcli/Dockerfile @@ -2,7 +2,7 @@ # - from the `lighthouse` dir with the command: `docker build -f ./lcli/Dockerflie .` # - from the current directory with the command: `docker build -f ./Dockerfile ../` FROM rust:1.65.0-bullseye AS builder -RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake libclang-dev protobuf-compiler +RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake clang libclang-dev protobuf-compiler COPY . lighthouse ARG PORTABLE ENV PORTABLE $PORTABLE diff --git a/testing/antithesis/Dockerfile.libvoidstar b/testing/antithesis/Dockerfile.libvoidstar index 32e2d5648df..a92bf6dbd6b 100644 --- a/testing/antithesis/Dockerfile.libvoidstar +++ b/testing/antithesis/Dockerfile.libvoidstar @@ -1,5 +1,5 @@ FROM rust:1.62.1-bullseye AS builder -RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake libclang-dev +RUN apt-get update && apt-get -y upgrade && apt-get install -y cmake clang libclang-dev COPY . lighthouse # Build lighthouse directly with a cargo build command, bypassing the Makefile. From c47a0ade22a10a2bb13844df7d74e9de7b374e47 Mon Sep 17 00:00:00 2001 From: Pawan Dhananjay Date: Thu, 29 Dec 2022 16:42:26 +0530 Subject: [PATCH 55/59] Fix config values for devnet 3; add more bootnodes --- .../built_in_network_configs/eip4844/boot_enr.yaml | 1 + .../built_in_network_configs/eip4844/config.yaml | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml index 143387543b8..89979814756 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/boot_enr.yaml @@ -1,3 +1,4 @@ - enr:-MK4QFnkGjrt5qw5Ct5XXT9QYvfqmH8Cf6xqKuczTHWixDUZQmngyLrlftv-tMRbXDAxZZQDxNciNTjx7XpW0G4yQguGAYU2Pmnxh2F0dG5ldHOIAAAAAAAAAACEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCJ5ITWJc2VjcDI1NmsxoQIlwaxycUgJ_Ht4lYdDlInbIuRxu0HcHcFbu0D7As2SLYhzeW5jbmV0cwCDdGNwgjLIg3VkcIIu4A - enr:-MK4QBqN5McD5YYgfEnfQjWUvrSaCITjBvQevlP5q0nCVbKuZRoa2XvGWOBwTDQyLNYiqgeettVwXs0PrSc1rOY2rjKGAYU2M7A8h2F0dG5ldHOIAAAAAAAAAgCEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCJ6vpeJc2VjcDI1NmsxoQNJzjxNKr7-a-iEDs0KvaL_vo1UH91kefEiWzgAdwSntYhzeW5jbmV0cw-DdGNwgjLIg3VkcIIu4A - enr:-MK4QEzb6r0hpSyiko9u-mbEX1TzdTD9RcSiU4jhey5jJbTAHLdXNFR32CfjingVa6QMyCPtZRUfzSGbJ0ur3-Pdxe-GAYU2OwM5h2F0dG5ldHOIAAAAAAAAAACEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCPi7faJc2VjcDI1NmsxoQIKBTGU_riCSYrscdRCLuocbNzhF9RTNItPfD4_PmYngIhzeW5jbmV0cwCDdGNwgjLIg3VkcIIu4A +- enr:-MK4QPnKUgY_13LlQBxPZsM49owul_gFUb0CxvGDZGkMnZixO1P_imfgFUCPJXOp-k4f3-t2reL8yr53h-ZwlCetaXKGAYU64CTsh2F0dG5ldHOIAAAAAAAAAACEZXRoMpA3FbaXIAAAk___________gmlkgnY0gmlwhCJ5ITWJc2VjcDI1NmsxoQIlwaxycUgJ_Ht4lYdDlInbIuRxu0HcHcFbu0D7As2SLYhzeW5jbmV0cwCDdGNwgjLIg3VkcIIu4A diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml index d5e18559162..b2a5b98111d 100644 --- a/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/eip4844/config.yaml @@ -12,11 +12,9 @@ TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 # --------------------------------------------------------------- # The genesis fork version looks weird for legacy reasons MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 2 -# Dec 1, 2020, 12pm UTC -MIN_GENESIS_TIME: 1606824000 +MIN_GENESIS_TIME: 1671528489 GENESIS_FORK_VERSION: 0x00000ffd -# 604800 seconds (7 days) -GENESIS_DELAY: 604800 +GENESIS_DELAY: 0 # Forking # --------------------------------------------------------------- From e63cf80040ba9f43af68da20544fa311385cbb38 Mon Sep 17 00:00:00 2001 From: Pawan Dhananjay Date: Thu, 29 Dec 2022 16:42:46 +0530 Subject: [PATCH 56/59] Update c-kzg version --- Cargo.lock | 2 +- crypto/kzg/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c9a52ba3ab..b808170999f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,7 +721,7 @@ dependencies = [ [[package]] name = "c-kzg" version = "0.1.0" -source = "git+https://github.com/pawanjay176/c-kzg-4844?rev=48c048b12a7d29ae3e7bf09000e07870da4cb701#48c048b12a7d29ae3e7bf09000e07870da4cb701" +source = "git+https://github.com/pawanjay176/c-kzg-4844?rev=69bde8f4e0bbf0da30d92601b7db138bdd7e6a04#69bde8f4e0bbf0da30d92601b7db138bdd7e6a04" dependencies = [ "hex", "libc", diff --git a/crypto/kzg/Cargo.toml b/crypto/kzg/Cargo.toml index aff195310d4..69b91571db5 100644 --- a/crypto/kzg/Cargo.toml +++ b/crypto/kzg/Cargo.toml @@ -18,7 +18,7 @@ eth2_serde_utils = "0.1.1" hex = "0.4.2" eth2_hashing = "0.3.0" ethereum-types = "0.12.1" -c-kzg = {git = "https://github.com/pawanjay176/c-kzg-4844", rev = "48c048b12a7d29ae3e7bf09000e07870da4cb701" } +c-kzg = {git = "https://github.com/pawanjay176/c-kzg-4844", rev = "69bde8f4e0bbf0da30d92601b7db138bdd7e6a04" } [features] default = ["mainnet-spec"] From 2734f3f9db015b285f7dfaf5b3605af49c62cb1b Mon Sep 17 00:00:00 2001 From: Pawan Dhananjay Date: Thu, 29 Dec 2022 20:34:23 +0530 Subject: [PATCH 57/59] Fix devnet3 genesis.ssz.zip --- .../eip4844/genesis.ssz.zip | Bin 3514 -> 3544 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/common/eth2_network_config/built_in_network_configs/eip4844/genesis.ssz.zip b/common/eth2_network_config/built_in_network_configs/eip4844/genesis.ssz.zip index 06c1b45fdcc2cde730587ba28932b174f0ee21a4..35e5f8b59cdb60daf884076f16c304d02c6da42f 100644 GIT binary patch delta 914 zcmdlbeM8zZz?+#xgnR+YJ4v$FT`&ycLYess&3g_Yq1>5cXYtJwj;nb%{Zh+n^{BVswt}e=!1Wc+Eap zfRTmSCW&z}Bcpx&j`fjqSJ*$B7#aF8(b4t4TJ7>!jsE*Qs&#$ z=FIb##Mw@iD0@Ej`0V*I)2~-N>Y4I!Y2(rJ?U&}wow4C>*^5Vi^o^sAP4D%MD|-L> zmS?Y9yU-{0_gqJK=f}Rk?{xM5hE%^CgPM~Kp$C1-l^<7|y^h_m>)XS6@5e>l#_3!8 z?p1udZ2tVdt;Ek?tzFBz?nO+En`^nmMxbiZ-BWh8Ubm*VY8^X%X3j2ymG^&kJhI)m zFp+!v@-x!=)*O4dw4ATk_w9{WMbEZB_b>I;w6QT(e_Qo(%}f2|Pq+8>&nT~ay5QA@ zT-j6HYDaYT{YpOB(WcLOO(eYZP2rdNU+HgOf4Nt+>ZG{6&i$G3`ny+zmwjT_y(f9k zZt<~)xtx-o%>KRe;wn~O?p1bv|Mk|y+p7aVI7GZ&W9rX0OJJkMr?hvy^R8Q&Nn4t} z`*AycS4p0rg!K1YYsK~7`bkavdilin+4WPxckX;S#f_V7+M5+pAM#4-DtZrhue-zX zY|ZWZc#E{!|8G1`E;V$GZQj0lm7Mgf&tX;liuX-#L|$5+oBF4PIe5|XvTjM+Wqzj* zbmg_Pv3eKt=}CV3ICF1raM0~<|MzWrx}|4+@n^sE{S)?VJNA&h{r|>#<^XSYj(-pT z`v~wdFo3c^fHxzP2s0vkK;D0STfPlp?=+2v-KNJ$h>-eX^Y|c1p)2PJ~#wD^O`<;*1DA$>r&Z;1b65^ zoPM8QZk|5>dHbw~$2uE-&x+&OqLX7+5?67uHU6~Fx_KF!>(Bi9;A@h9d6VV0PGZS9xueX4nu0ozOJuI{S+8-8WWZl*H5&56u^ z7^6N2Xuo!0U1e2z+u-Z%7xP4eA1%9fbHf71>Cg9_;8!)v5!t&n%k}5G;^No;YiHX% zow;7y{C&6g?LCS9hxeIh_o>A7WE2-wW?j4a?>OK0Jw?Cz>^v3Y`_buJBX1}+GdS=J( zmHc7y^;PGQ4c6;z?tOaF@@LuP^rb#J+&Z;(Q@*`<((-n@v$%NO)QeX8YHB`hs=j~4 zH_OOuN`OI0xI*5OJ8b_&SN)u>`#Guk;c2#1HuJl^J@4->%755i%3mKpYeM)G)8)Be zj%}X5cjt$92Txqr53vjVCP!;4P7)xW=Lzm1SvHAlj@`q!f+jL((5z8z_E z)44ZqQ^J$3sP^giElupU7SBE%d4I0`RokU6KD@cJ<#lRt+P*nq7wqhk4nDo=oONhh z=_-vmBAdUw@?W}GYQIQCaM0bI*Duz;o?pJ^dim>>Y4QJd6s0>h&v|5Lc~X8$ReH+t zo~ZWiswpbGcBW-%7uV{U_wnq%p6(tuU+o}sV(#YaHkK(tM<$(^U1?qw|N2hSmoGaW z=g)t6ZEI*k&7JJ+aeKB{XNG(`zxaOs&%(N^&z@bLr6U!yYjM?u-4|IOZspV8S)@E; zcV2z{#T{RniEFzJJ#+0pw6D5mY*cshwEf)APM>Z?wad%crTpg$@MdI^W5$&Y wBp9H;fniA_h>4ObSRuKhw1S&~k>v$50|S@{@MdKLDP;u0Kp-6q%v1~v0K$=_QUCw| From c4a41e8f5552cc760f8d9c90353e0a190b1c0a09 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Thu, 29 Dec 2022 11:07:22 -0500 Subject: [PATCH 58/59] only use withdrawals-processing in docker build on capella --- .github/workflows/docker.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ffd15c789f9..155d3182ef2 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -41,6 +41,7 @@ jobs: run: | echo "VERSION=capella" >> $GITHUB_ENV echo "VERSION_SUFFIX=" >> $GITHUB_ENV + echo "CROSS_FEATURES=withdrawals-processing" >> $GITHUB_ENV - name: Extract version (if eip4844) if: github.event.ref == 'refs/heads/eip4844' run: | @@ -54,6 +55,7 @@ jobs: outputs: VERSION: ${{ env.VERSION }} VERSION_SUFFIX: ${{ env.VERSION_SUFFIX }} + CROSS_FEATURES: ${{ env.CROSS_FEATURES }} build-docker-single-arch: name: build-docker-${{ matrix.binary }} runs-on: ubuntu-22.04 @@ -72,7 +74,7 @@ jobs: DOCKER_CLI_EXPERIMENTAL: enabled VERSION: ${{ needs.extract-version.outputs.VERSION }} VERSION_SUFFIX: ${{ needs.extract-version.outputs.VERSION_SUFFIX }} - CROSS_FEATURES: withdrawals-processing + CROSS_FEATURES: ${{ needs.extract-version.outputs.CROSS_FEATURES }} steps: - uses: actions/checkout@v3 - name: Update Rust From 786d9834f572fdf546604ebf5612ce2c3dd2e1c9 Mon Sep 17 00:00:00 2001 From: realbigsean Date: Tue, 3 Jan 2023 09:25:02 -0500 Subject: [PATCH 59/59] sym link clang in cross dockerfile --- scripts/cross/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cross/Dockerfile b/scripts/cross/Dockerfile index 5472b980bad..cee4b74d9df 100644 --- a/scripts/cross/Dockerfile +++ b/scripts/cross/Dockerfile @@ -9,6 +9,6 @@ RUN apt-get install -y unzip && \ unzip protoc.zip -d /usr && \ chmod +x /usr/bin/protoc -RUN apt-get install -y cmake clang-3.9 +RUN apt-get install -y cmake clang-3.9 && ln -s ../lib/llvm-3.9/bin/clang /usr/bin/clang ENV PROTOC=/usr/bin/protoc