- nu-vm/engine.rs: execute_block runs all txs in a block against StateDb; TokenTransfer fully applied, other variants return "not implemented" receipt - StateAccessor trait: set_balance/inc_nonce now take &self (RocksDB interior mutability) - src/block_loop.rs: tokio task that produces a block each slot (6s) in dev mode; drains mempool, executes txs, removes successful ones, persists block to RocksDB - StateDb wrapped in Arc<Mutex> — block loop holds write lock per block, RPC holds read lock for nu_getAccount - main.rs: spawns block_loop when --dev --validator flags are set Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
81 lines
2 KiB
Rust
81 lines
2 KiB
Rust
mod block_loop;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use anyhow::Result;
|
|
use clap::Parser;
|
|
use tokio::sync::Mutex;
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
use nu_mempool::Mempool;
|
|
use nu_rpc::server::RpcServer;
|
|
use nu_state::StateDb;
|
|
|
|
#[derive(Parser)]
|
|
#[command(name = "nu-node", version)]
|
|
struct Cli {
|
|
/// Single-validator dev mode — no consensus, produces blocks every slot
|
|
#[arg(long)]
|
|
dev: bool,
|
|
|
|
/// Act as block-producing validator
|
|
#[arg(long)]
|
|
validator: bool,
|
|
|
|
/// Validator address (required when --validator is set)
|
|
#[arg(long, default_value = "0xDEV0000000000000000000000000000000000000")]
|
|
validator_addr: String,
|
|
|
|
/// JSON-RPC HTTP bind address
|
|
#[arg(long, default_value = "0.0.0.0:9545")]
|
|
rpc_addr: String,
|
|
|
|
/// RocksDB data directory
|
|
#[arg(long, default_value = "./data/state")]
|
|
db_path: String,
|
|
|
|
/// Chain identifier
|
|
#[arg(long, default_value = "nu-devnet-1")]
|
|
chain_id: String,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
tracing_subscriber::fmt()
|
|
.with_env_filter(EnvFilter::from_default_env())
|
|
.init();
|
|
|
|
let cli = Cli::parse();
|
|
|
|
let db = Arc::new(Mutex::new(StateDb::open(&cli.db_path)?));
|
|
tracing::info!("State DB opened at {}", cli.db_path);
|
|
|
|
let mempool = Arc::new(Mutex::new(Mempool::new()));
|
|
|
|
// Spawn block production loop in dev mode
|
|
if cli.dev && cli.validator {
|
|
let cfg = block_loop::BlockLoopConfig {
|
|
validator_addr: cli.validator_addr.clone(),
|
|
chain_id: cli.chain_id.clone(),
|
|
};
|
|
tokio::spawn(block_loop::run(cfg, Arc::clone(&db), Arc::clone(&mempool)));
|
|
}
|
|
|
|
let rpc = RpcServer::new(
|
|
cli.rpc_addr.clone(),
|
|
Arc::clone(&db),
|
|
Arc::clone(&mempool),
|
|
cli.chain_id.clone(),
|
|
);
|
|
|
|
tracing::info!(
|
|
chain_id = %cli.chain_id,
|
|
rpc_addr = %cli.rpc_addr,
|
|
dev = cli.dev,
|
|
validator = cli.validator,
|
|
"nu-node ready"
|
|
);
|
|
|
|
rpc.run().await?;
|
|
Ok(())
|
|
}
|