diff --git a/CHANGELOG.md b/CHANGELOG.md index dc4fabf9d..af50cc258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - [BREAKING] `CheckNullifiersByPrefix` now takes a starting block number (#707). - [BREAKING] Removed nullifiers from `SyncState` endpoint (#708). - [BREAKING] Added `batch_prover_url` to block producer configuration (#701). +- [BREAKING] Added `block_prover_url` to block producer configuration (#719). ### Enhancements diff --git a/README.md b/README.md index 3ae8aae55..b79dd22f9 100644 --- a/README.md +++ b/README.md @@ -185,14 +185,13 @@ or alternatively start the systemd service if that's how you wish to operate: systemctl start miden-node.service ``` -The `miden-node.toml` can be modified adding a batch prover URL, to delegate the batch proving: +The node will use local provers for blocks and batches, but you can configure the node to use remote provers by adding the following to the `miden-node.toml` file in the `[block-producer]` section: ```toml batch_prover_url = "" +block_prover_url = "" ``` -If this variable is not set, the node will use a local batch prover. - ### Monitoring and telemetry Please see our operator documentation [here](docs/operator.md). diff --git a/bin/node/src/config.rs b/bin/node/src/config.rs index c18d9b2ee..70f1d539d 100644 --- a/bin/node/src/config.rs +++ b/bin/node/src/config.rs @@ -28,6 +28,7 @@ struct NormalizedBlockProducerConfig { endpoint: Url, verify_tx_proofs: bool, batch_prover_url: Option, + block_prover_url: Option, } impl Default for NormalizedRpcConfig { @@ -50,11 +51,13 @@ impl Default for NormalizedBlockProducerConfig { store_url: _, verify_tx_proofs, batch_prover_url, + block_prover_url, } = BlockProducerConfig::default(); Self { endpoint, verify_tx_proofs, batch_prover_url, + block_prover_url, } } } @@ -68,6 +71,7 @@ impl NodeConfig { store_url: store.endpoint.clone(), verify_tx_proofs: block_producer.verify_tx_proofs, batch_prover_url: block_producer.batch_prover_url, + block_prover_url: block_producer.block_prover_url, }; let rpc = RpcConfig { @@ -103,6 +107,7 @@ mod tests { endpoint = "http://127.0.0.1:8080" verify_tx_proofs = true batch_prover_url = "http://127.0.0.1:8081" + block_prover_url = "http://127.0.0.1:8082" [rpc] endpoint = "http://127.0.0.1:8080" @@ -124,6 +129,7 @@ mod tests { endpoint: Url::parse("http://127.0.0.1:8080").unwrap(), verify_tx_proofs: true, batch_prover_url: Some(Url::parse("http://127.0.0.1:8081").unwrap()), + block_prover_url: Some(Url::parse("http://127.0.0.1:8082").unwrap()), }, rpc: NormalizedRpcConfig { endpoint: Url::parse("http://127.0.0.1:8080").unwrap(), diff --git a/config/miden-node.toml b/config/miden-node.toml index 8a4c4ec85..0e5354984 100644 --- a/config/miden-node.toml +++ b/config/miden-node.toml @@ -7,7 +7,9 @@ endpoint = "http://127.0.0.1:48046" # transaction queue. verify_tx_proofs = true # address of the remote batch prover service -batch_prover_url = "http://127.0.0.1:8082/" +batch_prover_url = "http://127.0.0.1:8081/" +# address of the remote block prover service +block_prover_url = "http://127.0.0.1:8082/" [rpc] # port defined as: sum(ord(c)**p for (p, c) in enumerate('miden-rpc', 1)) % 2**16 diff --git a/crates/block-producer/Cargo.toml b/crates/block-producer/Cargo.toml index 3e686067b..9ef77e9ba 100644 --- a/crates/block-producer/Cargo.toml +++ b/crates/block-producer/Cargo.toml @@ -29,6 +29,7 @@ miden-objects = { workspace = true } miden-processor = { workspace = true } miden-proving-service-client = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next", features = [ "batch-prover", + "block-prover", ] } miden-tx = { workspace = true } miden-tx-batch-prover = { git = "https://github.com/0xPolygonMiden/miden-base.git", branch = "next" } diff --git a/crates/block-producer/src/block_builder/mod.rs b/crates/block-producer/src/block_builder/mod.rs index 9a24f4aa4..7052f1402 100644 --- a/crates/block-producer/src/block_builder/mod.rs +++ b/crates/block-producer/src/block_builder/mod.rs @@ -9,9 +9,11 @@ use miden_objects::{ note::NoteHeader, MIN_PROOF_SECURITY_LEVEL, }; +use miden_proving_service_client::proving_service::block_prover::RemoteBlockProver; use rand::Rng; use tokio::time::Duration; -use tracing::{instrument, Span}; +use tracing::{info, instrument, Span}; +use url::Url; use crate::{ errors::BuildBlockError, mempool::SharedMempool, store::StoreClient, COMPONENT, @@ -34,17 +36,25 @@ pub struct BlockBuilder { pub store: StoreClient, /// The prover used to prove a proposed block into a proven block. - pub block_prover: LocalBlockProver, + pub block_prover: BlockProver, } impl BlockBuilder { - pub fn new(store: StoreClient) -> Self { + /// Creates a new [`BlockBuilder`] with the given [`StoreClient`] and optional block prover URL. + /// + /// If the block prover URL is not set, the block builder will use the local block prover. + pub fn new(store: StoreClient, block_prover_url: Option) -> Self { + let block_prover = match block_prover_url { + Some(url) => BlockProver::new_remote(url), + None => BlockProver::new_local(MIN_PROOF_SECURITY_LEVEL), + }; + Self { block_interval: SERVER_BLOCK_FREQUENCY, // Note: The range cannot be empty. simulated_proof_time: Duration::ZERO..Duration::from_millis(1), failure_rate: 0.0, - block_prover: LocalBlockProver::new(MIN_PROOF_SECURITY_LEVEL), + block_prover, store, } } @@ -190,10 +200,7 @@ impl BlockBuilder { &self, proposed_block: ProposedBlock, ) -> Result { - let proven_block = self - .block_prover - .prove(proposed_block) - .map_err(BuildBlockError::ProveBlockFailed)?; + let proven_block = self.block_prover.prove(proposed_block).await?; self.simulate_proving().await; @@ -352,3 +359,38 @@ impl TelemetryInjectorExt for ProvenBlock { span.set_attribute("block.commitments.transaction", header.tx_hash()); } } + +// BLOCK PROVER +// ================================================================================================ + +pub enum BlockProver { + Local(LocalBlockProver), + Remote(RemoteBlockProver), +} + +impl BlockProver { + pub fn new_local(security_level: u32) -> Self { + info!(target: COMPONENT, "Using local block prover"); + Self::Local(LocalBlockProver::new(security_level)) + } + + pub fn new_remote(endpoint: impl Into) -> Self { + info!(target: COMPONENT, "Using remote block prover"); + Self::Remote(RemoteBlockProver::new(endpoint)) + } + + #[instrument(target = COMPONENT, skip_all, err)] + pub async fn prove( + &self, + proposed_block: ProposedBlock, + ) -> Result { + match self { + Self::Local(prover) => { + prover.prove(proposed_block).map_err(BuildBlockError::ProveBlockFailed) + }, + Self::Remote(prover) => { + prover.prove(proposed_block).await.map_err(BuildBlockError::RemoteProverError) + }, + } + } +} diff --git a/crates/block-producer/src/config.rs b/crates/block-producer/src/config.rs index 41153fec0..278541b6a 100644 --- a/crates/block-producer/src/config.rs +++ b/crates/block-producer/src/config.rs @@ -25,7 +25,14 @@ pub struct BlockProducerConfig { pub verify_tx_proofs: bool, /// URL of the remote batch prover. + /// + /// If not set, the block producer will use the local batch prover. pub batch_prover_url: Option, + + /// URL of the remote block prover. + /// + /// If not set, the block producer will use the local block prover. + pub block_prover_url: Option, } impl Display for BlockProducerConfig { @@ -38,7 +45,14 @@ impl Display for BlockProducerConfig { .as_ref() .map_or_else(|| "None".to_string(), ToString::to_string); - write!(f, ", batch_prover_url: \"{batch_prover_url}\" }}") + write!(f, ", batch_prover_url: \"{batch_prover_url}\" }}")?; + + let block_prover_url = self + .block_prover_url + .as_ref() + .map_or_else(|| "None".to_string(), ToString::to_string); + + write!(f, ", block_prover_url: \"{block_prover_url}\" }}") } } @@ -53,6 +67,7 @@ impl Default for BlockProducerConfig { .unwrap(), verify_tx_proofs: true, batch_prover_url: None, + block_prover_url: None, } } } diff --git a/crates/block-producer/src/errors.rs b/crates/block-producer/src/errors.rs index ee6db4073..400153899 100644 --- a/crates/block-producer/src/errors.rs +++ b/crates/block-producer/src/errors.rs @@ -165,6 +165,8 @@ pub enum BuildBlockError { /// responses. #[error("nothing actually went wrong, failure was injected on purpose")] InjectedFailure, + #[error("failed to prove block with remote prover")] + RemoteProverError(#[source] RemoteProverError), } // Store errors diff --git a/crates/block-producer/src/server.rs b/crates/block-producer/src/server.rs index 8a97c0e56..49ed27080 100644 --- a/crates/block-producer/src/server.rs +++ b/crates/block-producer/src/server.rs @@ -82,7 +82,7 @@ impl BlockProducer { Ok(Self { batch_builder: BatchBuilder::new(config.batch_prover_url), - block_builder: BlockBuilder::new(store.clone()), + block_builder: BlockBuilder::new(store.clone(), config.block_prover_url), batch_budget: BatchBudget::default(), block_budget: BlockBudget::default(), state_retention: SERVER_MEMPOOL_STATE_RETENTION,