Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions config/papyrus/default_config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"base_layer.ordered_l1_endpoint_urls": {
"description": "An ordered list of URLs for communicating with Ethereum. The list is used in order, cyclically, switching if the current one is non-operational.",
"privacy": "Private",
"value": "https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY"
},
"base_layer.prague_blob_gas_calc": {
"description": "If true use the blob gas calculcation from the Pectra upgrade. If false use the EIP 4844 calculation.",
"privacy": "Public",
Expand Down Expand Up @@ -236,10 +241,8 @@
},
"context.build_proposal_time_ratio_for_retrospective_block_hash": {
"description": "The fraction (0.0 - 1.0) of the total build time allocated to waiting for the retrospective block hash to be available. The remaining time is used to build the proposal.",
"value": {
"$serde_json::private::Number": "0.7"
},
"privacy": "Public"
"privacy": "Public",
"value": 0.7
},
"context.builder_address": {
"description": "The address of the contract that builds the block.",
Expand Down Expand Up @@ -338,10 +341,8 @@
},
"context.retrospective_block_hash_retry_interval_millis": {
"description": "The interval between retrospective block hash retries.",
"value": {
"$serde_json::private::Number": "500"
},
"privacy": "Public"
"privacy": "Public",
"value": 500
},
"context.validate_proposal_margin_millis": {
"description": "Safety margin (in ms) to make sure that consensus determines when to timeout validating a proposal.",
Expand Down
4 changes: 3 additions & 1 deletion crates/apollo_base_layer_tests/src/anvil_base_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ curl -L \
Starknet::deploy(anvil_client.clone()).await.unwrap();

let config = Self::config();
let url = Self::url();
let url =
config.ordered_l1_endpoint_urls.first().expect("No endpoint URLs provided").clone();
let root_client = anvil_client.root().clone();
let contract = Starknet::new(config.starknet_contract_address, root_client);

Expand All @@ -123,6 +124,7 @@ curl -L \
pub fn config() -> EthereumBaseLayerConfig {
EthereumBaseLayerConfig {
starknet_contract_address: Self::DEFAULT_ANVIL_L1_DEPLOYED_ADDRESS.parse().unwrap(),
ordered_l1_endpoint_urls: vec![Self::url()],
..Default::default()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ async fn anvil_starts_with_no_contract() {
let anvil = Anvil::new()
.try_spawn()
.expect("Anvil not installed, see anvil base layer for installation instructions.");
let url = anvil.endpoint_url();
let base_layer_config = EthereumBaseLayerConfig::default();
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone(), url.clone());
let base_layer_config = EthereumBaseLayerConfig {
ordered_l1_endpoint_urls: vec![anvil.endpoint_url()],
..Default::default()
};
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone());

let sender_address = ARBITRARY_ANVIL_L1_ACCOUNT_ADDRESS;
let receiver_address = OTHER_ARBITRARY_ANVIL_L1_ACCOUNT_ADDRESS;
make_block_history_on_anvil(
sender_address,
receiver_address,
base_layer_config.clone(),
&url,
NUM_L1_TRANSACTIONS,
)
.await;
Expand Down
1 change: 1 addition & 0 deletions crates/apollo_deployments/resources/testing_secrets.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"base_layer_config.ordered_l1_endpoint_urls": "http://anvil-service.anvil.svc.cluster.local:8545",
"consensus_manager_config.network_config.secret_key": "0x0101010101010101010101010101010101010101010101010101010101010101",
"l1_endpoint_monitor_config.ordered_l1_endpoint_urls": "http://anvil-service.anvil.svc.cluster.local:8545",
"l1_gas_price_provider_config.eth_to_strk_oracle_config.url_header_list": "http://dummy-eth2strk-oracle-service.dummy-eth2strk-oracle.svc.cluster.local/eth_to_strk_oracle?timestamp=:9000",
Expand Down
9 changes: 9 additions & 0 deletions crates/apollo_deployments/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ pub(crate) const FIX_BINARY_NAME: &str = "deployment_generator";

#[derive(Serialize)]
pub struct SecretsConfigOverride {
#[serde(
rename = "base_layer_config.ordered_l1_endpoint_urls",
serialize_with = "serialize_slice_wrapper"
)]
base_layer_config_ordered_l1_endpoint_urls: Vec<Url>,
#[serde(
rename = "consensus_manager_config.network_config.secret_key",
serialize_with = "serialize_optional_vec_u8_wrapper"
Expand Down Expand Up @@ -47,6 +52,10 @@ pub struct SecretsConfigOverride {
impl Default for SecretsConfigOverride {
fn default() -> Self {
Self {
base_layer_config_ordered_l1_endpoint_urls: vec![
Url::parse("https://arbitrary.ordered_l1_endpoint_1.url").unwrap(),
Url::parse("https://arbitrary.ordered_l1_endpoint_2.url").unwrap(),
],
consensus_manager_config_network_config_secret_key: None,
l1_endpoint_monitor_config_ordered_l1_endpoint_urls: vec![
Url::parse("https://arbitrary.ordered_l1_endpoint_1.url").unwrap(),
Expand Down
14 changes: 6 additions & 8 deletions crates/apollo_integration_tests/src/bin/sequencer_simulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,33 +136,31 @@ async fn initialize_anvil_state(sender_address: Address, receiver_address: Addre
sender_address, receiver_address
);

let (base_layer_config, base_layer_url) = build_base_layer_config_for_testing();
let base_layer_config = build_base_layer_config_for_testing();

let ethereum_base_layer_contract =
EthereumBaseLayerContract::new(base_layer_config.clone(), base_layer_url.clone());
let ethereum_base_layer_contract = EthereumBaseLayerContract::new(base_layer_config.clone());
Starknet::deploy(ethereum_base_layer_contract.contract.provider().clone()).await.unwrap();

make_block_history_on_anvil(
sender_address,
receiver_address,
base_layer_config,
&base_layer_url,
NUM_BLOCKS_NEEDED_ON_L1,
)
.await;
}

fn build_base_layer_config_for_testing() -> (EthereumBaseLayerConfig, Url) {
fn build_base_layer_config_for_testing() -> EthereumBaseLayerConfig {
let starknet_contract_address: EthereumContractAddress =
DEFAULT_ANVIL_L1_DEPLOYED_ADDRESS.parse().expect("Invalid contract address");
let node_url = Url::parse(ANVIL_NODE_URL).expect("Failed to parse Anvil URL");

let base_layer_config = EthereumBaseLayerConfig {
EthereumBaseLayerConfig {
ordered_l1_endpoint_urls: vec![node_url.clone()],
starknet_contract_address,
prague_blob_gas_calc: true,
..Default::default()
};
(base_layer_config, node_url)
}
}

#[derive(Parser, Debug)]
Expand Down
1 change: 0 additions & 1 deletion crates/apollo_integration_tests/src/flow_test_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ impl FlowTestSetup {
sender_address,
receiver_address,
base_layer_config.clone(),
&base_layer_url,
NUM_L1_TRANSACTIONS,
)
.await;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use mempool_test_utils::starknet_api_test_utils::{
MultiAccountTransactionGenerator,
};
use papyrus_base_layer::test_utils::anvil_mine_blocks;
use papyrus_base_layer::BaseLayerContract;
use starknet_api::block::BlockNumber;
use starknet_api::core::{ChainId, Nonce};
use starknet_api::execution_resources::GasAmount;
Expand Down Expand Up @@ -309,7 +308,6 @@ impl IntegrationTestManager {
anvil_mine_blocks(
anvil_base_layer.ethereum_base_layer.config.clone(),
MIN_EXPECTED_BLOCK_NUMBER,
&anvil_base_layer.get_url().await.expect("Failed to get anvil url."),
)
.await;

Expand Down
8 changes: 2 additions & 6 deletions crates/apollo_l1_provider/tests/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,8 @@ fn convert_call_data_to_u256(call_data: &[u8]) -> Vec<Uint<256, 4>> {
#[allow(dead_code)]
pub(crate) async fn setup_anvil_base_layer() -> AnvilBaseLayer {
let mut base_layer = AnvilBaseLayer::new(None).await;
anvil_mine_blocks(
base_layer.ethereum_base_layer.config.clone(),
NUMBER_OF_BLOCKS_TO_MINE,
&base_layer.ethereum_base_layer.get_url().await.expect("Failed to get anvil url."),
)
.await;
anvil_mine_blocks(base_layer.ethereum_base_layer.config.clone(), NUMBER_OF_BLOCKS_TO_MINE)
.await;
// We use a really long timeout because in the tests we sometimes advance the fake time by large
// jumps (e.g., when the runtime yields, tokio moves the fake time to the next pending timer).
base_layer.ethereum_base_layer.config.timeout_millis = Duration::from_secs(10000);
Expand Down
5 changes: 5 additions & 0 deletions crates/apollo_node/resources/config_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"privacy": "TemporaryValue",
"value": false
},
"base_layer_config.ordered_l1_endpoint_urls": {
"description": "An ordered list of URLs for communicating with Ethereum. The list is used in order, cyclically, switching if the current one is non-operational.",
"privacy": "Private",
"value": "https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY"
},
"base_layer_config.prague_blob_gas_calc": {
"description": "If true use the blob gas calculcation from the Pectra upgrade. If false use the EIP 4844 calculation.",
"privacy": "Public",
Expand Down
1 change: 1 addition & 0 deletions crates/apollo_node/resources/config_secrets_schema.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[
"base_layer_config.ordered_l1_endpoint_urls",
"consensus_manager_config.network_config.secret_key",
"l1_endpoint_monitor_config.ordered_l1_endpoint_urls",
"l1_gas_price_provider_config.eth_to_strk_oracle_config.url_header_list",
Expand Down
22 changes: 8 additions & 14 deletions crates/apollo_node/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,18 +372,15 @@ pub async fn create_node_components(
// TODO(guyn): make base layer config a pointer, to be included in the scraper config.
let base_layer_config =
config.base_layer_config.as_ref().expect("Base Layer config should be set");
let l1_endpoint_monitor_config = config
.l1_endpoint_monitor_config
.as_ref()
.expect("L1 Endpoint Monitor config should be set");
let initial_node_url = l1_endpoint_monitor_config.ordered_l1_endpoint_urls[0].clone();
// TODO(guyn): we are left in a weird situation in which the base layer config has a
// list of URLs but the l1 endpoing monitor also has such a list, and we use the latter.
// This will all go away in a subsequent PR where we remove the endpoint monitor.
let l1_scraper_config =
config.l1_scraper_config.as_ref().expect("L1 Scraper config should be set");
let l1_provider_client = clients.get_l1_provider_shared_client().unwrap();
let l1_endpoint_monitor_client =
clients.get_l1_endpoint_monitor_shared_client().unwrap();
let base_layer =
EthereumBaseLayerContract::new(base_layer_config.clone(), initial_node_url.clone());
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone());
let monitored_base_layer =
MonitoredEthereumBaseLayer::new(base_layer, l1_endpoint_monitor_client).await;

Expand Down Expand Up @@ -474,15 +471,12 @@ pub async fn create_node_components(
let l1_gas_price_client = clients
.get_l1_gas_price_shared_client()
.expect("L1 gas price client should be available");
// TODO(guyn): we are left in a weird situation in which the base layer config has a
// list of URLs but the l1 endpoing monitor also has such a list, and we use the latter.
// This will all go away in a subsequent PR where we remove the endpoint monitor.
let l1_endpoint_monitor_client =
clients.get_l1_endpoint_monitor_shared_client().unwrap();
let l1_endpoint_monitor_config = config
.l1_endpoint_monitor_config
.as_ref()
.expect("L1 Endpoint Monitor config should be set");
let initial_node_url = l1_endpoint_monitor_config.ordered_l1_endpoint_urls[0].clone();
let base_layer =
EthereumBaseLayerContract::new(base_layer_config.clone(), initial_node_url.clone());
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone());
let monitored_base_layer =
MonitoredEthereumBaseLayer::new(base_layer, l1_endpoint_monitor_client).await;

Expand Down
15 changes: 8 additions & 7 deletions crates/papyrus_base_layer/src/base_layer_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ use alloy::providers::mock::Asserter;
use alloy::providers::{Provider, ProviderBuilder};
use alloy::rpc::types::{Block, BlockTransactions, Header as AlloyRpcHeader};
use pretty_assertions::assert_eq;
use url::Url;

use crate::ethereum_base_layer_contract::{EthereumBaseLayerContract, Starknet};
use crate::ethereum_base_layer_contract::{
EthereumBaseLayerConfig,
EthereumBaseLayerContract,
Starknet,
};
use crate::BaseLayerContract;

// TODO(Gilad): Use everywhere instead of relying on the confusing `#[ignore]` api to mark slow
Expand All @@ -21,11 +24,9 @@ fn base_layer_with_mocked_provider() -> (EthereumBaseLayerContract, Asserter) {

let provider = ProviderBuilder::new().connect_mocked_client(asserter.clone()).root().clone();
let contract = Starknet::new(Default::default(), provider);
let base_layer = EthereumBaseLayerContract {
contract,
config: Default::default(),
url: Url::parse("http://dummy_url").unwrap(),
};
let config = EthereumBaseLayerConfig::default();
let url = config.ordered_l1_endpoint_urls.first().expect("No endpoint URLs provided").clone();
let base_layer = EthereumBaseLayerContract { contract, config, url };

(base_layer, asserter)
}
Expand Down
22 changes: 20 additions & 2 deletions crates/papyrus_base_layer/src/ethereum_base_layer_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ use alloy::rpc::types::eth::Filter as EthEventFilter;
use alloy::sol;
use alloy::sol_types::sol_data;
use alloy::transports::TransportErrorKind;
use apollo_config::converters::deserialize_milliseconds_to_duration;
use apollo_config::converters::{
deserialize_milliseconds_to_duration,
deserialize_vec,
serialize_slice,
};
use apollo_config::dumping::{ser_param, SerializeConfig};
use apollo_config::{ParamPath, ParamPrivacyInput, SerializedParam};
use async_trait::async_trait;
Expand Down Expand Up @@ -69,7 +73,9 @@ pub struct EthereumBaseLayerContract {
}

impl EthereumBaseLayerContract {
pub fn new(config: EthereumBaseLayerConfig, url: Url) -> Self {
pub fn new(config: EthereumBaseLayerConfig) -> Self {
let url =
config.ordered_l1_endpoint_urls.first().expect("No endpoint URLs provided").clone();
let contract = build_contract_instance(config.starknet_contract_address, url.clone());
Self { url, contract, config }
}
Expand Down Expand Up @@ -246,6 +252,8 @@ impl PartialEq for EthereumBaseLayerError {

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Validate)]
pub struct EthereumBaseLayerConfig {
#[serde(deserialize_with = "deserialize_vec")]
pub ordered_l1_endpoint_urls: Vec<Url>,
pub starknet_contract_address: EthereumContractAddress,
pub prague_blob_gas_calc: bool,
#[serde(deserialize_with = "deserialize_milliseconds_to_duration")]
Expand All @@ -255,6 +263,13 @@ pub struct EthereumBaseLayerConfig {
impl SerializeConfig for EthereumBaseLayerConfig {
fn dump(&self) -> BTreeMap<ParamPath, SerializedParam> {
BTreeMap::from_iter([
ser_param(
"ordered_l1_endpoint_urls",
&serialize_slice(&self.ordered_l1_endpoint_urls),
"An ordered list of URLs for communicating with Ethereum. The list is used in \
order, cyclically, switching if the current one is non-operational.",
ParamPrivacyInput::Private,
),
ser_param(
"starknet_contract_address",
&self.starknet_contract_address.to_string(),
Expand Down Expand Up @@ -284,6 +299,9 @@ impl Default for EthereumBaseLayerConfig {
"0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4".parse().unwrap();

Self {
ordered_l1_endpoint_urls: vec![
"https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY".parse().unwrap(),
],
starknet_contract_address,
prague_blob_gas_calc: true,
timeout_millis: Duration::from_millis(1000),
Expand Down
6 changes: 4 additions & 2 deletions crates/papyrus_base_layer/src/monitored_base_layer_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;
use apollo_l1_endpoint_monitor_types::MockL1EndpointMonitorClient;
use url::Url;

use crate::ethereum_base_layer_contract::EthereumBaseLayerContract;
use crate::ethereum_base_layer_contract::{EthereumBaseLayerConfig, EthereumBaseLayerContract};
use crate::monitored_base_layer::MonitoredEthereumBaseLayer;

#[tokio::test]
Expand All @@ -12,7 +12,9 @@ async fn switch_between_endpoints() {
let url1 = Url::parse("http://first_endpoint").unwrap();
let url2 = Url::parse("http://second_endpoint").unwrap();
let urls = [url1.clone(), url2.clone()];
let base_layer = EthereumBaseLayerContract::new(Default::default(), url1.clone());
let config =
EthereumBaseLayerConfig { ordered_l1_endpoint_urls: urls.to_vec(), ..Default::default() };
let base_layer = EthereumBaseLayerContract::new(config);
let mut l1_endpoint_monitor = MockL1EndpointMonitorClient::new();
l1_endpoint_monitor
.expect_get_active_l1_endpoint()
Expand Down
12 changes: 3 additions & 9 deletions crates/papyrus_base_layer/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use alloy::providers::Provider;
use alloy::rpc::types::TransactionRequest;
use starknet_api::hash::StarkHash;
use tracing::debug;
use url::Url;

use crate::ethereum_base_layer_contract::{
EthereumBaseLayerConfig,
Expand Down Expand Up @@ -37,10 +36,9 @@ pub async fn make_block_history_on_anvil(
sender_address: EthereumContractAddress,
receiver_address: EthereumContractAddress,
base_layer_config: EthereumBaseLayerConfig,
url: &Url,
num_blocks: usize,
) {
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone(), url.clone());
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone());
let provider = base_layer.contract.provider();
let mut prev_block_number =
usize::try_from(provider.get_block_number().await.unwrap()).unwrap();
Expand Down Expand Up @@ -72,12 +70,8 @@ pub async fn make_block_history_on_anvil(
///
/// Note: This creates empty blocks. For blocks with transactions, use the
/// `make_block_history_on_anvil` function instead.
pub async fn anvil_mine_blocks(
base_layer_config: EthereumBaseLayerConfig,
num_blocks: u64,
url: &Url,
) {
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone(), url.clone());
pub async fn anvil_mine_blocks(base_layer_config: EthereumBaseLayerConfig, num_blocks: u64) {
let base_layer = EthereumBaseLayerContract::new(base_layer_config.clone());
let provider = base_layer.contract.provider();

let block_before = provider.get_block_number().await.expect("Failed to get block number");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ source: crates/papyrus_node/src/config/config_test.rs
expression: dumped_default_config
---
{
"base_layer.ordered_l1_endpoint_urls": {
"description": "An ordered list of URLs for communicating with Ethereum. The list is used in order, cyclically, switching if the current one is non-operational.",
"value": "https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY",
"privacy": "Private"
},
"base_layer.prague_blob_gas_calc": {
"description": "If true use the blob gas calculcation from the Pectra upgrade. If false use the EIP 4844 calculation.",
"value": true,
Expand Down
Loading