Skip to content

Commit e8fb1bf

Browse files
authored
Merge pull request #28 from Steake/claude/resolve-merge-conflicts-01S8H7DHxRNV8Pa6Xpmz7hUz
Claude/resolve merge conflicts
2 parents fbe4197 + a68defe commit e8fb1bf

6 files changed

Lines changed: 59 additions & 49 deletions

File tree

crates/bitcell-node/src/blockchain.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl Blockchain {
132132
e.into_inner()
133133
}).get(&height).cloned()
134134
}
135-
135+
136136
/// Get transaction by hash using the O(1) hash index
137137
///
138138
/// Returns the transaction and its location (block height, index) if found.
@@ -146,7 +146,7 @@ impl Blockchain {
146146
});
147147
index.get(tx_hash).cloned()
148148
};
149-
149+
150150
// Then retrieve the actual transaction from the block
151151
if let Some(loc) = location {
152152
if let Some(block) = self.get_block(loc.block_height) {
@@ -155,10 +155,10 @@ impl Blockchain {
155155
}
156156
}
157157
}
158-
158+
159159
None
160160
}
161-
161+
162162
/// Get state manager (read-only access)
163163
pub fn state(&self) -> Arc<RwLock<StateManager>> {
164164
Arc::clone(&self.state)
@@ -196,7 +196,7 @@ impl Blockchain {
196196
});
197197
state.state_root
198198
};
199-
199+
200200
// Generate VRF output and proof using proper VRF chaining
201201
// For genesis block (height 1), use previous hash as input
202202
// For all other blocks, use the previous block's VRF output for chaining
@@ -216,15 +216,15 @@ impl Blockchain {
216216
tracing::error!("Lock poisoned in produce_block() - prior panic detected: {}", e);
217217
e.into_inner()
218218
});
219-
219+
220220
let vrf_input = if let Some(prev_block) = blocks.get(&current_height) {
221221
prev_block.header.vrf_output.to_vec()
222222
} else {
223223
// Fallback if previous block not found (shouldn't happen in normal operation)
224224
tracing::warn!("Previous block {} not found for VRF chaining, using hash fallback", current_height);
225225
prev_hash.as_bytes().to_vec()
226226
};
227-
227+
228228
// Generate VRF proof while still holding the read lock to prevent race conditions
229229
let (vrf_output, vrf_proof) = self.secret_key.vrf_prove(&vrf_input);
230230
(vrf_output, bincode::serialize(&vrf_proof).unwrap_or_default())
@@ -282,11 +282,11 @@ impl Blockchain {
282282
if block.signature.verify(&block.header.proposer, header_hash.as_bytes()).is_err() {
283283
return Err(crate::Error::Node("Invalid block signature".to_string()));
284284
}
285-
285+
286286
// Verify VRF proof using proper VRF chaining
287287
let vrf_proof: bitcell_crypto::VrfProof = bincode::deserialize(&block.header.vrf_proof)
288288
.map_err(|_| crate::Error::Node("Invalid VRF proof format".to_string()))?;
289-
289+
290290
// Reconstruct VRF input using the same chaining logic as produce_block
291291
let vrf_input = if block.header.height == 1 {
292292
// First block after genesis uses genesis hash as VRF input

crates/bitcell-node/src/network.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ impl NetworkManager {
102102
tracing::info!("DHT enabled");
103103
Ok(())
104104
}
105+
106+
105107

106108
/// Start the network listener
107109
///
@@ -588,7 +590,7 @@ impl NetworkManager {
588590
let guard = self.dht.read();
589591
guard.clone()
590592
};
591-
593+
592594
if let Some(dht) = dht_opt {
593595
if let Err(e) = dht.broadcast_block(block).await {
594596
tracing::error!("Failed to broadcast block via DHT: {}", e);
@@ -622,7 +624,7 @@ impl NetworkManager {
622624
let guard = self.dht.read();
623625
guard.clone()
624626
};
625-
627+
626628
if let Some(dht) = dht_opt {
627629
if let Err(e) = dht.broadcast_transaction(tx).await {
628630
tracing::error!("Failed to broadcast transaction via DHT: {}", e);

crates/bitcell-node/src/rpc.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,10 @@ async fn eth_get_block_by_number(state: &RpcState, params: Option<Value>) -> Res
228228
.collect();
229229
json!(tx_hashes)
230230
};
231-
231+
232232
// Calculate actual block size
233233
let block_size = bincode::serialized_size(&block).unwrap_or(0);
234-
234+
235235
Ok(json!({
236236
"number": format!("0x{:x}", block.header.height),
237237
"hash": format!("0x{}", hex::encode(block.hash().as_bytes())),
@@ -305,7 +305,7 @@ async fn eth_get_transaction_by_hash(state: &RpcState, params: Option<Value>) ->
305305
let mut hash = [0u8; 32];
306306
hash.copy_from_slice(&tx_hash_bytes);
307307
let target_hash = bitcell_crypto::Hash256::from(hash);
308-
308+
309309
// Use efficient O(1) lookup via transaction hash index
310310
if let Some((tx, location)) = state.blockchain.get_transaction_by_hash(&target_hash) {
311311
// Get the block to include block hash in response
@@ -325,7 +325,7 @@ async fn eth_get_transaction_by_hash(state: &RpcState, params: Option<Value>) ->
325325
}));
326326
}
327327
}
328-
328+
329329
Ok(Value::Null)
330330
}
331331

@@ -387,7 +387,8 @@ async fn eth_get_balance(state: &RpcState, params: Option<Value>) -> Result<Valu
387387
.map(|account| account.balance)
388388
.unwrap_or(0)
389389
};
390-
390+
391+
391392
// Return balance as hex string
392393
Ok(json!(format!("0x{:x}", balance)))
393394
}
@@ -405,7 +406,7 @@ async fn eth_get_transaction_count(state: &RpcState, params: Option<Value>) -> R
405406
message: "Params must be an array".to_string(),
406407
data: None,
407408
})?;
408-
409+
409410
if args.is_empty() {
410411
return Err(JsonRpcError {
411412
code: -32602,
@@ -427,18 +428,18 @@ async fn eth_get_transaction_count(state: &RpcState, params: Option<Value>) -> R
427428
message: "Invalid address format".to_string(),
428429
data: None,
429430
})?;
430-
431+
431432
if address_bytes.len() != 33 {
432433
return Err(JsonRpcError {
433434
code: -32602,
434435
message: "Address must be 33 bytes (compressed public key)".to_string(),
435436
data: None,
436437
});
437438
}
438-
439+
439440
let mut address = [0u8; 33];
440441
address.copy_from_slice(&address_bytes);
441-
442+
442443
// Fetch nonce from blockchain state
443444
let nonce = {
444445
let state_lock = state.blockchain.state();
@@ -451,7 +452,7 @@ async fn eth_get_transaction_count(state: &RpcState, params: Option<Value>) -> R
451452
.map(|account| account.nonce)
452453
.unwrap_or(0)
453454
};
454-
455+
455456
// Return nonce as hex string
456457
Ok(json!(format!("0x{:x}", nonce)))
457458
}
@@ -460,7 +461,7 @@ async fn eth_get_transaction_count(state: &RpcState, params: Option<Value>) -> R
460461
const DEFAULT_GAS_PRICE: u64 = 1_000_000_000;
461462

462463
/// Get current gas price
463-
///
464+
///
464465
/// Returns the current gas price. In production, this should be
465466
/// dynamically calculated based on network congestion and mempool state.
466467
async fn eth_gas_price(_state: &RpcState) -> Result<Value, JsonRpcError> {
@@ -565,36 +566,36 @@ async fn eth_send_raw_transaction(state: &RpcState, params: Option<Value>) -> Re
565566
data: None,
566567
});
567568
}
568-
569+
569570
// Validate gas parameters to prevent spam and overflow attacks
570571
// Gas price and limit must be non-zero and within reasonable bounds
571572
const MAX_GAS_PRICE: u64 = 10_000_000_000_000; // 10,000 Gwei max
572573
const MAX_GAS_LIMIT: u64 = 30_000_000; // 30M gas max (similar to Ethereum block limit)
573-
574+
574575
if tx.gas_price == 0 || tx.gas_limit == 0 {
575576
return Err(JsonRpcError {
576577
code: -32602,
577578
message: "Transactions from new accounts require non-zero gas price and limit to prevent DoS attacks".to_string(),
578579
data: None,
579580
});
580581
}
581-
582+
582583
if tx.gas_price > MAX_GAS_PRICE {
583584
return Err(JsonRpcError {
584585
code: -32602,
585586
message: format!("Gas price {} exceeds maximum allowed {}", tx.gas_price, MAX_GAS_PRICE),
586587
data: None,
587588
});
588589
}
589-
590+
590591
if tx.gas_limit > MAX_GAS_LIMIT {
591592
return Err(JsonRpcError {
592593
code: -32602,
593594
message: format!("Gas limit {} exceeds maximum allowed {}", tx.gas_limit, MAX_GAS_LIMIT),
594595
data: None,
595596
});
596597
}
597-
598+
598599
tracing::debug!(
599600
from = %hex::encode(tx.from.as_bytes()),
600601
"Allowing transaction from new account with nonce 0"

crates/bitcell-state/src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ pub enum Error {
3131

3232
#[error("Invalid bond")]
3333
InvalidBond,
34-
34+
3535
#[error("Balance overflow")]
3636
BalanceOverflow,
37-
37+
3838
#[error("Storage error: {0}")]
3939
StorageError(String),
4040
}
@@ -116,7 +116,8 @@ impl StateManager {
116116
/// in memory (eventual consistency model).
117117
pub fn update_account(&mut self, pubkey: [u8; 33], account: Account) {
118118
self.accounts.insert(pubkey, account.clone());
119-
119+
120+
120121
// Persist to storage if available
121122
if let Some(storage) = &self.storage {
122123
if let Err(e) = storage.store_account(&pubkey, &account) {
@@ -160,7 +161,8 @@ impl StateManager {
160161
/// in memory (eventual consistency model).
161162
pub fn update_bond(&mut self, pubkey: [u8; 33], bond: BondState) {
162163
self.bonds.insert(pubkey, bond.clone());
163-
164+
165+
164166
// Persist to storage if available
165167
if let Some(storage) = &self.storage {
166168
if let Err(e) = storage.store_bond(&pubkey, &bond) {

crates/bitcell-zkp/src/battle_circuit.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@
1111
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
1212
use ark_bn254::Fr;
1313

14+
use ark_ff::Field;
15+
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError};
16+
use ark_bn254::Fr;
17+
1418
/// Battle circuit configuration
15-
///
19+
///
1620
/// Proves that a battle between two players resulted in the claimed winner.
1721
/// Winner ID meanings:
1822
/// - 0: Draw (no winner)
@@ -162,15 +166,15 @@ mod tests {
162166
Fr::one(), // commitment B
163167
Fr::from(1u8), // winner ID
164168
];
165-
169+
166170
assert!(BattleCircuit::verify(&vk, &proof, &public_inputs).unwrap());
167171
}
168-
172+
169173
#[test]
170174
fn test_battle_circuit_all_winner_ids() {
171175
// Test that all valid winner IDs (0, 1, 2) work
172176
let (pk, vk) = BattleCircuit::setup().expect("Circuit setup should succeed");
173-
177+
174178
for winner_id in [0u8, 1u8, 2u8] {
175179
let circuit = BattleCircuit::new(
176180
Fr::one(),
@@ -179,15 +183,15 @@ mod tests {
179183
100,
180184
200,
181185
);
182-
186+
183187
let proof = circuit.prove(&pk).unwrap_or_else(|_| panic!("Proof should succeed for winner_id {}", winner_id));
184-
188+
185189
let public_inputs = vec![
186190
Fr::one(),
187191
Fr::one(),
188192
Fr::from(winner_id),
189193
];
190-
194+
191195
assert!(
192196
BattleCircuit::verify(&vk, &proof, &public_inputs).unwrap(),
193197
"Verification should succeed for winner_id {}",

0 commit comments

Comments
 (0)