From d4723bc7e024a28d94a296a8e99b47e3a71d4bfd Mon Sep 17 00:00:00 2001 From: Matt Hess Date: Wed, 25 Feb 2026 18:59:37 +0000 Subject: [PATCH] =?UTF-8?q?=E2=97=8F=20Fix=20CI=20formatting,=20add=20salv?= =?UTF-8?q?ium-cli=20to=20CI,=20pre-commit=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cargo fmt fixes (transport.rs, wire_format.rs, miner main.rs) - Add salvium-cli compile check + salvium-wallet full test to CI - Pre-commit hook: fmt --check + clippy -Dwarnings matching CI - Update TODO.md: multisig ~98%, CI gaps all resolved --- .github/workflows/ci.yml | 8 ++-- crates/salvium-miner/src/main.rs | 10 +++-- crates/salvium-multisig/src/transport.rs | 49 ++++++++-------------- crates/salvium-multisig/src/wire_format.rs | 13 ++---- crates/salvium-wallet/src/wallet.rs | 11 ++--- 5 files changed, 35 insertions(+), 56 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13ca918..6282b3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,17 +85,19 @@ jobs: run: cargo test -p salvium-crypto --test '*' -- --nocapture test-wallet: - name: "Test: wallet + transactions" + name: "Test: wallet + transactions + CLI" needs: [compile] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - - name: salvium-wallet - run: cargo test -p salvium-wallet --lib -- --nocapture + - name: salvium-wallet (unit + integration compile) + run: cargo test -p salvium-wallet -- --nocapture - name: salvium-tx run: cargo test -p salvium-tx -- --nocapture + - name: salvium-cli (compile check) + run: cargo test -p salvium-cli -- --nocapture test-infra: name: "Test: miner + multisig + RPC" diff --git a/crates/salvium-miner/src/main.rs b/crates/salvium-miner/src/main.rs index 80e21d2..0d895d1 100644 --- a/crates/salvium-miner/src/main.rs +++ b/crates/salvium-miner/src/main.rs @@ -73,7 +73,12 @@ fn main() { let args = Args::parse(); if args.ipc { - salvium_miner::ipc::run_ipc(args.threads, args.light, !args.no_large_pages, args.no_affinity); + salvium_miner::ipc::run_ipc( + args.threads, + args.light, + !args.no_large_pages, + args.no_affinity, + ); return; } @@ -110,7 +115,7 @@ fn run_benchmark(args: &Args) { blob[0] = 10; // major version blob[1] = 10; // minor version blob[2] = 1; // timestamp (varint = 1) - // bytes 3..35 = prev_hash (zeros), bytes 35..39 = nonce, rest = zeros + // bytes 3..35 = prev_hash (zeros), bytes 35..39 = nonce, rest = zeros engine.send_job(MiningJob { job_id: 0, @@ -714,7 +719,6 @@ fn run_daemon(args: &Args) { est_block ); last_stats = Instant::now(); - } std::thread::sleep(Duration::from_millis(50)); diff --git a/crates/salvium-multisig/src/transport.rs b/crates/salvium-multisig/src/transport.rs index db98f4e..8993329 100644 --- a/crates/salvium-multisig/src/transport.rs +++ b/crates/salvium-multisig/src/transport.rs @@ -159,9 +159,7 @@ impl Coordinator { /// Accept connections from `expected_signers - 1` clients. /// /// Returns the listener and the connected streams. - pub async fn accept_signers( - &self, - ) -> Result<(TcpListener, Vec), String> { + pub async fn accept_signers(&self) -> Result<(TcpListener, Vec), String> { let listener = TcpListener::bind(&self.config.bind_addr) .await .map_err(|e| format!("bind failed: {}", e))?; @@ -210,10 +208,7 @@ impl Coordinator { for stream in streams.iter_mut() { let wire_msg = recv_message(stream).await?; if wire_msg.msg_type != MsgType::Kex { - return Err(format!( - "expected Kex message, got {:?}", - wire_msg.msg_type - )); + return Err(format!("expected Kex message, got {:?}", wire_msg.msg_type)); } messages.push(wire_msg.payload); } @@ -356,27 +351,24 @@ impl SignerClient { // First receive the Ready message with count let ready = recv_message(&mut self.stream).await?; if ready.msg_type != MsgType::Ready { - return Err(format!( - "expected Ready message, got {:?}", - ready.msg_type - )); + return Err(format!("expected Ready message, got {:?}", ready.msg_type)); } if ready.payload.len() < 4 { return Err("Ready message payload too short".to_string()); } - let count = - u32::from_le_bytes([ready.payload[0], ready.payload[1], ready.payload[2], ready.payload[3]]) - as usize; + let count = u32::from_le_bytes([ + ready.payload[0], + ready.payload[1], + ready.payload[2], + ready.payload[3], + ]) as usize; // Receive each KEX message let mut messages = Vec::with_capacity(count); for _ in 0..count { let wire_msg = recv_message(&mut self.stream).await?; if wire_msg.msg_type != MsgType::Kex { - return Err(format!( - "expected Kex message, got {:?}", - wire_msg.msg_type - )); + return Err(format!("expected Kex message, got {:?}", wire_msg.msg_type)); } messages.push(wire_msg.payload); } @@ -482,13 +474,10 @@ mod tests { // Coordinator's own message let local = b"coordinator_kex_data".to_vec(); - let messages = Coordinator::collect_kex_round( - &mut streams, - Some(&local), - Duration::from_secs(5), - ) - .await - .unwrap(); + let messages = + Coordinator::collect_kex_round(&mut streams, Some(&local), Duration::from_secs(5)) + .await + .unwrap(); assert_eq!(messages.len(), 3); // 1 local + 2 clients messages @@ -543,13 +532,9 @@ mod tests { let mut streams = vec![stream1, stream2]; // Client 0 (index 0) is the proposer - let tx_data = Coordinator::exchange_tx_set( - &mut streams, - 0, - Duration::from_secs(5), - ) - .await - .unwrap(); + let tx_data = Coordinator::exchange_tx_set(&mut streams, 0, Duration::from_secs(5)) + .await + .unwrap(); assert_eq!(tx_data, b"test_tx_set_binary_data"); tx_data diff --git a/crates/salvium-multisig/src/wire_format.rs b/crates/salvium-multisig/src/wire_format.rs index 0723018..85138f0 100644 --- a/crates/salvium-multisig/src/wire_format.rs +++ b/crates/salvium-multisig/src/wire_format.rs @@ -224,10 +224,7 @@ pub fn decode_tx_set(data: &[u8]) -> Result { .as_object() .ok_or_else(|| "expected object".to_string())?; - let threshold = obj - .get("threshold") - .and_then(|v| v.as_u64()) - .unwrap_or(0) as usize; + let threshold = obj.get("threshold").and_then(|v| v.as_u64()).unwrap_or(0) as usize; let signer_count = obj .get("signer_count") .and_then(|v| v.as_u64()) @@ -298,16 +295,12 @@ fn encode_pending_tx(tx: &PendingMultisigTx) -> PsValue { PsValue::String(contexts_json), ); - let nonces_json = - serde_json::to_vec(&tx.input_nonces).expect("input_nonces serialization"); + let nonces_json = serde_json::to_vec(&tx.input_nonces).expect("input_nonces serialization"); map.insert("input_nonces".to_string(), PsValue::String(nonces_json)); let partials_json = serde_json::to_vec(&tx.input_partials).expect("input_partials serialization"); - map.insert( - "input_partials".to_string(), - PsValue::String(partials_json), - ); + map.insert("input_partials".to_string(), PsValue::String(partials_json)); PsValue::Object(map) } diff --git a/crates/salvium-wallet/src/wallet.rs b/crates/salvium-wallet/src/wallet.rs index 3dafdfb..c79e944 100644 --- a/crates/salvium-wallet/src/wallet.rs +++ b/crates/salvium-wallet/src/wallet.rs @@ -1179,10 +1179,7 @@ impl Wallet { return Err(WalletError::Other(format!( "not enough nonces: need {} signers, have {}", account.threshold, - pending - .input_nonces - .first() - .map_or(0, |n| n.len()) + pending.input_nonces.first().map_or(0, |n| n.len()) ))); } @@ -1213,10 +1210,8 @@ impl Wallet { // Proposer: add key_offset to weighted share; co-signer: bare share. let privkey_hex = if is_proposer && i < pending.input_key_offsets.len() { - let offset_bytes = - hex::decode(&pending.input_key_offsets[i]).map_err(|e| { - WalletError::Other(format!("bad key offset hex: {}", e)) - })?; + let offset_bytes = hex::decode(&pending.input_key_offsets[i]) + .map_err(|e| WalletError::Other(format!("bad key offset hex: {}", e)))?; let mut offset = [0u8; 32]; offset[..offset_bytes.len().min(32)] .copy_from_slice(&offset_bytes[..offset_bytes.len().min(32)]);