mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 03:31:45 +00:00
Merge unstable 20230925 into deneb-free-blobs.
This commit is contained in:
@@ -10,15 +10,14 @@ use eth2::{
|
||||
types::{BlockId as CoreBlockId, ForkChoiceNode, StateId as CoreStateId, *},
|
||||
BeaconNodeHttpClient, Error, StatusCode, Timeouts,
|
||||
};
|
||||
use execution_layer::test_utils::TestingBuilder;
|
||||
use execution_layer::test_utils::DEFAULT_BUILDER_THRESHOLD_WEI;
|
||||
use execution_layer::test_utils::{
|
||||
Operation, DEFAULT_BUILDER_PAYLOAD_VALUE_WEI, DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI,
|
||||
MockBuilder, Operation, DEFAULT_BUILDER_PAYLOAD_VALUE_WEI, DEFAULT_BUILDER_THRESHOLD_WEI,
|
||||
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI,
|
||||
};
|
||||
use futures::stream::{Stream, StreamExt};
|
||||
use futures::FutureExt;
|
||||
use http_api::{
|
||||
test_utils::{create_api_server, create_api_server_on_port, ApiServer},
|
||||
test_utils::{create_api_server, ApiServer},
|
||||
BlockId, StateId,
|
||||
};
|
||||
use lighthouse_network::{Enr, EnrExt, PeerId};
|
||||
@@ -73,7 +72,7 @@ struct ApiTester {
|
||||
network_rx: NetworkReceivers<E>,
|
||||
local_enr: Enr,
|
||||
external_peer_id: PeerId,
|
||||
mock_builder: Option<Arc<TestingBuilder<E>>>,
|
||||
mock_builder: Option<Arc<MockBuilder<E>>>,
|
||||
}
|
||||
|
||||
struct ApiTesterConfig {
|
||||
@@ -120,24 +119,28 @@ impl ApiTester {
|
||||
}
|
||||
|
||||
pub async fn new_from_config(config: ApiTesterConfig) -> Self {
|
||||
// Get a random unused port
|
||||
let spec = config.spec;
|
||||
let port = unused_port::unused_tcp4_port().unwrap();
|
||||
let beacon_url = SensitiveUrl::parse(format!("http://127.0.0.1:{port}").as_str()).unwrap();
|
||||
|
||||
let harness = Arc::new(
|
||||
BeaconChainHarness::builder(MainnetEthSpec)
|
||||
.spec(spec.clone())
|
||||
.chain_config(ChainConfig {
|
||||
reconstruct_historic_states: config.retain_historic_states,
|
||||
..ChainConfig::default()
|
||||
})
|
||||
.logger(logging::test_logger())
|
||||
.deterministic_keypairs(VALIDATOR_COUNT)
|
||||
.fresh_ephemeral_store()
|
||||
.mock_execution_layer_with_builder(beacon_url.clone(), config.builder_threshold)
|
||||
.build(),
|
||||
);
|
||||
let mut harness = BeaconChainHarness::builder(MainnetEthSpec)
|
||||
.spec(spec.clone())
|
||||
.chain_config(ChainConfig {
|
||||
reconstruct_historic_states: config.retain_historic_states,
|
||||
..ChainConfig::default()
|
||||
})
|
||||
.logger(logging::test_logger())
|
||||
.deterministic_keypairs(VALIDATOR_COUNT)
|
||||
.fresh_ephemeral_store()
|
||||
.mock_execution_layer_with_config()
|
||||
.build();
|
||||
|
||||
harness
|
||||
.mock_execution_layer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.server
|
||||
.execution_block_generator()
|
||||
.move_to_terminal_block()
|
||||
.unwrap();
|
||||
|
||||
harness.advance_slot();
|
||||
|
||||
@@ -247,29 +250,40 @@ impl ApiTester {
|
||||
|
||||
let ApiServer {
|
||||
server,
|
||||
listening_socket: _,
|
||||
listening_socket,
|
||||
network_rx,
|
||||
local_enr,
|
||||
external_peer_id,
|
||||
} = create_api_server_on_port(chain.clone(), &harness.runtime, log, port).await;
|
||||
} = create_api_server(chain.clone(), &harness.runtime, log).await;
|
||||
|
||||
harness.runtime.task_executor.spawn(server, "api_server");
|
||||
|
||||
// Late-initalize the mock builder now that the mock execution node and beacon API ports
|
||||
// have been allocated.
|
||||
let beacon_api_port = listening_socket.port();
|
||||
let beacon_url =
|
||||
SensitiveUrl::parse(format!("http://127.0.0.1:{beacon_api_port}").as_str()).unwrap();
|
||||
let mock_builder_server = harness.set_mock_builder(beacon_url.clone());
|
||||
|
||||
// Start the mock builder service prior to building the chain out.
|
||||
harness.runtime.task_executor.spawn(
|
||||
async move {
|
||||
if let Err(e) = mock_builder_server.await {
|
||||
panic!("error in mock builder server: {e:?}");
|
||||
}
|
||||
},
|
||||
"mock_builder_server",
|
||||
);
|
||||
|
||||
let mock_builder = harness.mock_builder.clone();
|
||||
|
||||
let client = BeaconNodeHttpClient::new(
|
||||
beacon_url,
|
||||
Timeouts::set_all(Duration::from_secs(SECONDS_PER_SLOT)),
|
||||
);
|
||||
|
||||
let builder_ref = harness.mock_builder.as_ref().unwrap().clone();
|
||||
harness.runtime.task_executor.spawn(
|
||||
async move { builder_ref.run().await },
|
||||
"mock_builder_server",
|
||||
);
|
||||
|
||||
let mock_builder = harness.mock_builder.clone();
|
||||
|
||||
Self {
|
||||
harness,
|
||||
harness: Arc::new(harness),
|
||||
chain,
|
||||
client,
|
||||
next_block,
|
||||
@@ -383,7 +397,6 @@ impl ApiTester {
|
||||
.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_BUILDER_THRESHOLD_WEI,
|
||||
)));
|
||||
@@ -406,7 +419,6 @@ impl ApiTester {
|
||||
.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_BUILDER_PAYLOAD_VALUE_WEI,
|
||||
)));
|
||||
@@ -2528,6 +2540,70 @@ impl ApiTester {
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn test_block_production_ssz(self) -> Self {
|
||||
let fork = self.chain.canonical_head.cached_head().head_fork();
|
||||
let genesis_validators_root = self.chain.genesis_validators_root;
|
||||
|
||||
for _ in 0..E::slots_per_epoch() * 3 {
|
||||
let slot = self.chain.slot().unwrap();
|
||||
let epoch = self.chain.epoch().unwrap();
|
||||
|
||||
let proposer_pubkey_bytes = self
|
||||
.client
|
||||
.get_validator_duties_proposer(epoch)
|
||||
.await
|
||||
.unwrap()
|
||||
.data
|
||||
.into_iter()
|
||||
.find(|duty| duty.slot == slot)
|
||||
.map(|duty| duty.pubkey)
|
||||
.unwrap();
|
||||
let proposer_pubkey = (&proposer_pubkey_bytes).try_into().unwrap();
|
||||
|
||||
let sk = self
|
||||
.validator_keypairs()
|
||||
.iter()
|
||||
.find(|kp| kp.pk == proposer_pubkey)
|
||||
.map(|kp| kp.sk.clone())
|
||||
.unwrap();
|
||||
|
||||
let randao_reveal = {
|
||||
let domain = self.chain.spec.get_domain(
|
||||
epoch,
|
||||
Domain::Randao,
|
||||
&fork,
|
||||
genesis_validators_root,
|
||||
);
|
||||
let message = epoch.signing_root(domain);
|
||||
sk.sign(message).into()
|
||||
};
|
||||
|
||||
let block_bytes = self
|
||||
.client
|
||||
.get_validator_blocks_ssz::<E, FullPayload<E>>(slot, &randao_reveal, None)
|
||||
.await
|
||||
.unwrap()
|
||||
.expect("block bytes");
|
||||
|
||||
let block =
|
||||
BeaconBlock::<E, FullPayload<E>>::from_ssz_bytes(&block_bytes, &self.chain.spec)
|
||||
.expect("block bytes can be decoded");
|
||||
|
||||
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
|
||||
|
||||
self.client
|
||||
.post_beacon_blocks_ssz(&signed_block)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(self.chain.head_beacon_block().as_ref(), &signed_block);
|
||||
|
||||
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn test_block_production_no_verify_randao(self) -> Self {
|
||||
for _ in 0..E::slots_per_epoch() {
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -2713,12 +2789,18 @@ impl ApiTester {
|
||||
sk.sign(message).into()
|
||||
};
|
||||
|
||||
let block_contents = self
|
||||
let block_contents_bytes = self
|
||||
.client
|
||||
.get_validator_blinded_blocks::<E, Payload>(slot, &randao_reveal, None)
|
||||
.get_validator_blinded_blocks_ssz::<E, Payload>(slot, &randao_reveal, None)
|
||||
.await
|
||||
.unwrap()
|
||||
.data;
|
||||
.expect("block bytes");
|
||||
|
||||
let block_contents = BlockContents::<E, Payload>::from_ssz_bytes(
|
||||
&block_contents_bytes,
|
||||
&self.chain.spec,
|
||||
)
|
||||
.expect("block bytes can be decoded");
|
||||
|
||||
let signed_block_contents =
|
||||
block_contents.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
|
||||
@@ -3309,6 +3391,7 @@ impl ApiTester {
|
||||
.unwrap()
|
||||
.get_payload_by_root(&payload.tree_hash_root())
|
||||
.is_none());
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
@@ -3317,7 +3400,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::GasLimit(30_000_000));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -3361,7 +3443,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::FeeRecipient(test_fee_recipient));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -3404,7 +3485,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::ParentHash(invalid_parent_hash));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -3454,7 +3534,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::PrevRandao(invalid_prev_randao));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -3500,7 +3579,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::BlockNumber(invalid_block_number));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -3548,7 +3626,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Timestamp(invalid_timestamp));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -3589,11 +3666,7 @@ impl ApiTester {
|
||||
}
|
||||
|
||||
pub async fn test_payload_rejects_invalid_signature(self) -> Self {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.invalid_signatures();
|
||||
self.mock_builder.as_ref().unwrap().invalid_signatures();
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
let epoch = self.chain.epoch().unwrap();
|
||||
@@ -3878,7 +3951,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_BUILDER_THRESHOLD_WEI - 1,
|
||||
)));
|
||||
@@ -3916,7 +3988,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI + 1,
|
||||
)));
|
||||
@@ -3954,7 +4025,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI,
|
||||
)));
|
||||
@@ -3992,7 +4062,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI - 1,
|
||||
)));
|
||||
@@ -4030,7 +4099,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI + 1,
|
||||
)));
|
||||
@@ -4104,7 +4172,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::Value(Uint256::from(
|
||||
DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI + 1,
|
||||
)));
|
||||
@@ -4112,7 +4179,6 @@ impl ApiTester {
|
||||
self.mock_builder
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.builder
|
||||
.add_operation(Operation::WithdrawalsRoot(Hash256::repeat_byte(0x42)));
|
||||
|
||||
let slot = self.chain.slot().unwrap();
|
||||
@@ -4976,6 +5042,20 @@ async fn block_production_verify_randao_invalid() {
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn block_production_ssz_full_payload() {
|
||||
ApiTester::new().await.test_block_production_ssz().await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn block_production_ssz_with_skip_slots() {
|
||||
ApiTester::new()
|
||||
.await
|
||||
.skip_slots(E::slots_per_epoch() * 2)
|
||||
.test_block_production_ssz()
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn blinded_block_production_full_payload_premerge() {
|
||||
ApiTester::new()
|
||||
|
||||
Reference in New Issue
Block a user