From b2a2b12045608cb3601af266d7524dd70f20dbc0 Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Fri, 19 Sep 2025 15:50:14 -0400 Subject: [PATCH 1/2] Switch pvw commands to use ETH_RPC_URL to disambiguate deployments --- .../boundless-cli/src/commands/povw/claim.rs | 18 ++++++++++----- .../boundless-cli/src/commands/povw/submit.rs | 22 +++++++++++++------ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/crates/boundless-cli/src/commands/povw/claim.rs b/crates/boundless-cli/src/commands/povw/claim.rs index 2ed484210..65f187d1b 100644 --- a/crates/boundless-cli/src/commands/povw/claim.rs +++ b/crates/boundless-cli/src/commands/povw/claim.rs @@ -30,6 +30,7 @@ use boundless_povw::{ log_updater::IPovwAccounting::{self, EpochFinalized, IPovwAccountingInstance, WorkLogUpdated}, mint_calculator::{prover::MintCalculatorProver, IPovwMint, CHAIN_SPECS}, }; +use boundless_zkc::deployments::NamedChain; use clap::Args; use risc0_povw::PovwLogId; use risc0_zkvm::{default_prover, Digest, ProverOpts}; @@ -87,6 +88,10 @@ pub struct PovwClaim { #[clap(flatten, next_help_heading = "Prover")] prover_config: ProverConfig, + + /// The RPC URL to use to submit the reward claim transaction. + #[clap(long, env = "ETH_RPC_URL")] + pub eth_rpc_url: Url, } impl PovwClaim { @@ -97,14 +102,14 @@ impl PovwClaim { tracing::warn!("You can provide it using the --beacon-api-url flag."); } let tx_signer = global_config.require_private_key()?; - let rpc_url = global_config.require_rpc_url()?; + let eth_rpc_url = self.eth_rpc_url.clone(); // Connect to the chain. let provider = ProviderBuilder::new() .wallet(tx_signer.clone()) - .connect(rpc_url.as_str()) + .connect(eth_rpc_url.as_str()) .await - .with_context(|| format!("failed to connect provider to {rpc_url}"))?; + .with_context(|| format!("failed to connect provider to {eth_rpc_url}"))?; let chain_id = provider.get_chain_id().await.context("Failed to query the chain ID")?; let chain_spec = CHAIN_SPECS.get(&chain_id).with_context(|| { @@ -114,9 +119,10 @@ impl PovwClaim { .deployment .clone() .or_else(|| Deployment::from_chain_id(chain_id)) - .context( - "could not determine deployment from chain ID; please specify deployment explicitly", - )?; + .context(format!( + "could not determine deployment from chain ID {chain_id} ({:?}); please check the RPC matches the chain of the PoVW accounting contract or specify deployment explicitly", + NamedChain::try_from(chain_id) + ))?; // Determine the limits on the blocks that will be searched for events. let latest_block_number = diff --git a/crates/boundless-cli/src/commands/povw/submit.rs b/crates/boundless-cli/src/commands/povw/submit.rs index 5035476b6..f3a061a28 100644 --- a/crates/boundless-cli/src/commands/povw/submit.rs +++ b/crates/boundless-cli/src/commands/povw/submit.rs @@ -24,9 +24,11 @@ use boundless_povw::{ deployments::Deployment, log_updater::{prover::LogUpdaterProver, IPovwAccounting}, }; +use boundless_zkc::deployments::NamedChain; use clap::Args; use risc0_povw::guest::Journal as LogBuilderJournal; use risc0_zkvm::{default_prover, ProverOpts}; +use url::Url; use super::State; use crate::config::{GlobalConfig, ProverConfig}; @@ -58,6 +60,10 @@ pub struct PovwSubmit { #[clap(flatten, next_help_heading = "Prover")] prover_config: ProverConfig, + + /// The RPC URL to use to submit the work update transaction to the staking contract. + #[clap(long, env = "ETH_RPC_URL")] + pub eth_rpc_url: Url, } impl PovwSubmit { @@ -65,7 +71,7 @@ impl PovwSubmit { pub async fn run(&self, global_config: &GlobalConfig) -> anyhow::Result<()> { let tx_signer = global_config.require_private_key()?; let work_log_signer = self.povw_private_key.as_ref().unwrap_or(&tx_signer); - let rpc_url = global_config.require_rpc_url()?; + let eth_rpc_url = self.eth_rpc_url.clone(); // Load the state and check to make sure the private key matches. let mut state = State::load(&self.state) @@ -83,21 +89,23 @@ impl PovwSubmit { // Connect to the chain. let provider = ProviderBuilder::new() .wallet(tx_signer.clone()) - .connect(rpc_url.as_str()) + .connect(eth_rpc_url.as_str()) .await - .with_context(|| format!("Failed to connect provider to {rpc_url}"))?; + .with_context(|| format!("Failed to connect provider to {eth_rpc_url}"))?; let chain_id = provider .get_chain_id() .await - .with_context(|| format!("Failed to get chain ID from {rpc_url}"))?; + .with_context(|| format!("Failed to get chain ID from {eth_rpc_url}"))?; + let deployment = self .deployment .clone() .or_else(|| Deployment::from_chain_id(chain_id)) - .context( - "could not determine deployment from chain ID; please specify deployment explicitly", - )?; + .context(format!( + "could not determine deployment from chain ID {chain_id} ({:?}); please check the RPC matches the chain of the PoVW accounting contract or specify deployment explicitly", + NamedChain::try_from(chain_id) + ))?; let povw_accounting = IPovwAccounting::new(deployment.povw_accounting_address, provider.clone()); From 5561f4264c027e25b7c7a4b51afead9655bf3286 Mon Sep 17 00:00:00 2001 From: Austin Abell Date: Wed, 24 Sep 2025 19:47:49 -0400 Subject: [PATCH 2/2] update tests --- crates/boundless-cli/tests/povw.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/boundless-cli/tests/povw.rs b/crates/boundless-cli/tests/povw.rs index 571dccb98..40ccb2c12 100644 --- a/crates/boundless-cli/tests/povw.rs +++ b/crates/boundless-cli/tests/povw.rs @@ -160,7 +160,7 @@ async fn prove_and_send_update() -> anyhow::Result<()> { .env("VEZKC_ADDRESS", format!("{:#x}", ctx.zkc_rewards.address())) .env("PRIVATE_KEY", format!("{:#x}", tx_signer.to_bytes())) .env("RISC0_DEV_MODE", "1") - .env("RPC_URL", ctx.anvil.lock().await.endpoint_url().as_str()) + .env("ETH_RPC_URL", ctx.anvil.lock().await.endpoint_url().as_str()) .env("POVW_PRIVATE_KEY", format!("{:#x}", work_log_signer.to_bytes())) .assert() .success() @@ -270,7 +270,7 @@ async fn claim_reward_multi_epoch() -> anyhow::Result<()> { .env("VEZKC_ADDRESS", format!("{:#x}", ctx.zkc_rewards.address())) .env("PRIVATE_KEY", format!("{:#x}", tx_signer.to_bytes())) .env("RISC0_DEV_MODE", "1") - .env("RPC_URL", ctx.anvil.lock().await.endpoint_url().as_str()) + .env("ETH_RPC_URL", ctx.anvil.lock().await.endpoint_url().as_str()) .env("POVW_PRIVATE_KEY", format!("{:#x}", work_log_signer.to_bytes())); let result = cmd.assert().success().stdout(contains("Work log update confirmed")); @@ -382,7 +382,7 @@ async fn claim_on_partially_finalized_epochs() -> anyhow::Result<()> { .env("VEZKC_ADDRESS", format!("{:#x}", ctx.zkc_rewards.address())) .env("PRIVATE_KEY", format!("{:#x}", tx_signer.to_bytes())) .env("RISC0_DEV_MODE", "1") - .env("RPC_URL", ctx.anvil.lock().await.endpoint_url().as_str()) + .env("ETH_RPC_URL", ctx.anvil.lock().await.endpoint_url().as_str()) .env("POVW_PRIVATE_KEY", format!("{:#x}", work_log_signer.to_bytes())); let result = cmd.assert().success().stdout(contains("Work log update confirmed"));