Skip to content

Commit

Permalink
Devnet network is now starting
Browse files Browse the repository at this point in the history
  • Loading branch information
HariSeldon23 committed Jan 1, 2025
1 parent bf21abb commit 4ad9025
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 63 deletions.
1 change: 1 addition & 0 deletions config/storage.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ blocks_per_section = 10000

# Sections for different types of blockchain data
[journal.partitions]
genesis = "genesis_data"
blocks = "block_data"
transactions = "tx_data"
receipts = "receipt_data"
Expand Down
2 changes: 2 additions & 0 deletions src/config/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub struct JournalConfig {
/// Names for different journal partitions
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct JournalPartitions {
pub genesis: String,
pub blocks: String,
pub transactions: String,
pub receipts: String,
Expand Down Expand Up @@ -172,6 +173,7 @@ impl StorageConfig {
journal: JournalConfig {
blocks_per_section: defaults::BLOCKS_PER_SECTION,
partitions: JournalPartitions {
genesis: "genesis_data".to_string(),
blocks: "block_data".to_string(),
transactions: "tx_data".to_string(),
receipts: "receipt_data".to_string(),
Expand Down
81 changes: 63 additions & 18 deletions src/consensus/automaton.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,99 @@
use commonware_consensus::{Automaton, simplex::Context};
use commonware_runtime::deterministic::Context as RuntimeContext;
use bytes::{Buf, BufMut, Bytes, BytesMut};
use commonware_consensus::{simplex::Context, Automaton};
use commonware_consensus::{Committer, Relay, Supervisor};
use commonware_cryptography::{Ed25519, PublicKey, Scheme};
use commonware_p2p::{Recipients, Sender}; // Removed unused Receiver import
use commonware_consensus::{Relay, Committer, Supervisor};
use commonware_p2p::{Recipients, Sender}; // Removed unused Receiver import
use commonware_runtime::deterministic::Context as RuntimeContext;
use commonware_runtime::Clock;
use bytes::Bytes;
use std::time::SystemTime;
use tracing::{info, warn};
use futures::channel::oneshot;
use std::time::{Duration, SystemTime};
use tracing::{info, warn};

use crate::block::{Block, BlockHeader};
use crate::config::genesis::GenesisConfig;

#[derive(Clone)]
pub struct BlockchainAutomaton {
runtime: RuntimeContext,
p2p_sender: Option<commonware_p2p::authenticated::Sender>,
pub signer: Ed25519,
genesis_config: GenesisConfig,
}

impl BlockchainAutomaton {
pub fn new(runtime: RuntimeContext, signer: Ed25519) -> Self {
pub fn new(runtime: RuntimeContext, signer: Ed25519, genesis_config: GenesisConfig) -> Self {
Self {
runtime,
p2p_sender: None,
signer,
genesis_config,
}
}

pub fn set_sender(&mut self, sender: commonware_p2p::authenticated::Sender) {
self.p2p_sender = Some(sender);
}

async fn create_genesis_block(&self, genesis_time: u64) -> Block {
Block {
header: BlockHeader {
view: 0,
height: 0,
timestamp: SystemTime::UNIX_EPOCH + Duration::from_secs(genesis_time),
previous_hash: [0; 32],
transactions_root: [0; 32],
state_root: [0; 32],
validator_public_key: self.signer.public_key(),
utilization: 0.0,
},
transactions: vec![],
}
}
}

impl Automaton for BlockchainAutomaton {
type Context = Context;

async fn genesis(&mut self) -> Bytes {
let timestamp: u64 = self.runtime.current()
// Create genesis block using the time from our config
let genesis_block = self
.create_genesis_block(self.genesis_config.network.genesis_time)
.await;

let mut buffer = BytesMut::new();

// Serialize the block data
buffer.put_u32(genesis_block.header.view);
buffer.put_u64(genesis_block.header.height);

// Convert SystemTime to u64 timestamp
let timestamp = genesis_block
.header
.timestamp
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();

Bytes::from(format!("Genesis Block: {}", timestamp))
}
buffer.put_u64(timestamp);

buffer.put_slice(&genesis_block.header.previous_hash);
buffer.put_slice(&genesis_block.header.transactions_root);
buffer.put_slice(&genesis_block.header.state_root);
buffer.put_slice(&genesis_block.header.validator_public_key);
buffer.put_f64(genesis_block.header.utilization);

buffer.freeze()
}
// Changed to return the Future directly instead of nesting it
async fn propose(&mut self, context: Self::Context) -> oneshot::Receiver<Bytes> {
let timestamp: u64 = self.runtime.current()
let timestamp: u64 = self
.runtime
.current()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();

let block = Bytes::from(format!("Block at view {}: {}", context.view, timestamp));

if let Some(sender) = &mut self.p2p_sender {
if let Err(e) = sender.send(Recipients::All, block.clone(), true).await {
warn!("Failed to broadcast block: {}", e);
Expand Down Expand Up @@ -78,13 +121,15 @@ impl Automaton for BlockchainAutomaton {
"Block validated for view {}: {}",
context.view, block_content
));
if let Err(e) = sender.send(Recipients::All, validation_message, true).await {
if let Err(e) =
sender.send(Recipients::All, validation_message, true).await
{
warn!("Failed to broadcast validation: {}", e);
}
}
}
is_valid
},
}
Err(_) => {
warn!("Invalid UTF-8 payload at view {}", context.view);
false
Expand Down Expand Up @@ -137,4 +182,4 @@ impl Supervisor for BlockchainAutomaton {
}

async fn report(&self, _activity: u8, _proof: Bytes) {}
}
}
73 changes: 28 additions & 45 deletions src/node/validator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use bytes::{Buf, BufMut, Bytes, BytesMut};
use commonware_consensus::simplex::{Config as ConsensusConfig, Engine};
use commonware_consensus::Automaton;
use commonware_cryptography::Ed25519;
Expand All @@ -20,7 +21,9 @@ use std::sync::Mutex;
use std::time::{Duration, SystemTime};
use tracing::{error, info};

use crate::block::{Block, BlockHeader};
use crate::config::genesis::GenesisConfig;
use crate::config::storage::StorageConfig;
use crate::config::validator::ValidatorConfig;
use crate::consensus::automaton::BlockchainAutomaton;
use crate::regions::region::RegionConfig;
Expand All @@ -32,13 +35,12 @@ pub struct Node {
automaton: BlockchainAutomaton,
genesis_config: GenesisConfig,
validator_config: ValidatorConfig,
storage_config: StorageConfig,
}

impl Node {
/// Creates a new Node instance
pub fn new(runtime: RuntimeContext, signer: Ed25519) -> Self {
let automaton = BlockchainAutomaton::new(runtime.clone(), signer);

// Load network-wide genesis configuration
let genesis_config = match GenesisConfig::load_default() {
Ok(config) => {
Expand All @@ -52,6 +54,22 @@ impl Node {
}
};

// Create automaton with genesis config
let automaton = BlockchainAutomaton::new(runtime.clone(), signer, genesis_config.clone());

// Load Storage configuration
let storage_config = match StorageConfig::load_default() {
Ok(config) => {
info!("Storage configuration loaded successfully");

config
}
Err(e) => {
error!("Failed to load storage configuration: {}", e);
std::process::exit(1);
}
};

let validator_config = match ValidatorConfig::load_validator_config() {
Ok(config) => {
let region_config = RegionConfig::load()
Expand Down Expand Up @@ -89,42 +107,10 @@ impl Node {
automaton,
genesis_config,
validator_config,
storage_config,
}
}

/// Initializes the genesis state for the blockchain
async fn initialize_genesis_state(
&mut self,
journal: &mut Journal<Blob, Storage>,
) -> Result<(), Box<dyn std::error::Error>> {
info!(
"Initializing genesis state for chain {}",
self.genesis_config.network.chain_id
);

// Check if we're past genesis time
let current_time = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs();

if current_time < self.genesis_config.network.genesis_time {
let wait_time = self.genesis_config.network.genesis_time - current_time;
info!("Waiting {} seconds for genesis time...", wait_time);
self.runtime.sleep(Duration::from_secs(wait_time)).await;
}

// Create and store the genesis block
let genesis_block = self.automaton.genesis().await;
info!("Generated genesis block: {:?}", genesis_block);

// Store genesis block in the journal
journal.append(0, genesis_block).await?;
journal.sync(0).await?;

info!("Genesis block created and stored");
Ok(())
}

/// Main entry point for running the node
pub async fn run(
mut self,
Expand All @@ -133,28 +119,25 @@ impl Node {
bootstrap: Option<SocketAddr>,
) {
info!("Starting node at {}", address);
info!("TODO: Validator details added to Metadata");

// Initialize storage with journal configuration
let journal_config = JournalConfig {
registry: Arc::new(Mutex::new(Registry::default())),
partition: format!("blockchain_data_{}", self.genesis_config.network.chain_id),
// Simply use the genesis partition name from storage config
partition: self.storage_config.journal.partitions.genesis.clone(),
};

info!(
"Creating journal with partition: {}",
journal_config.partition
);

let mut journal = Journal::init(self.runtime.clone(), journal_config)
.await
.expect("Failed to create journal");

info!("Commonware Journal Storage initialized...");

// Initialize genesis state if this is a genesis node
if is_genesis {
if let Err(e) = self.initialize_genesis_state(&mut journal).await {
error!("Failed to initialize genesis state: {}", e);
return;
}
}

// Configure P2P network with authentication
let p2p_config = P2PConfig::recommended(
self.automaton.signer.clone(),
Expand Down

0 comments on commit 4ad9025

Please sign in to comment.