Skip to content

Commit f63e952

Browse files
authored
Merge branch 'master' into tournament-mii-plus-system
2 parents 43d9e05 + 590fa57 commit f63e952

25 files changed

Lines changed: 6035 additions & 64 deletions

.github/copilot-setup-steps.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Configuration for GitHub Copilot Coding Agent
2+
# This file specifies the runner and setup steps for Copilot
3+
4+
runs-on: ubuntu-22.04-xl
5+
6+
steps:
7+
- name: Install Rust toolchain
8+
uses: dtolnay/rust-toolchain@stable
9+
with:
10+
components: rustfmt, clippy
11+
12+
- name: Cache cargo registry
13+
uses: actions/cache@v4
14+
with:
15+
path: |
16+
~/.cargo/registry
17+
~/.cargo/git
18+
target
19+
key: ${{ runner.os }}-cargo-stable-${{ hashFiles('**/Cargo.lock') }}
20+
restore-keys: |
21+
${{ runner.os }}-cargo-

.github/workflows/release.yml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [created]
6+
workflow_dispatch:
7+
8+
env:
9+
CARGO_TERM_COLOR: always
10+
RUST_BACKTRACE: 1
11+
12+
jobs:
13+
build:
14+
name: Build ${{ matrix.target }}
15+
runs-on: ${{ matrix.os }}
16+
permissions:
17+
contents: read
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
include:
22+
- os: ubuntu-latest
23+
target: x86_64-unknown-linux-gnu
24+
artifact_name: bitcell-linux-x86_64
25+
- os: macos-latest
26+
target: x86_64-apple-darwin
27+
artifact_name: bitcell-macos-x86_64
28+
- os: macos-14 # Native ARM64 runner
29+
target: aarch64-apple-darwin
30+
artifact_name: bitcell-macos-aarch64
31+
- os: windows-latest
32+
target: x86_64-pc-windows-msvc
33+
artifact_name: bitcell-windows-x86_64
34+
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- name: Install Rust
39+
uses: dtolnay/rust-toolchain@stable
40+
with:
41+
targets: ${{ matrix.target }}
42+
43+
- name: Cache cargo registry
44+
uses: actions/cache@v4
45+
with:
46+
path: |
47+
~/.cargo/registry
48+
~/.cargo/git
49+
target
50+
key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
51+
restore-keys: |
52+
${{ runner.os }}-${{ matrix.target }}-cargo-
53+
54+
- name: Build release binaries
55+
run: cargo build --release --target ${{ matrix.target }} -p bitcell-node -p bitcell-admin
56+
57+
- name: Create artifact directory
58+
shell: bash
59+
run: mkdir -p artifacts
60+
61+
- name: Copy binaries (Unix)
62+
if: runner.os != 'Windows'
63+
shell: bash
64+
run: |
65+
cp target/${{ matrix.target }}/release/bitcell-node artifacts/
66+
cp target/${{ matrix.target }}/release/bitcell-admin artifacts/
67+
68+
- name: Copy binaries (Windows)
69+
if: runner.os == 'Windows'
70+
shell: bash
71+
run: |
72+
cp target/${{ matrix.target }}/release/bitcell-node.exe artifacts/
73+
cp target/${{ matrix.target }}/release/bitcell-admin.exe artifacts/
74+
75+
- name: Create archive (Unix)
76+
if: runner.os != 'Windows'
77+
shell: bash
78+
run: |
79+
cd artifacts
80+
tar -czvf ../${{ matrix.artifact_name }}.tar.gz *
81+
cd ..
82+
83+
- name: Create archive (Windows)
84+
if: runner.os == 'Windows'
85+
shell: pwsh
86+
run: |
87+
Compress-Archive -Path artifacts/* -DestinationPath ${{ matrix.artifact_name }}.zip
88+
89+
- name: Upload artifact (Unix)
90+
if: runner.os != 'Windows'
91+
uses: actions/upload-artifact@v4
92+
with:
93+
name: ${{ matrix.artifact_name }}
94+
path: ${{ matrix.artifact_name }}.tar.gz
95+
retention-days: 7
96+
97+
- name: Upload artifact (Windows)
98+
if: runner.os == 'Windows'
99+
uses: actions/upload-artifact@v4
100+
with:
101+
name: ${{ matrix.artifact_name }}
102+
path: ${{ matrix.artifact_name }}.zip
103+
retention-days: 7
104+
105+
release:
106+
name: Upload Release Assets
107+
needs: build
108+
runs-on: ubuntu-latest
109+
if: github.event_name == 'release'
110+
permissions:
111+
contents: write
112+
113+
steps:
114+
- name: Download all artifacts
115+
uses: actions/download-artifact@v4
116+
with:
117+
path: artifacts
118+
119+
- name: Display structure of downloaded files
120+
run: ls -la artifacts/
121+
122+
- name: Upload release assets
123+
uses: softprops/action-gh-release@v2
124+
with:
125+
files: |
126+
artifacts/bitcell-linux-x86_64/bitcell-linux-x86_64.tar.gz
127+
artifacts/bitcell-macos-x86_64/bitcell-macos-x86_64.tar.gz
128+
artifacts/bitcell-macos-aarch64/bitcell-macos-aarch64.tar.gz
129+
artifacts/bitcell-windows-x86_64/bitcell-windows-x86_64.zip
130+
env:
131+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ members = [
1212
"crates/bitcell-node",
1313
"crates/bitcell-admin",
1414
"crates/bitcell-simulation",
15+
"crates/bitcell-wallet",
1516
]
1617
resolver = "2"
1718

@@ -75,6 +76,7 @@ parking_lot = "0.12"
7576
rayon = "1.8"
7677
dashmap = "5.5"
7778
bytes = "1.5"
79+
zeroize = { version = "1.8", features = ["derive"] }
7880

7981
[profile.release]
8082
opt-level = 3

crates/bitcell-node/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ pub struct NodeConfig {
1111
pub enable_dht: bool,
1212
pub bootstrap_nodes: Vec<String>,
1313
pub key_seed: Option<String>,
14+
/// Block production interval in seconds.
15+
/// Defaults to 10 seconds for testing. Use 600 (10 minutes) for production.
16+
pub block_time_secs: u64,
1417
}
1518

1619
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -29,6 +32,7 @@ impl Default for NodeConfig {
2932
enable_dht: false, // Disabled by default for backwards compatibility
3033
bootstrap_nodes: vec![],
3134
key_seed: None,
35+
block_time_secs: 10, // Default to 10 seconds for testing
3236
}
3337
}
3438
}

crates/bitcell-node/src/network.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ use tokio::net::{TcpListener, TcpStream};
1111
use tokio::io::{AsyncReadExt, AsyncWriteExt};
1212
use serde::{Serialize, Deserialize};
1313

14+
/// Maximum message size limit (10MB) to prevent memory exhaustion attacks
15+
const MAX_MESSAGE_SIZE: usize = 10_000_000;
16+
1417
/// Network message types
1518
#[derive(Debug, Clone, Serialize, Deserialize)]
1619
pub enum NetworkMessage {
@@ -377,7 +380,7 @@ impl NetworkManager {
377380
.map_err(|e| format!("Read error: {}", e))?;
378381
let len = u32::from_be_bytes(len_bytes) as usize;
379382

380-
if len > 10_000_000 { // 10MB safety limit
383+
if len > MAX_MESSAGE_SIZE {
381384
return Err("Message too large".into());
382385
}
383386

@@ -398,7 +401,7 @@ impl NetworkManager {
398401
.map_err(|e| format!("Read error: {}", e))?;
399402
let len = u32::from_be_bytes(len_bytes) as usize;
400403

401-
if len > 10_000_000 { // 10MB safety limit
404+
if len > MAX_MESSAGE_SIZE {
402405
return Err("Message too large".into());
403406
}
404407

crates/bitcell-node/src/validator.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ use std::sync::Arc;
99
use std::time::Duration;
1010
use tokio::time;
1111

12-
/// Block production interval (10 seconds for testing, TODO: make this 10 minutes in production)
13-
const BLOCK_TIME_SECS: u64 = 10;
14-
1512
/// Max transactions per block
1613
const MAX_TXS_PER_BLOCK: usize = 1000;
1714

@@ -167,9 +164,10 @@ impl ValidatorNode {
167164
let secret_key = self.secret_key.clone();
168165
let tournament_manager = self.tournament_manager.clone();
169166
let network = self.network.clone();
167+
let block_time_secs = self.config.block_time_secs;
170168

171169
tokio::spawn(async move {
172-
let mut interval = time::interval(Duration::from_secs(BLOCK_TIME_SECS));
170+
let mut interval = time::interval(Duration::from_secs(block_time_secs));
173171
let mut next_height = 1u64;
174172

175173
loop {

crates/bitcell-state/src/storage.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,19 @@ impl StorageManager {
162162
}
163163

164164
/// Prune old blocks (keep last N blocks)
165+
///
166+
/// # TODO: Production Implementation
167+
/// This is a simplified implementation for development. A production version should:
168+
/// - Use iterators for efficient range deletion
169+
/// - Delete associated transactions and state roots
170+
/// - Handle edge cases (e.g., concurrent reads during pruning)
171+
/// - Optionally archive pruned blocks to cold storage
172+
///
173+
/// # Arguments
174+
/// * `keep_last` - Number of recent blocks to retain
175+
///
176+
/// # Returns
177+
/// * `Ok(())` on success, or error message on failure
165178
pub fn prune_old_blocks(&self, keep_last: u64) -> Result<(), String> {
166179
let latest = self.get_latest_height()?.unwrap_or(0);
167180
if latest <= keep_last {
@@ -170,17 +183,20 @@ impl StorageManager {
170183

171184
let prune_until = latest - keep_last;
172185

173-
// Verify blocks column family exists
174-
self.db.cf_handle(CF_BLOCKS)
186+
// Get column family handles
187+
let cf_blocks = self.db.cf_handle(CF_BLOCKS)
175188
.ok_or_else(|| "Blocks column family not found".to_string())?;
189+
let cf_headers = self.db.cf_handle(CF_HEADERS)
190+
.ok_or_else(|| "Headers column family not found".to_string())?;
176191

177-
// This is a simplified version - in production would iterate and delete
192+
// Iterate and delete blocks and headers for heights less than prune_until
178193
for height in 0..prune_until {
179-
if let Some(header_data) = self.get_header_by_height(height)? {
180-
// Extract hash and delete block
181-
// (Simplified - would need proper header deserialization)
182-
let _ = header_data;
183-
}
194+
// Delete block by height
195+
self.db.delete_cf(cf_blocks, height.to_be_bytes())
196+
.map_err(|e| format!("Failed to delete block at height {}: {}", height, e))?;
197+
// Delete header by height
198+
self.db.delete_cf(cf_headers, height.to_be_bytes())
199+
.map_err(|e| format!("Failed to delete header at height {}: {}", height, e))?;
184200
}
185201

186202
Ok(())

crates/bitcell-wallet/Cargo.toml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
[package]
2+
name = "bitcell-wallet"
3+
version.workspace = true
4+
authors.workspace = true
5+
edition.workspace = true
6+
rust-version.workspace = true
7+
license.workspace = true
8+
repository.workspace = true
9+
description = "Modular wallet for BitCell blockchain with multi-chain support"
10+
11+
[dependencies]
12+
bitcell-crypto = { path = "../bitcell-crypto" }
13+
bitcell-state = { path = "../bitcell-state" }
14+
15+
# Cryptography
16+
sha2.workspace = true
17+
blake3.workspace = true
18+
k256.workspace = true
19+
rand.workspace = true
20+
rand_core.workspace = true
21+
hex.workspace = true
22+
23+
# BIP39/BIP32 seed phrases
24+
bip39 = "2.0"
25+
hmac = "0.12"
26+
pbkdf2 = { version = "0.12", default-features = false }
27+
28+
# Encoding
29+
bs58 = "0.5"
30+
31+
# Serialization
32+
serde.workspace = true
33+
serde_json = "1.0"
34+
bincode.workspace = true
35+
36+
# Error handling
37+
thiserror.workspace = true
38+
39+
# Utilities
40+
zeroize.workspace = true
41+
parking_lot.workspace = true
42+
43+
[dev-dependencies]
44+
proptest.workspace = true
45+
46+
[features]
47+
default = []
48+
bitcoin = []
49+
ethereum = []

0 commit comments

Comments
 (0)