Skip to content
Merged
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
3 changes: 3 additions & 0 deletions bin/benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,14 @@ nohup miden-remote-prover \
> logs/remote-prover.log 2>&1 &

# The node runs store + block-producer + RPC in a single sequencer process.
# Send collected fees to an arbitrary non-existent account ID for now.
BATCH_BUILDER_WALLET_ACCOUNT_ID=0xcc0000000000dd010000ee000000ff
nohup miden-node sequencer \
--data-directory "$DATA/node" \
--rpc.listen 127.0.0.1:57291 \
--validator.url http://127.0.0.1:50101 \
--ntx-builder.url http://127.0.0.1:50301 \
--batch.builder.wallet-account-id "$BATCH_BUILDER_WALLET_ACCOUNT_ID" \
--batch.max-txs 1024 \
--block.max-batches 64 \
--block.interval 2s \
Expand Down
37 changes: 37 additions & 0 deletions bin/node/src/commands/block_producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ use miden_node_block_producer::{
DEFAULT_MAX_TXS_PER_BATCH,
};
use miden_node_utils::clap::duration_to_human_readable_string;
use miden_protocol::account::AccountId;
use url::Url;

// BLOCK PRODUCTION
// ================================================================================================

#[derive(clap::Args, Clone, Debug)]
pub struct BlockProducerOptions {
#[command(flatten)]
pub builder: BuilderOptions,

#[command(flatten)]
pub batch: BatchOptions,

Expand Down Expand Up @@ -50,6 +54,10 @@ impl BlockProducerOptions {
);
}

if self.batch.max_txs.get() < 2 {
anyhow::bail!("batch.max-txs must be at least 2 to include the batch fee transaction");
}

Ok(())
}
}
Expand All @@ -64,6 +72,7 @@ mod tests {
BlockOptions,
BlockProducerOptions,
BlockProverOptions,
BuilderOptions,
MempoolOptions,
};
use crate::commands::block_producer::{
Expand All @@ -74,6 +83,12 @@ mod tests {

fn options(max_batches: usize, max_txs: usize) -> BlockProducerOptions {
BlockProducerOptions {
builder: BuilderOptions {
wallet_account_id: miden_protocol::account::AccountId::from_hex(
"0xcc0000000000dd010000ee000000ff",
)
.unwrap(),
},
batch: BatchOptions {
interval: DEFAULT_BATCH_INTERVAL,
max_txs: NonZeroUsize::new(max_txs).unwrap(),
Expand Down Expand Up @@ -124,6 +139,28 @@ mod tests {

assert!(err.to_string().contains("batch.max-txs"));
}

#[test]
fn rejects_max_txs_without_room_for_a_user_transaction() {
let err = options(miden_protocol::MAX_BATCHES_PER_BLOCK, 1)
.validate()
.expect_err("the batch must include a user transaction");

assert!(err.to_string().contains("batch.max-txs"));
}
}

#[derive(clap::Args, Clone, Debug)]
pub struct BuilderOptions {
/// Wallet account ID that receives the batch builder's fees.
#[arg(
long = "batch.builder.wallet-account-id",
env = "MIDEN_NODE_BATCH_BUILDER_WALLET_ACCOUNT_ID",
value_name = "ACCOUNT_ID",
value_parser = AccountId::from_hex,
help_heading = super::section::BLOCK_PRODUCTION_HELP_HEADING
)]
pub wallet_account_id: AccountId,
}

#[derive(clap::Args, Clone, Debug)]
Expand Down
4 changes: 2 additions & 2 deletions bin/node/src/commands/fee_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub enum FeeCollectorCommand {
/// Writes fee-collector.mac in the existing data directory. Refuses to overwrite an existing
/// file. Creation is offline. Keep the file private because it contains the signing key.
///
/// Use `miden-node fee-collector deploy` to deploy this account before collecting batch fees.
/// Use `miden-node fee-collector deploy` to deploy this account before starting the sequencer.
Create(CreateCommand),

/// Deploy a fee collector account in a dedicated block.
Expand All @@ -43,7 +43,7 @@ pub enum FeeCollectorCommand {
/// and pays no transaction fee. If the matching account is already deployed, the command
/// succeeds without creating another block.
///
/// Keep the account file and its signing key for fee collection.
/// After deployment, start the sequencer with the same account file.
Deploy(Box<DeployCommand>),
}

Expand Down
2 changes: 1 addition & 1 deletion bin/node/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub enum Command {
/// Create or deploy the sequencer's fee collector account.
///
/// The immutable collector combines transaction fees into P2ID notes for the batch builder's
/// wallet.
/// wallet. Create and deploy a collector before starting the sequencer.
#[command(subcommand)]
FeeCollector(FeeCollectorCommand),

Expand Down
16 changes: 14 additions & 2 deletions bin/node/src/commands/modes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use tokio::net::TcpListener;
use url::Url;

use super::block_producer::BlockProducerOptions;
use super::fee_collector::FeeCollectorAccountOptions;
use super::rpc::SyncOptions;
use super::runtime::{RuntimeConfig, RuntimeOptions};
use super::store::StoreOptions;
Expand All @@ -45,6 +46,9 @@ pub struct SequencerCommand {
#[command(flatten)]
pub runtime: RuntimeOptions,

#[command(flatten)]
pub fee_collector: FeeCollectorAccountOptions,

#[command(flatten)]
pub external_services: SequencerExternalServiceOptions,

Expand Down Expand Up @@ -73,10 +77,15 @@ pub struct SequencerCommand {
}

impl SequencerCommand {
#[expect(
clippy::too_many_lines,
reason = "Keep sequencer service startup and task supervision together"
)]
pub async fn handle(self, shutdown: CancellationToken) -> anyhow::Result<()> {
self.log_starting();
let runtime = self.runtime.runtime_config(&self.store);
self.block_producer.validate()?;
let fee_collector_account = self.fee_collector.read(&runtime.data_directory)?;
let network_tx_auth = self.runtime.rpc.network_tx_auth()?;
let (validator_clients, validator_monitors) =
self.external_services.validator_clients_and_monitors()?;
Expand Down Expand Up @@ -112,9 +121,12 @@ impl SequencerCommand {
max_concurrent_proofs: self.block_producer.block.max_concurrent_proofs,
mempool_tx_capacity: self.block_producer.mempool.tx_capacity,
batch_workers: self.block_producer.batch.workers,
builder_account_id: self.block_producer.builder.wallet_account_id,
fee_collector_account,
}
.spawn(shutdown.clone())
.context("failed to spawn sequencer")?;
.start(shutdown.clone())
.await
.context("failed to start sequencer")?;
let block_producer = sequencer.api();

let rpc = Rpc {
Expand Down
2 changes: 2 additions & 0 deletions compose/node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ services:
- --validator.url=http://validator-2:50101
- --validator.url=http://validator-3:50101
- --ntx-builder.url=http://ntx-builder:50301
# Send collected fees to an arbitrary non-existent account ID for now.
- --batch.builder.wallet-account-id=${MIDEN_NODE_BATCH_BUILDER_WALLET_ACCOUNT_ID:-0xcc0000000000dd010000ee000000ff}
- --rpc.network-tx-auth-header-value=secret_value
environment:
MIDEN_NODE_DISABLE_ACCOUNT_ALLOWLIST: "${MIDEN_NODE_DISABLE_ACCOUNT_ALLOWLIST:-true}"
Expand Down
Loading
Loading