Skip to content

Commit

Permalink
FIX: Add (optional) timeout to parent sync Ethereum API queries (#758)
Browse files Browse the repository at this point in the history
  • Loading branch information
aakoshh authored Feb 29, 2024
1 parent 088cb4f commit b2bdb1f
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 12 deletions.
3 changes: 3 additions & 0 deletions fendermint/app/settings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ pub struct TopDownSettings {
pub exponential_retry_limit: usize,
/// The parent rpc http endpoint
pub parent_http_endpoint: Url,
/// Timeout for calls to the parent Ethereum API.
#[serde_as(as = "Option<DurationSeconds<u64>>")]
pub parent_http_timeout: Option<Duration>,
/// The parent registry address
#[serde(deserialize_with = "deserialize_eth_address_from_str")]
pub parent_registry: Address,
Expand Down
1 change: 1 addition & 0 deletions fendermint/app/src/cmd/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ async fn new_genesis_from_parent(
.ok_or_else(|| anyhow!("subnet is not a child"))?,
config: SubnetConfig::Fevm(EVMSubnet {
provider_http: args.parent_endpoint.clone(),
provider_timeout: None,
auth_token: None,
registry_addr: args.parent_registry,
gateway_addr: args.parent_gateway,
Expand Down
1 change: 1 addition & 0 deletions fendermint/app/src/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ fn make_ipc_provider_proxy(settings: &Settings) -> anyhow::Result<IPCProviderPro
.to_string()
.parse()
.unwrap(),
provider_timeout: topdown_config.parent_http_timeout,
auth_token: None,
registry_addr: topdown_config.parent_registry,
gateway_addr: topdown_config.parent_gateway,
Expand Down
9 changes: 6 additions & 3 deletions fendermint/vm/topdown/src/sync/syncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ where

return Ok(height);
}
return Err(Error::CannotQueryParent(err, height));
return Err(Error::CannotQueryParent(
format!("get_block_hash: {e}"),
height,
));
}
};

Expand Down Expand Up @@ -249,7 +252,7 @@ where
.parent_proxy
.get_validator_changes(height)
.await
.map_err(|e| Error::CannotQueryParent(e.to_string(), height))?;
.map_err(|e| Error::CannotQueryParent(format!("get_validator_changes: {e}"), height))?;

if changes_res.block_hash != block_hash {
tracing::warn!(
Expand All @@ -265,7 +268,7 @@ where
.parent_proxy
.get_top_down_msgs(height)
.await
.map_err(|e| Error::CannotQueryParent(e.to_string(), height))?;
.map_err(|e| Error::CannotQueryParent(format!("get_top_down_msgs: {e}"), height))?;

if topdown_msgs_res.block_hash != block_hash {
tracing::warn!(
Expand Down
8 changes: 5 additions & 3 deletions infra/fendermint/scripts/fendermint.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ docker run \
--env FM_IPC__SUBNET_ID=${SUBNET_ID} \
--env FM_IPC__TOPDOWN__CHAIN_HEAD_DELAY=${TOPDOWN_CHAIN_HEAD_DELAY} \
--env FM_IPC__TOPDOWN__PARENT_HTTP_ENDPOINT=${PARENT_ENDPOINT} \
--env FM_IPC__TOPDOWN__PARENT_HTTP_TIMEOUT=60 \
--env FM_IPC__TOPDOWN__PARENT_REGISTRY=${PARENT_REGISTRY} \
--env FM_IPC__TOPDOWN__PARENT_GATEWAY=${PARENT_GATEWAY} \
--env FM_IPC__TOPDOWN__EXPONENTIAL_BACK_OFF=5 \
Expand All @@ -73,7 +74,7 @@ docker run \
--env FM_VALIDATOR_KEY__PATH=/data/${NODE_NAME}/${VALIDATOR_PRIV_KEY_PATH} \
--env FM_VALIDATOR_KEY__KIND=ethereum \
--env TENDERMINT_RPC_URL=http://${CMT_CONTAINER_NAME}:26657 \
--env LOG_LEVEL=${LOG_LEVEL} \
--env LOG_LEVEL=${FM_LOG_LEVEL} \
--env RUST_BACKTRACE=1 \
${FM_DOCKER_IMAGE} \
--network=${FM_NETWORK} \
Expand Down Expand Up @@ -104,6 +105,7 @@ docker run \
--env FM_IPC__SUBNET_ID=${SUBNET_ID} \
--env FM_IPC__TOPDOWN__CHAIN_HEAD_DELAY=${TOPDOWN_CHAIN_HEAD_DELAY} \
--env FM_IPC__TOPDOWN__PARENT_HTTP_ENDPOINT=${PARENT_ENDPOINT} \
--env FM_IPC__TOPDOWN__PARENT_HTTP_TIMEOUT=60 \
--env FM_IPC__TOPDOWN__PARENT_REGISTRY=${PARENT_REGISTRY} \
--env FM_IPC__TOPDOWN__PARENT_GATEWAY=${PARENT_GATEWAY} \
--env FM_IPC__TOPDOWN__EXPONENTIAL_BACK_OFF=5 \
Expand All @@ -116,7 +118,7 @@ docker run \
--env FM_RESOLVER__DISCOVERY__STATIC_ADDRESSES=${RESOLVER_BOOTSTRAPS} \
--env FM_TENDERMINT_RPC_URL=http://${CMT_CONTAINER_NAME}:26657 \
--env TENDERMINT_RPC_URL=http://${CMT_CONTAINER_NAME}:26657 \
--env LOG_LEVEL=${LOG_LEVEL} \
--env LOG_LEVEL=${FM_LOG_LEVEL} \
--env RUST_BACKTRACE=1 \
${FM_DOCKER_IMAGE} \
--network=${FM_NETWORK} \
Expand All @@ -131,7 +133,7 @@ docker run \
--init \
--user $(id -u) \
--volume ${BASE_DIR}:/data \
--env LOG_LEVEL=${LOG_LEVEL} \
--env LOG_LEVEL=${FM_LOG_LEVEL} \
--env RUST_BACKTRACE=1 \
${FM_DOCKER_IMAGE} \
--network=${FM_NETWORK} \
Expand Down
1 change: 1 addition & 0 deletions ipc/provider/src/config/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ mod tests {
config: SubnetConfig::Fevm(EVMSubnet {
gateway_addr: Address::from(eth_addr1),
provider_http: "http://127.0.0.1:3030/rpc/v1".parse().unwrap(),
provider_timeout: None,
auth_token: None,
registry_addr: Address::from(eth_addr1),
}),
Expand Down
11 changes: 11 additions & 0 deletions ipc/provider/src/config/subnet.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::time::Duration;

// Copyright 2022-2024 Protocol Labs
// SPDX-License-Identifier: MIT
use fvm_shared::address::Address;
Expand Down Expand Up @@ -53,6 +55,12 @@ impl Subnet {
}
}

pub fn rpc_timeout(&self) -> Option<Duration> {
match &self.config {
SubnetConfig::Fevm(s) => s.provider_timeout,
}
}

pub fn gateway_addr(&self) -> Address {
match &self.config {
SubnetConfig::Fevm(s) => s.gateway_addr,
Expand All @@ -74,10 +82,13 @@ pub struct FVMSubnet {
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
pub struct EVMSubnet {
pub provider_http: Url,
pub provider_timeout: Option<Duration>,
pub auth_token: Option<String>,

#[serde(deserialize_with = "deserialize_eth_address_from_str")]
#[serde(serialize_with = "serialize_eth_address_to_str")]
pub registry_addr: Address,

#[serde(deserialize_with = "deserialize_eth_address_from_str")]
#[serde(serialize_with = "serialize_eth_address_to_str")]
pub gateway_addr: Address,
Expand Down
29 changes: 23 additions & 6 deletions ipc/provider/src/manager/evm/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use ipc_actors_abis::{
};
use ipc_api::evm::{fil_to_eth_amount, payload_to_evm_address, subnet_id_to_evm_addresses};
use ipc_api::validator::from_contract_validators;
use reqwest::header::HeaderValue;
use reqwest::Client;
use std::net::{IpAddr, SocketAddr};

use ipc_api::subnet::{PermissionMode, SupplyKind, SupplySource};
Expand Down Expand Up @@ -65,7 +67,7 @@ const ETH_PROVIDER_POLLING_TIME: Duration = Duration::from_secs(1);
const TRANSACTION_RECEIPT_RETRIES: usize = 200;

/// The majority vote percentage for checkpoint submission when creating a subnet.
const SUBNET_MAJORITY_PERCENTAGE: u8 = 60;
const SUBNET_MAJORITY_PERCENTAGE: u8 = 67;

pub struct EthSubnetManager {
keystore: Option<Arc<RwLock<PersistentKeyStore<EthKeyAddress>>>>,
Expand Down Expand Up @@ -937,11 +939,26 @@ impl EthSubnetManager {

let SubnetConfig::Fevm(config) = &subnet.config;

let provider = if auth_token.is_some() {
Http::new_with_auth(url, Authorization::Bearer(auth_token.unwrap()))?
} else {
Http::new(url)
};
let mut client = Client::builder();

if let Some(auth_token) = auth_token {
let auth = Authorization::Bearer(auth_token);
let mut auth_value = HeaderValue::from_str(&auth.to_string())?;
auth_value.set_sensitive(true);

let mut headers = reqwest::header::HeaderMap::new();
headers.insert(reqwest::header::AUTHORIZATION, auth_value);

client = client.default_headers(headers);
}

if let Some(timeout) = subnet.rpc_timeout() {
client = client.timeout(timeout);
}

let client = client.build()?;

let provider = Http::new_with_client(url, client);

let mut provider = Provider::new(provider);
// set polling interval for provider to fit fast child subnets block times.
Expand Down

0 comments on commit b2bdb1f

Please sign in to comment.