Skip to content

Commit

Permalink
Move some constants to config (#625)
Browse files Browse the repository at this point in the history
* bitcoinclient: make retry count and retry interval configurable

* refactor: rename to indicate default values

* make broadcast poll duration configurable

* dep: update openssl to fix cargo audit
  • Loading branch information
sapinb authored Feb 3, 2025
1 parent c6ef01c commit a1a2e46
Show file tree
Hide file tree
Showing 16 changed files with 150 additions and 32 deletions.
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions bin/bridge-client/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ pub(crate) struct Cli {
#[argh(option, description = "password for bitcoin RPC")]
pub btc_pass: String,

/// Max retries for Bitcoin RPC calls.
#[argh(option, description = "max retries for bitcoin RPC (default: 3)")]
pub btc_retry_count: Option<u8>,

/// Timeout duration for btc request retries in ms. Defaults to `1000`.
#[argh(
option,
description = "max interval between bitcoin RPC retries in ms (default: 1000)"
)]
pub btc_retry_interval: Option<u64>,

/// URL for the Rollup RPC server.
#[argh(option, description = "url for the rollup RPC server")]
pub rollup_url: String,
Expand Down
4 changes: 2 additions & 2 deletions bin/bridge-client/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub(super) const DEFAULT_RPC_HOST: &str = "127.0.0.1";

pub(super) const DEFAULT_DUTY_TIMEOUT_SEC: u64 = 600;
/// The default bridge rocksdb database retry count, if not overridden by the user.
pub(super) const ROCKSDB_RETRY_COUNT: u16 = 3;
pub(super) const DEFAULT_ROCKSDB_RETRY_COUNT: u16 = 3;

/// The default RPC retry count, if not overridden by the user.
pub(super) const MAX_RPC_RETRY_COUNT: u16 = 5;
pub(super) const DEFAULT_MAX_RPC_RETRY_COUNT: u16 = 5;
20 changes: 14 additions & 6 deletions bin/bridge-client/src/modes/operator/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ use super::{constants::DB_THREAD_COUNT, task_manager::TaskManager};
use crate::{
args::Cli,
constants::{
DEFAULT_DUTY_TIMEOUT_SEC, DEFAULT_RPC_HOST, DEFAULT_RPC_PORT, MAX_RPC_RETRY_COUNT,
ROCKSDB_RETRY_COUNT,
DEFAULT_DUTY_TIMEOUT_SEC, DEFAULT_MAX_RPC_RETRY_COUNT, DEFAULT_ROCKSDB_RETRY_COUNT,
DEFAULT_RPC_HOST, DEFAULT_RPC_PORT,
},
db::open_rocksdb_database,
rpc_server::{self, BridgeRpc},
Expand All @@ -48,7 +48,7 @@ pub(crate) async fn bootstrap(args: Cli) -> anyhow::Result<()> {

// Initialize a rocksdb instance with the required column families.
let rbdb = open_rocksdb_database(data_dir)?;
let retry_count = args.retry_count.unwrap_or(ROCKSDB_RETRY_COUNT);
let retry_count = args.retry_count.unwrap_or(DEFAULT_ROCKSDB_RETRY_COUNT);
let ops_config = DbOpsConfig::new(retry_count);

// Setup Threadpool for the database I/O ops.
Expand All @@ -65,8 +65,14 @@ pub(crate) async fn bootstrap(args: Cli) -> anyhow::Result<()> {

// Setup RPC clients.
let l1_rpc_client = Arc::new(
BitcoinClient::new(args.btc_url, args.btc_user, args.btc_pass)
.expect("error creating the bitcoin client"),
BitcoinClient::new(
args.btc_url,
args.btc_user,
args.btc_pass,
args.btc_retry_count,
args.btc_retry_interval,
)
.expect("error creating the bitcoin client"),
);

let config = WsClientConfig {
Expand Down Expand Up @@ -169,7 +175,9 @@ pub(crate) async fn bootstrap(args: Cli) -> anyhow::Result<()> {
.unwrap_or(DEFAULT_DUTY_TIMEOUT_SEC),
);

let max_retry_count = args.max_rpc_retry_count.unwrap_or(MAX_RPC_RETRY_COUNT);
let max_retry_count = args
.max_rpc_retry_count
.unwrap_or(DEFAULT_MAX_RPC_RETRY_COUNT);

// TODO: wrap these in `strata-tasks`
let duty_task = tokio::spawn(async move {
Expand Down
11 changes: 11 additions & 0 deletions bin/prover-client/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ pub struct Args {
#[argh(option, description = "bitcoind RPC password")]
pub bitcoind_password: String,

/// Max retries for Bitcoin RPC calls.
#[argh(option, description = "max retries for bitcoin RPC (default: 3)")]
pub bitcoin_retry_count: Option<u8>,

/// Timeout duration for btc request retries in ms. Defaults to `1000`.
#[argh(
option,
description = "max interval between bitcoin RPC retries in ms (default: 1000)"
)]
pub bitcoin_retry_interval: Option<u64>,

/// Path to the custom rollup configuration file.
#[argh(option, short = 'p', description = "custom rollup config path")]
pub rollup_params: PathBuf,
Expand Down
2 changes: 2 additions & 0 deletions bin/prover-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ async fn main_inner(args: Args) -> anyhow::Result<()> {
args.get_btc_rpc_url(),
args.bitcoind_user.clone(),
args.bitcoind_password.clone(),
args.bitcoin_retry_count,
args.bitcoin_retry_interval,
)
.context("Failed to connect to the Bitcoin client")?;

Expand Down
19 changes: 19 additions & 0 deletions bin/strata-client/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ pub struct Args {
#[argh(option, description = "bitcoind RPC password")]
pub bitcoind_password: Option<String>,

/// Max retries for Bitcoin RPC calls.
#[argh(option, description = "max retries for bitcoin RPC (default: 3)")]
pub bitcoind_retry_count: Option<u8>,

/// Timeout duration for btc request retries in ms. Defaults to `1000`.
#[argh(
option,
description = "max interval between bitcoin RPC retries in ms (default: 1000)"
)]
pub bitcoind_retry_interval: Option<u64>,

#[argh(option, short = 'n', description = "L1 network to run on")]
pub network: Option<Network>,

Expand Down Expand Up @@ -71,6 +82,8 @@ impl Args {
"args: no bitcoin --rpc-password provided",
)?,
network: require(args.network, "args: no bitcoin --network provided")?,
retry_count: args.bitcoind_retry_count,
retry_interval: args.bitcoind_retry_interval,
},
client: ClientConfig {
rpc_host: require(args.rpc_host, "args: no client --rpc-host provided")?,
Expand Down Expand Up @@ -123,6 +136,12 @@ impl Args {
if let Some(rpc_password) = args.bitcoind_password {
config.bitcoind_rpc.rpc_password = rpc_password;
}
if let Some(retry_count) = args.bitcoind_retry_count {
config.bitcoind_rpc.retry_count = Some(retry_count);
}
if let Some(retry_interval) = args.bitcoind_retry_interval {
config.bitcoind_rpc.retry_interval = Some(retry_interval);
}
if let Some(rpc_host) = args.rpc_host {
config.client.rpc_host = rpc_host;
}
Expand Down
2 changes: 2 additions & 0 deletions bin/strata-client/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ pub fn create_bitcoin_rpc_client(config: &Config) -> anyhow::Result<Arc<BitcoinC
bitcoind_url,
config.bitcoind_rpc.rpc_user.clone(),
config.bitcoind_rpc.rpc_password.clone(),
config.bitcoind_rpc.retry_count,
config.bitcoind_rpc.retry_interval,
)
.map_err(anyhow::Error::from)?;

Expand Down
11 changes: 9 additions & 2 deletions bin/strata-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ fn main_inner(args: Args) -> anyhow::Result<()> {
&executor,
ctx.bitcoin_client.clone(),
params.clone(),
config.btcio.broadcaster.poll_interval_ms,
);
let writer_db = init_writer_database(rbdb.clone(), ops_config);

Expand Down Expand Up @@ -477,15 +478,21 @@ fn start_broadcaster_tasks(
executor: &TaskExecutor,
bitcoin_client: Arc<BitcoinClient>,
params: Arc<Params>,
broadcast_poll_interval: u64,
) -> Arc<L1BroadcastHandle> {
// Set up L1 broadcaster.
let broadcast_ctx = strata_storage::ops::l1tx_broadcast::Context::new(
broadcast_database.l1_broadcast_db().clone(),
);
let broadcast_ops = Arc::new(broadcast_ctx.into_ops(pool));
// start broadcast task
let broadcast_handle =
spawn_broadcaster_task(executor, bitcoin_client.clone(), broadcast_ops, params);
let broadcast_handle = spawn_broadcaster_task(
executor,
bitcoin_client.clone(),
broadcast_ops,
params,
broadcast_poll_interval,
);
Arc::new(broadcast_handle)
}

Expand Down
13 changes: 10 additions & 3 deletions crates/btcio/src/broadcaster/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,23 @@ pub fn spawn_broadcaster_task<T>(
l1_rpc_client: Arc<T>,
broadcast_ops: Arc<BroadcastDbOps>,
params: Arc<Params>,
broadcast_poll_interval: u64,
) -> L1BroadcastHandle
where
T: ReaderRpc + BroadcasterRpc + WalletRpc + SignerRpc + Send + Sync + 'static,
{
let (broadcast_entry_tx, broadcast_entry_rx) = mpsc::channel::<(u64, L1TxEntry)>(64);
let ops = broadcast_ops.clone();
executor.spawn_critical_async("l1_broadcaster_task", async move {
broadcaster_task(l1_rpc_client, ops, broadcast_entry_rx, params)
.await
.map_err(Into::into)
broadcaster_task(
l1_rpc_client,
ops,
broadcast_entry_rx,
params,
broadcast_poll_interval,
)
.await
.map_err(Into::into)
});
L1BroadcastHandle::new(broadcast_entry_tx, broadcast_ops)
}
5 changes: 2 additions & 3 deletions crates/btcio/src/broadcaster/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ use crate::{
rpc::traits::{BroadcasterRpc, WalletRpc},
};

const BROADCAST_POLL_INTERVAL: u64 = 1_000; // millis

/// Broadcasts the next blob to be sent
pub async fn broadcaster_task(
rpc_client: Arc<impl BroadcasterRpc + WalletRpc>,
ops: Arc<l1tx_broadcast::BroadcastDbOps>,
mut entry_receiver: Receiver<(u64, L1TxEntry)>,
params: Arc<Params>,
broadcast_poll_interval: u64,
) -> BroadcasterResult<()> {
info!("Starting Broadcaster task");
let interval = tokio::time::interval(Duration::from_millis(BROADCAST_POLL_INTERVAL));
let interval = tokio::time::interval(Duration::from_millis(broadcast_poll_interval));
tokio::pin!(interval);

let mut state = BroadcasterState::initialize(&ops).await?;
Expand Down
34 changes: 28 additions & 6 deletions crates/btcio/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ use crate::rpc::{
pub type ClientResult<T> = Result<T, ClientError>;

/// The maximum number of retries for a request.
const MAX_RETRIES: u8 = 3;
const DEFAULT_MAX_RETRIES: u8 = 3;

/// The maximum number of retries for a request.
const DEFAULT_RETRY_INTERVAL_MS: u64 = 1_000;

/// Custom implementation to convert a value to a `Value` type.
pub fn to_value<T>(value: T) -> ClientResult<Value>
Expand All @@ -59,6 +62,10 @@ pub struct BitcoinClient {
client: Client,
/// The ID of the current request.
id: AtomicUsize,
/// The maximum number of retries for a request.
max_retries: u8,
/// Interval between retries for a request in ms.
retry_interval: u64,
}

/// Response returned by the `bitcoind` RPC server.
Expand All @@ -71,7 +78,13 @@ struct Response<R> {

impl BitcoinClient {
/// Creates a new [`BitcoinClient`] with the given URL, username, and password.
pub fn new(url: String, username: String, password: String) -> ClientResult<Self> {
pub fn new(
url: String,
username: String,
password: String,
max_retries: Option<u8>,
retry_interval: Option<u64>,
) -> ClientResult<Self> {
if username.is_empty() || password.is_empty() {
return Err(ClientError::MissingUserPassword);
}
Expand All @@ -96,9 +109,18 @@ impl BitcoinClient {

let id = AtomicUsize::new(0);

let max_retries = max_retries.unwrap_or(DEFAULT_MAX_RETRIES);
let retry_interval = retry_interval.unwrap_or(DEFAULT_RETRY_INTERVAL_MS);

trace!(url = %url, "Created bitcoin client");

Ok(Self { url, client, id })
Ok(Self {
url,
client,
id,
max_retries,
retry_interval,
})
}

fn next_id(&self) -> usize {
Expand Down Expand Up @@ -186,10 +208,10 @@ impl BitcoinClient {
}
}
retries += 1;
if retries >= MAX_RETRIES {
return Err(ClientError::MaxRetriesExceeded(MAX_RETRIES));
if retries >= self.max_retries {
return Err(ClientError::MaxRetriesExceeded(self.max_retries));
}
sleep(Duration::from_millis(1_000)).await;
sleep(Duration::from_millis(self.retry_interval)).await;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/btcio/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ pub mod corepc_node_helpers {
let bitcoind = BitcoinD::from_downloaded().unwrap();
let url = bitcoind.rpc_url();
let (user, password) = get_auth(&bitcoind);
let client = BitcoinClient::new(url, user, password).unwrap();
let client = BitcoinClient::new(url, user, password, None, None).unwrap();
(bitcoind, client)
}
}
Expand Down
16 changes: 16 additions & 0 deletions crates/config/src/btcio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::Deserialize;
pub struct BtcioConfig {
pub reader: ReaderConfig,
pub writer: WriterConfig,
pub broadcaster: BroadcasterConfig,
}

/// Configuration for btcio reader.
Expand Down Expand Up @@ -38,6 +39,13 @@ pub enum FeePolicy {
Fixed(u64),
}

/// Configuration for btcio broadcaster.
#[derive(Debug, Clone, Deserialize)]
pub struct BroadcasterConfig {
/// How often to invoke the broadcaster, in ms.
pub poll_interval_ms: u64,
}

impl Default for WriterConfig {
fn default() -> Self {
Self {
Expand All @@ -56,3 +64,11 @@ impl Default for ReaderConfig {
}
}
}

impl Default for BroadcasterConfig {
fn default() -> Self {
Self {
poll_interval_ms: 1_000,
}
}
}
Loading

0 comments on commit a1a2e46

Please sign in to comment.