Skip to content

Commit

Permalink
Structural Changes & Bug fixing for v0.1.0-pre.alpha.3
Browse files Browse the repository at this point in the history
  • Loading branch information
rustyspottedcatt committed Feb 8, 2025
1 parent 6888214 commit 2a8bf4c
Show file tree
Hide file tree
Showing 17 changed files with 356 additions and 378 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/target
/.idea
/nebula_db
/nebula_db
/.cargo
/*.tar.gz
34 changes: 26 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
[package]
name = "nebulacrypto"
name = "nebula"
version = "0.1.0-pre.alpha.3"
edition = "2024"
authors = ["NEBYTE [email protected]"]
description = "Nebula is a blockchain-based system that replicates ICP’s architecture—including neurons, governance, canisters, transactions, and staking. It uses ed25519-dalek for key management and transaction signing."
license = "AGPL-3"
readme = "README.md"
repository = "https://github.com/NEBYTE/nebula"

[dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros", "full"] }
Expand All @@ -13,14 +18,27 @@ chrono = { version = "0.4.39", features = ["serde"]}
sha2 = "0.10.8"
hex = "0.4.3"

[package.metadata.deb]
maintainer = "NEBYTE [email protected]"
copyright = "2025, NEBYTE"
license-file = ["LICENSE"]
depends = "libssl-dev"
section = "utils"
priority = "optional"
assets = [
["target/release/nebula", "/usr/bin/", "755"],
]

[[bin]]
name = "nebula"
path = "src/main.rs"

[lib]
name = "nebula"
path = "src/lib.rs"

[[test]]
name = "transactions"
path = "tests/transactions.rs"

[[test]]
name = "staking"
path = "tests/staking.rs"
[profile.release]
strip = true
opt-level = "z"
lto = true
panic = "abort"
213 changes: 76 additions & 137 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

> **NOTE:** Nebula is still under heavy development. Expect bugs and frequent API changes.
Nebula is a blockchain-based system that replicates ICP’s architecture—including neurons, governance, canisters, transactions, and staking. It uses **ed25519-dalek** for key management and transaction signing.
Nebula is a blockchain-based system that replicates ICP’s architecture—including neurons, governance, canisters, transactions, and staking. It utilizes **ed25519-dalek** for key management and transaction signing.

---

Expand All @@ -22,7 +22,8 @@ Nebula is a blockchain-based system that replicates ICP’s architecture—inclu
- [Installation](#installation)
- [Usage](#usage)
- [Wallet Management](#wallet-management)
- [Transaction Processing (Direct and via Canisters)](#transaction-processing)
- [Transaction Processing](#transaction-processing)
- [Canister Transactions](#canister-transactions)
- [Block Production](#block-production)
- [Neuron Management](#neuron-management)
- [Staking](#staking)
Expand All @@ -34,13 +35,13 @@ Nebula is a blockchain-based system that replicates ICP’s architecture—inclu

## Features

- **Wallet Management:** Generate wallets with private keys, public keys, and blockchain-compatible addresses.
- **Transaction Processing:** Build, sign, and submit transactions with dynamic fee and index calculation.
- **Consensus Engine:** Validator selection, block production, and transaction verification.
- **Governance:** Neuron-based proposals and voting.
- **Nervous System:** Neuron creation, locking/unlocking, and stake delegation.
- **Staking:** Secure staking and unstaking of tokens.
- **Canisters:** Wrap functionality (e.g., transaction submission, staking) into canisters for modularity and secure isolation.
- **Wallet Management** - Create and manage wallets with private/public keys and blockchain-compatible addresses.
- **Transaction Processing** - Build, sign, and submit transactions securely.
- **Consensus Engine** - Validator selection, block production, and transaction verification.
- **Governance** - Neuron-based proposals and voting.
- **Nervous System** - Neuron creation, locking/unlocking, and stake delegation.
- **Staking** - Secure staking and unstaking of tokens.
- **Canisters** - Modular execution of functions via on-chain canisters.

---

Expand Down Expand Up @@ -76,183 +77,120 @@ cargo run

### Wallet Management

Create a wallet using the built-in function. The wallet returns a private key, a public key (as a VerifyingKey), and an address.

```rust
use crate::core::api::v1::wallet::create_wallet;

let (signing_key, public_key, address) = create_wallet();
println!("Wallet created: {:x?}", address); // Shareable address
println!("Public Key: {:?}", public_key); // Safe to share
println!("Private Key: {:?}", signing_key); // DO NOT SHARE!
// Create a new wallet
let (signing_key, public_key, sender_address) = create_wallet();
println!("Sender Wallet created: {:x?}", sender_address);

let (_receiver_signing, receiver_public, receiver_address) = create_wallet();
println!("Receiver Wallet created: {:x?}", receiver_address);
```

### Transaction Processing
---

#### Direct Transaction Creation
### Transaction Processing

The following example shows how to build, sign, and submit a transaction directly using the consensus engine (without a canister).
#### Direct Transaction

```rust
use crate::core::api::v1::transaction::{build_transaction, finalize_transaction, submit_transaction};
use crate::core::api::v1::transaction::{build_transaction, finalize_transaction};
use crate::core::types::TransactionType;

// Assume consensus_engine is already initialized and sender/receiver ledger accounts exist.
let amount = 50;
let mut tx = build_transaction(
&mut consensus_engine,
sender_address, // sender's address
receiver_address, // receiver's address
amount,
0, // memo
0, // nrc_memo
TransactionType::Transfer
);
finalize_transaction(&mut tx, &signing_key)?; // Signs the transaction
submit_transaction(&mut consensus_engine, tx)?; // Submits to the mempool
sender_address.clone(),
receiver_address.clone(),
50, // Amount
0, // Memo
0, // NRC Memo
TransactionType::Transfer,
);

// above assumes ledger were made with the sufficient balance for the sender address.

finalize_transaction(&mut tx, &signing_key).expect("Failed to finalize transaction");
```

#### Transaction Submission via Canisters
---

Nebula allows you to wrap functionality in a canister. In the example below, we create a canister, initialize ledger accounts for sender and receiver, build and sign a transaction, then submit it via the canister.
### Canister Transactions

```rust
use crate::core::api::v1::transaction::{submit_transaction, build_transaction, finalize_transaction};
use crate::core::api::v1::wallet::create_wallet;
use crate::core::canister::canister::{Canister, CanisterFunctionPayload};
use crate::core::canister::registry::CanisterRegistry;
use crate::core::consensus::{ValidatorInfo};
use crate::core::consensus::model::ConsensusEngine;
use crate::core::nervous::NervousSystem;
use crate::core::types::TransactionType;

#[tokio::main]
async fn main() {
// Create wallet for sender.
let (signing_key, public_key, address) = create_wallet();
println!("Wallet created: {:x?}", address);

// Create and register a canister.
let mut canister_registry = CanisterRegistry::new();
let canister_id = "my_canister".to_string();
let canister = Canister::new(canister_id.clone(), address.clone());
println!("Canister ID: {}", canister.canister_id);
canister_registry.register_canister(&canister_id, canister);
let mut registered_canister = match canister_registry.get_canister(&canister_id) {
Some(c) => c,
None => {
eprintln!("Canister '{}' not found", canister_id);
return;
}
};

// Use canister-based API to submit a transaction.
{
// Create a wallet for the receiver.
let (_signing_key1, public_key1, address1) = create_wallet();

// Initialize the Nervous System and Consensus Engine.
let nervous_system = NervousSystem::new();
let validators = vec![ValidatorInfo { address: address.clone(), active: true }];
let mut consensus_engine = ConsensusEngine::new(validators, nervous_system.neurons.clone());

// Initialize ledger accounts for sender and receiver.
consensus_engine.init_ledger(address.clone(), public_key, 100)
.expect("Failed to initialize sender ledger");
consensus_engine.init_ledger(address1.clone(), public_key1, 0)
.expect("Failed to initialize receiver ledger");

let amount = 50;
// Build and sign the transaction.
let mut tx = build_transaction(
&mut consensus_engine,
address.clone(),
address1.clone(),
amount,
0,
0,
TransactionType::Transfer
);
finalize_transaction(&mut tx, &signing_key)
.expect("Failed to sign the transaction");

// Create a transfer payload for the canister.
let transfer_payload = CanisterFunctionPayload::Transfer {
consensus_engine: &mut consensus_engine,
tx,
};

// Execute the transaction via the canister.
match registered_canister.execute_function(transfer_payload) {
Ok(msg) => println!("Successfully sent transfer: {}", msg),
Err(err) => eprintln!("Transfer failed: {}", err),
}
}
}
// Register a canister
let mut canister_registry = CanisterRegistry::new();
let canister = Canister::new("my_canister".to_string(), sender_address.clone());
println!("Canister created with ID: {}", canister.canister_id);

canister_registry.register_canister(&canister.canister_id, canister.clone());
```

### Block Production
---

After transactions are in the mempool, you can produce a block:
### Block Production

```rust
use crate::core::consensus::block::produce_block;

let block = produce_block(&mut consensus_engine, &signing_key)?;
println!("Block produced with {} transactions", block.transactions.len());
println!("Block timestamp: {}", block.header.timestamp);
use crate::core::consensus::consensus::run_consensus_loop;
use std::time::Duration;

let target_cycle = Duration::from_secs(1 / 2); // 0.5s
let signing_key_clone = signing_key.clone();
let mut consensus_engine_clone = consensus_engine.clone(); // consensus_engine uses Arc<Mutex<T>>, everything is synchronized.

tokio::spawn(async move {
run_consensus_loop(
&mut consensus_engine_clone,
&signing_key_clone,
target_cycle,
).await;
});
println!("🚀 Blockchain node is running! Listening for transactions...");
```

### Neuron Management
---

Create a neuron for governance:
### Neuron Management

```rust
use crate::core::nervous::neuron_handler::create_neuron;
use crate::core::nervous::{create_neuron, NervousSystem};

let neuron_id = create_neuron(&nervous_system, &signing_key, "Test Neuron".to_string(), 30)?;
println!("Neuron created with id: {}", neuron_id);
let mut nervous_system = NervousSystem::new();
let neuron_id = create_neuron(&mut nervous_system, &signing_key, "John Doe".to_string(), 365)
.expect("Failed to create neuron");
println!("Created Neuron with ID: {}", neuron_id);
```

### Staking
---

Stake tokens to a neuron:
### Staking

```rust
use crate::core::staking::staking_handler::{stake, unstake};
use crate::core::staking::{stake, StakingModule};

// init consensus_engine beforehand
let mut staking_module = core::staking::staking_module::StakingModule::new(nervous_system.neurons.clone());
stake(&mut staking_module, &mut consensus_engine, &signing_key, neuron_id, 50)?;
println!("Staked 50 tokens to neuron {}", neuron_id);
let mut staking_module = StakingModule::new(nervous_system.neurons.clone());
stake(&mut staking_module, &mut consensus_engine, &signing_key, neuron_id, 500)
.expect("Failed to stake 500 tokens");
println!("Staked 500 tokens to neuron {}", neuron_id);
```

### Governance and Voting
---

Submit a proposal and vote:
### Governance and Voting

```rust
use crate::core::governance::{proposal_handler::propose, voting::{vote, finalize}};

let governance = core::governance::Governance::new(nervous_system.neurons.clone());
let proposal_id = propose(&governance, "Increase block size".to_string(), &signing_key, neuron_id)?;
println!("Proposal created with id: {}", proposal_id);
use crate::core::governance::Governance;

match vote(&governance, &signing_key, neuron_id, proposal_id, true, 10) {
Ok(_) => println!("Voted on proposal {}", proposal_id),
Err(e) => println!("Voting failed: {}", e),
}

let proposal_result = finalize(&governance, proposal_id)?;
println!("Proposal finalized with result: {}", proposal_result);
let mut governance_module = Governance::new(nervous_system.neurons.clone());
```

---

## Dependencies

Add the following to your `Cargo.toml`:

```toml
[dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros", "full"] }
Expand All @@ -269,4 +207,5 @@ hex = "0.4"

## License

Distributed under the [GNU AGPLv3](https://choosealicense.com/licenses/agpl-3.0/) license.
Distributed under the [GNU AGPLv3](https://choosealicense.com/licenses/agpl-3.0/) license.

21 changes: 15 additions & 6 deletions src/core/api/v1/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ pub fn build_transaction(
tx_type: TransactionType,
) -> Transaction {
let fee = amount / 100;
let index = consensus
.chain
.iter()
.map(|chain| chain.transactions.len())
.sum::<usize>() as u32
+ consensus.mempool.len() as u32;

let chain_guard = consensus.chain.lock().unwrap();
let total_chain_txs: usize = chain_guard.iter().map(|block| block.transactions.len()).sum();

let mempool_guard = consensus.mempool.lock().unwrap();
let mempool_len = mempool_guard.len();

let index = total_chain_txs as u32 + mempool_len as u32;

Transaction {
hash: String::new(),
Expand Down Expand Up @@ -54,6 +56,13 @@ pub fn finalize_transaction(tx: &mut Transaction, signing_key: &SigningKey) -> R
Ok(())
}

pub fn cancel_transaction(canister: &mut Canister, consensus_engine: &mut ConsensusEngine, tx_hash: String) -> Result<String, String> {
canister.execute_function(CanisterFunctionPayload::CancelTransfer {
consensus_engine,
tx_hash,
})
}

pub fn submit_transaction(
canister: &mut Canister,
consensus_engine: &mut ConsensusEngine,
Expand Down
Loading

0 comments on commit 2a8bf4c

Please sign in to comment.