Skip to content

Commit

Permalink
derivative chain mining
Browse files Browse the repository at this point in the history
  • Loading branch information
YeahNotSewerSide committed May 4, 2024
1 parent f5dbd5b commit ddd1cf2
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 169 deletions.
74 changes: 74 additions & 0 deletions examples/mine_derivative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use blockchaintree::block::Block as _;
use blockchaintree::tools;
use blockchaintree::{blockchaintree::BlockChainTree, static_values};
use primitive_types::U256;
use std::time::{SystemTime, UNIX_EPOCH};

fn main() {
let rt = tokio::runtime::Runtime::new().unwrap();

let mut tree = BlockChainTree::new().unwrap();

let wallet = [1u8; 33];

let chain = tree.get_derivative_chain(&wallet).unwrap();

loop {
println!("Current height: {}", chain.get_height());
println!(
"Current miner gas amount: {}",
tree.get_gas(&wallet).unwrap()
);
let mut nonce = U256::zero();
let (prev_hash, difficulty, _prev_timestamp, _height) =
if let Some(block) = chain.get_last_block().unwrap() {
(
block.hash().unwrap(),
block.get_info().difficulty,
block.get_info().timestamp,
block.get_info().height,
)
} else {
let block = tree
.get_main_chain()
.find_by_hash(&chain.genesis_hash)
.unwrap()
.unwrap();
(
block.hash().unwrap(),
static_values::BEGINNING_DIFFICULTY,
block.get_info().timestamp,
U256::zero(),
)
};
println!(
"Current difficulty: {}",
tools::count_leading_zeros(&difficulty)
);
while nonce < U256::MAX {
let mut pow = [0u8; 32];
nonce.to_big_endian(&mut pow);
if tools::check_pow(&prev_hash, &difficulty, &pow) {
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();

println!("Found nonce! {}", nonce);

let block = rt
.block_on(tree.emmit_new_derivative_block(&pow, &wallet, timestamp))
.unwrap();

tree.add_gas(&wallet, *static_values::MAIN_CHAIN_PAYMENT)
.unwrap();

println!("Added new block! {:?}\n", block.hash().unwrap());

rt.block_on(chain.flush()).unwrap();
break;
}
nonce += U256::one();
}
}
}
15 changes: 6 additions & 9 deletions src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl TransactionBlock {
#[derive(Debug)]
pub struct DerivativeBlock {
pub default_info: BasicInfo,
pub payment_transaction: Hash,
//pub payment_transaction: Hash,
}

pub trait Block {
Expand All @@ -255,7 +255,7 @@ pub trait Block {

impl Block for DerivativeBlock {
fn get_dump_size(&self) -> usize {
self.default_info.get_dump_size() + 32 + 1
self.default_info.get_dump_size() + 1
}
fn get_info(&self) -> &BasicInfo {
&self.default_info
Expand All @@ -268,7 +268,6 @@ impl Block for DerivativeBlock {
let mut to_return = Vec::<u8>::with_capacity(size);

to_return.push(Headers::DerivativeBlock as u8);
to_return.extend(self.payment_transaction.iter());
self.default_info.dump(&mut to_return)?;

Ok(to_return)
Expand All @@ -277,7 +276,8 @@ impl Block for DerivativeBlock {
Ok(tools::hash(&self.dump()?))
}
fn get_merkle_root(&self) -> Hash {
self.payment_transaction
unimplemented!()
//self.payment_transaction
}
fn verify_block(&self, prev_hash: &Hash) -> bool {
self.default_info.previous_hash.eq(prev_hash)
Expand Down Expand Up @@ -335,13 +335,10 @@ impl DerivativeBlock {
.attach_printable("data.len() < 32"),
);
}
let mut index: usize = 0;
let payment_transaction: Hash = unsafe { data[0..32].try_into().unwrap_unchecked() }; // read payment transaction hash
index += 32;
let default_info: BasicInfo = BasicInfo::parse(&data[index..])?;
let default_info: BasicInfo = BasicInfo::parse(data)?;
Ok(DerivativeBlock {
default_info,
payment_transaction,
//payment_transaction,
})
}
}
Expand Down
87 changes: 70 additions & 17 deletions src/blockchaintree.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::{collections::HashMap, path::Path, sync::Arc};

use crate::{
block::{self, BlockArc, TransactionBlock},
block::{self, Block as _, BlockArc, TransactionBlock},
chain,
errors::{BCTreeErrorKind, BlockChainTreeError},
errors::{BCTreeErrorKind, BlockChainTreeError, ChainErrorKind},
merkletree,
static_values::{
AMMOUNT_SUMMARY, BLOCKS_PER_EPOCH, COINS_PER_CYCLE, GAS_SUMMARY, MAIN_CHAIN_PAYMENT,
self, AMMOUNT_SUMMARY, BLOCKS_PER_EPOCH, COINS_PER_CYCLE, GAS_SUMMARY, MAIN_CHAIN_PAYMENT,
OLD_AMMOUNT_SUMMARY, OLD_GAS_SUMMARY, ROOT_PUBLIC_ADDRESS,
},
tools,
Expand All @@ -21,7 +21,7 @@ use std::fs;

pub struct BlockChainTree {
main_chain: chain::MainChain,
pub derivative_chains: HashMap<[u8; 32], chain::DerivativeChain>,
derivative_chains: HashMap<[u8; 33], chain::DerivativeChain>,
summary_db: Db,
old_summary_db: Db,
gas_db: Db,
Expand Down Expand Up @@ -78,6 +78,21 @@ impl BlockChainTree {
})
}

pub fn get_derivative_chain(
&mut self,
owner: &[u8; 33],
) -> Result<chain::DerivativeChain, Report<BlockChainTreeError>> {
if let Some(chain) = self.derivative_chains.get(owner) {
return Ok(chain.clone());
}
let last_block = self.main_chain.get_last_block()?.unwrap(); // practically cannot fail
let derivative_chain =
chain::DerivativeChain::new(&hex::encode(owner), &last_block.hash().unwrap())?;
self.derivative_chains
.insert(owner.clone(), derivative_chain.clone());
Ok(derivative_chain)
}

pub fn get_main_chain(&self) -> chain::MainChain {
self.main_chain.clone()
}
Expand Down Expand Up @@ -204,11 +219,7 @@ impl BlockChainTree {
Ok(())
}

pub fn add_gas_amount(
&self,
owner: &[u8],
amount: U256,
) -> Result<(), Report<BlockChainTreeError>> {
pub fn add_gas(&self, owner: &[u8], amount: U256) -> Result<(), Report<BlockChainTreeError>> {
self.gas_db
.transaction(
|db| -> Result<(), sled::transaction::ConflictableTransactionError<()>> {
Expand All @@ -227,11 +238,7 @@ impl BlockChainTree {

Ok(())
}
pub fn sub_gas_amount(
&self,
owner: &[u8],
amount: U256,
) -> Result<(), Report<BlockChainTreeError>> {
pub fn sub_gas(&self, owner: &[u8], amount: U256) -> Result<(), Report<BlockChainTreeError>> {
self.gas_db
.transaction(
|db| -> Result<(), sled::transaction::ConflictableTransactionError<()>> {
Expand All @@ -253,7 +260,7 @@ impl BlockChainTree {

Ok(())
}
pub fn get_gas_amount(&self, owner: &[u8; 33]) -> Result<U256, Report<BlockChainTreeError>> {
pub fn get_gas(&self, owner: &[u8; 33]) -> Result<U256, Report<BlockChainTreeError>> {
match self
.gas_db
.get(owner)
Expand Down Expand Up @@ -349,6 +356,52 @@ impl BlockChainTree {
Ok(*merkle_tree.get_root())
}

pub async fn emmit_new_derivative_block(
&mut self,
pow: &[u8; 32],
founder: &[u8; 33],
timestamp: u64,
) -> Result<block::BlockArc, Report<BlockChainTreeError>> {
let derivative_chain = self.get_derivative_chain(founder)?;
let (prev_hash, mut difficulty, prev_timestamp, height) =
if let Some(block) = derivative_chain.get_last_block()? {
(
block.hash().unwrap(),
block.get_info().difficulty,
block.get_info().timestamp,
block.get_info().height,
)
} else {
let block = self
.main_chain
.find_by_hash(&derivative_chain.genesis_hash)?
.ok_or(BlockChainTreeError::Chain(ChainErrorKind::FindByHashE))?;
(
block.hash().unwrap(),
static_values::BEGINNING_DIFFICULTY,
block.get_info().timestamp,
U256::zero(),
)
};

if !tools::check_pow(&prev_hash, &difficulty, pow) {
return Err(BlockChainTreeError::BlockChainTree(BCTreeErrorKind::WrongPow).into());
};
tools::recalculate_difficulty(prev_timestamp, timestamp, &mut difficulty);
let default_info = block::BasicInfo {
timestamp,
pow: *pow,
previous_hash: prev_hash,
height: height + 1,
difficulty,
founder: *founder,
};

let block = block::DerivativeBlock { default_info };
derivative_chain.add_block(&block)?;
Ok(Arc::new(block))
}

pub async fn emmit_new_main_block(
&mut self,
pow: &[u8; 32],
Expand All @@ -362,10 +415,10 @@ impl BlockChainTree {
.change_context(BlockChainTreeError::BlockChainTree(BCTreeErrorKind::DumpDb))
.attach_printable("failed to hash block")?;

if !tools::check_pow(&prev_hash, &last_block.get_info().difficulty, pow) {
let mut difficulty = last_block.get_info().difficulty;
if !tools::check_pow(&prev_hash, &difficulty, pow) {
return Err(BlockChainTreeError::BlockChainTree(BCTreeErrorKind::WrongPow).into());
};
let mut difficulty = last_block.get_info().difficulty;
tools::recalculate_difficulty(last_block.get_info().timestamp, timestamp, &mut difficulty);
let fee = tools::recalculate_fee(&difficulty);
let default_info = block::BasicInfo {
Expand Down
Loading

0 comments on commit ddd1cf2

Please sign in to comment.