Skip to content
Snippets Groups Projects
Commit bcb58586 authored by vinithk2's avatar vinithk2
Browse files

utxo draft

parent 438cd94b
No related branches found
No related tags found
No related merge requests found
......@@ -11,6 +11,7 @@ use tiny_http::Header;
use tiny_http::Response;
use tiny_http::Server as HTTPServer;
use url::Url;
use std::time;
pub struct Server {
handle: HTTPServer,
......@@ -70,7 +71,9 @@ impl Server {
match url.path() {
"/miner/start" => {
let params = url.query_pairs();
println!("{}",params.count());
let params: HashMap<_, _> = params.into_owned().collect();
println!("{}",params.len());
let lambda = match params.get("lambda") {
Some(v) => v,
None => {
......@@ -89,8 +92,29 @@ impl Server {
return;
}
};
miner.start(0);
txgen.start(lambda);
/*let index = match params.get("index") {
Some(v) => v,
None => {
respond_result!(req, false, "missing index");
return;
}
};
let index = match index.parse::<u64>() {
Ok(v) => v,
Err(e) => {
respond_result!(
req,
false,
format!("error parsing index: {}", e)
);
return;
}
};*/
txgen.start(lambda,lambda%3);
let interval = time::Duration::from_micros(10000);
thread::sleep(interval);
miner.start(10000);
respond_result!(req, true, "ok");
}
"/network/ping" => {
......
......@@ -48,7 +48,7 @@ pub fn generate_random_block(parent: &H256) -> Block {
let local: DateTime<Local> = Local::now();
//let mut buffer: [u8; 32] = [0; 32];
let b:H256 = hex!("09911718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920").into();
let b:H256 = hex!("00911718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920").into();
let h:Header = Header{parenthash:*parent,nonce:r1,difficulty:b,timestamp:local.timestamp_millis(),merkle_root:b};
let t = transaction::generate_random_signed_transaction();
//transaction::pr();
......@@ -61,7 +61,7 @@ pub fn generate_random_block(parent: &H256) -> Block {
pub fn generate_genesis_block(parent: &H256) -> Block {
//let b:H256 = hex!("00011718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920").into();
let b:H256 = hex!("09911718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920").into();
let b:H256 = hex!("00911718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920").into();
let r1:u32 = 0;
let r2:i64 = 0;
//let local: DateTime<Local> = Local::now();
......
......@@ -3,6 +3,9 @@ use crate::crypto::hash::{H256,Hashable};
use log::info;
use std::collections::HashMap;
use std::collections::VecDeque;
use crate::mempool::TransactionMempool;
use crate::ledger_state::{BlockState,update_block_state};
use crate::utils::{*};
extern crate chrono;
use chrono::prelude::*;
......@@ -33,7 +36,7 @@ impl Blockchain {
}
/// Insert a block into blockchain
pub fn insert(&mut self, block: &Block) {
pub fn insert(&mut self, block: &Block,mut mempool:&mut TransactionMempool,mut blockstate:&mut BlockState) {
let h:H256 = block.hash();
......@@ -42,19 +45,36 @@ impl Blockchain {
match self.chain.get(&block.header.parenthash){
Some(pblock) => { //insertion into mainchain
let mut validity:bool = false;
if h < pblock.header.difficulty && !self.chain.contains_key(&h) {
let b_delay = Local::now().timestamp_millis() - block.header.timestamp;
self.totaldelay = self.totaldelay + b_delay;
if blockstate.block_state_map.contains_key(&block.header.parenthash){
validity = is_blck_valid(&block,&blockstate.block_state_map.get(&block.header.parenthash).unwrap());
}
else {
info!("State of parent block not found");
return;
}
//checks and updates
if !validity {
info!("Block with hash {} does not satisfy state validity",h);
return;
}
info!("Adding block with hash {} to chain",h);
println!("Block delay is: {:?}",(Local::now().timestamp_millis() - block.header.timestamp));
println!("Average delay is {}",self.totaldelay/(self.chain.len() as i64));
println!("Total number of blocks in blockchain:{}\n",self.chain.len());
self.chain.insert(h,block.clone());
mempool_update(&block,&mut mempool);
update_block_state(&block,&mut blockstate);
let len = self.heights[&block.header.parenthash]+1;
self.heights.insert(h,len);
if len>self.heights[&self.tiphash] {
self.tiphash = h;
println!("Current tipheight is {}",len);
}
//let mut bhash_copy:H256 = hash::generate_random_hash();
......@@ -69,9 +89,29 @@ impl Blockchain {
//flag = true;
let bhash_copy:H256 = *bhash;
bhash_vec.push(bhash_copy);
//checks and updates
let mut validity:bool = false;
if blockstate.block_state_map.contains_key(&h){
validity = is_blck_valid(&block,&blockstate.block_state_map.get(&h).unwrap());
}
else {
info!("State of parent block not found");
continue;
}
//let validity:bool = is_blck_valid(&block,&blockstate.block_state_map.get(&block.header.parenthash).unwrap());
if !validity {
info!("Block with hash {} does not satisfy state validity",h);
return;
}
self.chain.insert(bhash_copy,blck.clone());
let b_delay = Local::now().timestamp_millis() - block.header.timestamp;
mempool_update(&blck,&mut mempool);
update_block_state(&blck,&mut blockstate);
let b_delay = Local::now().timestamp_millis() - blck.header.timestamp;
self.totaldelay = self.totaldelay + b_delay;
info!("Adding block with hash {} to chain",blck.hash());
println!("Block delay is: {:?}",(Local::now().timestamp_millis() - blck.header.timestamp));
println!("Average delay is {}",self.totaldelay/(self.chain.len() as i64));
......
......@@ -67,6 +67,13 @@ pub fn address_from_public_key(public_key: <Ed25519KeyPair as KeyPair>::PublicKe
H160(raw_address)
}
pub fn address_from_public_key_vec_ref(public_key: &Vec<u8>) -> H160 {
let public_key_hash = digest::digest(&digest::SHA256, public_key);
let mut raw_address: [u8; 20] = [0; 20];
raw_address.copy_from_slice(&(public_key_hash.as_ref()[12..32]));
H160(raw_address)
}
pub fn generate_random_address() -> H160 {
let mut rng = rand::thread_rng();
......
use crate::transaction::{UtxoInput, UtxoOutput};
use crate::crypto::hash::H256;
use crate::block::Block;
use crate::crypto::hash::Hashable;
use crate::crypto::address::{self, H160};
use ring::signature::{self,Ed25519KeyPair, Signature, KeyPair};
use std::collections::HashMap;
use log::debug;
#[derive(Debug, Default, Clone)]
pub struct State{
pub state_map: HashMap<UtxoInput, UtxoOutput>,
}
pub struct BlockState{
pub block_state_map: HashMap<H256, State>,
}
impl BlockState {
pub fn new(genhash:&H256)-> Self{
let gen_state = ico();
let mut hmap:HashMap<H256, State>= HashMap::new();
hmap.insert(*genhash,gen_state.clone());
let bs_map:BlockState = BlockState{block_state_map:hmap};
bs_map
}
}
//TODO: Can change the signature of the function if passing some mutex version
//of block_state
pub fn update_block_state(block: &Block, block_state: &mut BlockState) {
let parent_state = &block_state.block_state_map[&block.header.parenthash];
let mut cur_block_state = parent_state.clone();
//debug!{"parent_state {:?}", parent_state}
for signed_tx in &block.content.data {
for tx_input in &signed_tx.tx.tx_input {
cur_block_state.state_map.remove(tx_input);
}
for (i, tx_output) in (&signed_tx.tx.tx_output).iter().enumerate() {
let tx_input = UtxoInput{tx_hash: signed_tx.tx.hash(), idx: i as u8};
cur_block_state.state_map.insert(tx_input, tx_output.clone());
}
}
//debug!{"cur_block_state {:?}", cur_block_state}
block_state.block_state_map.insert(block.hash(), cur_block_state);
}
pub fn ico() -> State {
/*let public_key1: Vec<u8> = b"AAAAC3NzaC1lZDI1NTE5AAAAICYqyx/qrxvVPB2lPvV3ZmTH+uYwB6wL1hkBlGaYPmGu".to_vec();
let public_key2: Vec<u8> = b"AAAAC3NzaC1lZDI1NTE5AAAAIDfqgH+ezyswXrz2YNDkkYXCTCTMi+Ms6GWW5NQXNUc4".to_vec();
let public_key3: Vec<u8> = b"AAAAC3NzaC1lZDI1NTE5AAAAIMborH2X51+g+ziV0LmZY8p90+eEP/9jPAOUauBPorL/".to_vec();
let mut address_vec: Vec<H160> = vec![];
let address1 = address::address_from_public_key_vec_ref(&public_key1);
let address2 = address::address_from_public_key_vec_ref(&public_key2);
let address3 = address::address_from_public_key_vec_ref(&public_key3);
address_vec.push(address1);
address_vec.push(address2);
address_vec.push(address3);*/
let key_pair1 = signature::Ed25519KeyPair::from_pkcs8([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 187, 131, 74, 161, 134, 11, 240, 6, 188, 109, 18, 108, 124, 219, 167, 164, 215, 125, 168, 79, 204, 194, 232, 91, 58, 186, 181, 230, 212, 78, 163, 28, 161, 35, 3, 33, 0, 233, 72, 146, 218, 220, 235, 17, 123, 202, 112, 119, 63, 134, 105, 134, 71, 34, 185, 71, 193, 59, 66, 43, 137, 50, 194, 120, 234, 97, 132, 235, 159].as_ref().into()).unwrap();
let key_pair2 = signature::Ed25519KeyPair::from_pkcs8([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 154, 186, 73, 239, 105, 129, 142, 211, 156, 79, 213, 209, 229, 87, 22, 92, 113, 203, 244, 222, 244, 33, 199, 254, 130, 102, 178, 65, 198, 67, 20, 132, 161, 35, 3, 33, 0, 161, 153, 171, 27, 96, 146, 25, 237, 5, 189, 186, 116, 0, 24, 2, 8, 28, 143, 5, 119, 20, 47, 142, 186, 55, 234, 189, 167, 154, 15, 210, 97].as_ref().into()).unwrap();
let key_pair3 = signature::Ed25519KeyPair::from_pkcs8([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 147, 195, 231, 118, 135, 29, 32, 40, 23, 117, 107, 218, 6, 220, 198, 50, 81, 113, 167, 122, 175, 161, 118, 93, 191, 137, 50, 125, 203, 69, 70, 42, 161, 35, 3, 33, 0, 125, 80, 160, 138, 247, 46, 227, 162, 118, 51, 64, 42, 174, 60, 87, 134, 77, 60, 225, 11, 189, 222, 22, 185, 65, 10, 67, 78, 250, 41, 188, 60].as_ref().into()).unwrap();
let mut address_vec: Vec<H160> = vec![];
let address1 = address::address_from_public_key_vec_ref(&key_pair1.public_key().as_ref().to_vec());
let address2 = address::address_from_public_key_vec_ref(&key_pair2.public_key().as_ref().to_vec());
let address3 = address::address_from_public_key_vec_ref(&key_pair3.public_key().as_ref().to_vec());
address_vec.push(address1);
address_vec.push(address2);
address_vec.push(address3);
let mut sam = hex!("6b787718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920");
//let mut initial_tx_hash: H256 = sam.into() ;
let val: u32 = 100;
let mut initial_state: State = State{state_map: HashMap::new()};
for j in 1..20 {
sam[j/10]=(j%10) as u8;
let mut initial_tx_hash: H256 = sam.into() ;
for (i,address) in address_vec.iter().enumerate() {
let input = UtxoInput{tx_hash: initial_tx_hash, idx: i as u8};
let output = UtxoOutput{receipient_addr: *address, value: val};
initial_state.state_map.insert(input, output);
}
}
initial_state
}
......@@ -10,8 +10,9 @@ pub mod miner;
pub mod network;
pub mod transaction;
pub mod mempool;
pub mod transaction_checks;
pub mod utils;
pub mod tx_generator;
pub mod ledger_state;
use clap::clap_app;
use crossbeam::channel;
......@@ -23,6 +24,9 @@ use std::process;
use std::thread;
use std::time;
use std::sync::{Arc, Mutex};
use crate::crypto::hash::{self, H256, Hashable};
use crate::block::{*};
fn main() {
// parse command line arguments
......@@ -70,20 +74,38 @@ fn main() {
let (server_ctx, server) = server::new(p2p_addr, msg_tx).unwrap();
server_ctx.start().unwrap();
// start the transaction generator
// generating genblock and genhash
let buffer: [u8; 32] = [0; 32];
let b:H256 = buffer.into();
let genesis:Block = block::generate_genesis_block(&b);
let genhash:H256 = genesis.hash();
// create state_chain
let ledger_state = Arc::new(Mutex::new(ledger_state::BlockState::new(&genhash)));
// create mempool
let mempool = Arc::new(Mutex::new(mempool::TransactionMempool::new()));
// create blockchain
let blockchain = Arc::new(Mutex::new(blockchain::Blockchain::new()));
// start the transaction generator
let (txgen_ctx,txgen) = tx_generator::new(
&server,
&mempool,
&ledger_state,
&blockchain,
);
txgen_ctx.start();
// start the miner
let blockchain = Arc::new(Mutex::new(blockchain::Blockchain::new()));
// start the miner
let (miner_ctx, miner) = miner::new(
&server,
&blockchain,
&mempool,
&ledger_state,
);
miner_ctx.start();
......@@ -102,6 +124,7 @@ fn main() {
&server,
&blockchain,
&mempool,
&ledger_state,
);
worker_ctx.start();
......
use crate::network::server::Handle as ServerHandle;
use crate::blockchain::Blockchain;
use crate::mempool::TransactionMempool;
use crate::ledger_state::BlockState;
use crate::block::*;
use crate::transaction::{self, SignedTransaction};
use crate::crypto::hash::{H256, Hashable};
use crate::crypto::hash::{H256, Hashable,generate_random_hash};
use crate::crypto::merkle::{*};
use crate::network::message::Message;
use log::{debug,info};
......@@ -36,6 +37,7 @@ pub struct Context {
blockchain: Arc<Mutex<Blockchain>>,
mempool:Arc<Mutex<TransactionMempool>>,
num_mined:u8,
ledger_state: Arc<Mutex<BlockState>>,
}
#[derive(Clone)]
......@@ -50,7 +52,8 @@ pub struct Handle {
pub fn new(
server: &ServerHandle,
blockchain: &Arc<Mutex<Blockchain>>,
mempool: &Arc<Mutex<TransactionMempool>>
mempool: &Arc<Mutex<TransactionMempool>>,
ledger_state: &Arc<Mutex<BlockState>>
) -> (Context, Handle) {
let (signal_chan_sender, signal_chan_receiver) = unbounded();
......@@ -61,6 +64,7 @@ pub fn new(
blockchain: Arc::clone(blockchain),
mempool: Arc::clone(mempool),
num_mined:0,
ledger_state: Arc::clone(ledger_state),
};
let handle = Handle {
......@@ -93,29 +97,43 @@ impl Context {
info!("Miner initialized into paused mode");
}
pub fn tx_pool_gen(&self) -> (Content,H256) {
pub fn tx_pool_gen(&self,mempool:&mut TransactionMempool) -> (Content,H256) {
let mut vect: Vec<SignedTransaction> = vec![];
let mut merkle_init_vect: Vec<H256> = vec![];
info!("Inside tx_pool_gen");
loop {
let mut locked_mempool = self.mempool.lock().unwrap();
if locked_mempool.tx_hash_queue.len()<15 {
std::mem::drop(locked_mempool);
info!("Inside tx_pool_gen loop");
//let mut locked_mempool = self.mempool.lock().unwrap();
/*
if mempool.tx_hash_queue.len()<15 {
continue;
} else {
while vect.len()<10 && locked_mempool.tx_hash_queue.len()>0 {
let h = locked_mempool.tx_hash_queue.pop_front().unwrap();
if locked_mempool.tx_to_process.contains_key(&h) && locked_mempool.tx_to_process.get(&h).unwrap() == &true {
vect.push(locked_mempool.tx_map.get(&h).unwrap().clone());
while vect.len()<10 && mempool.tx_hash_queue.len()>0 {
let h = mempool.tx_hash_queue.pop_front().unwrap();
if mempool.tx_to_process.contains_key(&h) && mempool.tx_to_process.get(&h).unwrap() == &true {
vect.push(mempool.tx_map.get(&h).unwrap().clone());
merkle_init_vect.push(h);
}
}
std::mem::drop(locked_mempool);
if vect.len()==10 {
break;
}
}*/
while vect.len()<3 && mempool.tx_hash_queue.len()>0 {
let h = mempool.tx_hash_queue.pop_front().unwrap();
match mempool.tx_to_process.get(&h) {
Some(boolean) => if *boolean && mempool.tx_map.contains_key(&h){
vect.push(mempool.tx_map.get(&h).unwrap().clone());
merkle_init_vect.push(h);
},
None => continue
}
}
if vect.len()==3 {
break;
}
}
let mut content: Content = Content{data:vect};
let mut merkle_tree_tx = MerkleTree::new(&merkle_init_vect);
......@@ -139,8 +157,12 @@ impl Context {
}
fn miner_loop(&mut self) {
let (mut content,mut merkle_root) = self.tx_pool_gen();
let mut flag:bool = true;
// main mining loop
let mut content:Content;
let mut vect: Vec<SignedTransaction> = vec![];
content = Content{data:vect};
let mut merkle_root:H256=generate_random_hash();
loop {
// check and react to control signals
match self.operating_state {
......@@ -194,26 +216,34 @@ impl Context {
let mut merkle_tree_tx = MerkleTree::new(&merkle_init_vect);
let mut merkle_root = merkle_tree_tx.root();
*/
let mut locked_blockchain = self.blockchain.lock().unwrap();
let mut locked_mempool = self.mempool.lock().unwrap();
let mut locked_state = self.ledger_state.lock().unwrap();
if flag {
let (content,merkle_root) = self.tx_pool_gen(&mut locked_mempool);
}
flag = false;
// actual mining
// create Block
//TODO: Put this in a function
//Creating Header fields
let mut locked_blockchain = self.blockchain.lock().unwrap();
let phash = locked_blockchain.tiphash;
let mut rng = rand::thread_rng();
let nonce = rng.gen();
let timestamp = Local::now().timestamp_millis();
let difficulty = locked_blockchain.chain.get(&locked_blockchain.tiphash)
let mut difficulty:H256 = hex!("09911718210e0b3b608814e04e61fde06d0df794319a12162f287412df3ec920").into();
if locked_blockchain.chain.contains_key(&locked_blockchain.tiphash){
difficulty = locked_blockchain.chain.get(&locked_blockchain.tiphash)
.unwrap()
.header
.difficulty ;
}
//Creating Content
//It will also be used for Merkel Root for the Header
......@@ -239,7 +269,7 @@ impl Context {
if new_block.hash() <= difficulty {
info!("block with hash:{} generated\n",new_block.hash());
println!("Number of blocks mined until now:{}\n",self.num_mined+1);
locked_blockchain.insert(&new_block);
locked_blockchain.insert(&new_block,&mut locked_mempool,&mut locked_state);
let encodedhead: Vec<u8> = bincode::serialize(&new_block).unwrap();
debug!("Size of block generated is {} bytes\n",encodedhead.len());
//print!("Total number of blocks in blockchain:{}\n",locked_blockchain.chain.len());
......@@ -247,8 +277,12 @@ impl Context {
let mut new_block_hash : Vec<H256> = vec![];
new_block_hash.push(new_block.hash());
self.server.broadcast(Message::NewBlockHashes(new_block_hash));
let (content,merkle_root) = self.tx_pool_gen();
let (content,merkle_root) = self.tx_pool_gen(&mut locked_mempool);
}
std::mem::drop(locked_state);
std::mem::drop(locked_mempool);
std::mem::drop(locked_blockchain);
if let OperatingState::Run(i) = self.operating_state {
if i != 0 {
......@@ -257,7 +291,7 @@ impl Context {
}
}
std::mem::drop(locked_blockchain);
}
}
}
......@@ -4,9 +4,10 @@ use crate::network::server::Handle as ServerHandle;
use crate::blockchain::Blockchain;
use crate::block::*;
use crate::transaction::SignedTransaction;
use crate::transaction_checks;
use crate::utils;
use crate::mempool::TransactionMempool;
use crate::crypto::hash::{H256, Hashable};
use crate::ledger_state::BlockState;
use crossbeam::channel;
use log::{debug,info, warn};
......@@ -21,6 +22,7 @@ pub struct Context {
server: ServerHandle,
blockchain: Arc<Mutex<Blockchain>>,
tx_mempool: Arc<Mutex<TransactionMempool>>,
ledger_state: Arc<Mutex<BlockState>>,
}
pub fn new(
......@@ -28,14 +30,16 @@ pub fn new(
msg_src: channel::Receiver<(Vec<u8>, peer::Handle)>,
server: &ServerHandle,
blockchain: &Arc<Mutex<Blockchain>>,
tx_mempool: &Arc<Mutex<TransactionMempool>>
tx_mempool: &Arc<Mutex<TransactionMempool>>,
ledger_state: &Arc<Mutex<BlockState>>
) -> Context {
Context {
msg_chan: msg_src,
num_worker,
server: server.clone(),
blockchain: Arc::clone(blockchain),
tx_mempool: Arc::clone(tx_mempool)
tx_mempool: Arc::clone(tx_mempool),
ledger_state: Arc::clone(ledger_state),
}
}
......@@ -58,6 +62,7 @@ impl Context {
let msg: Message = bincode::deserialize(&msg).unwrap();
let mut locked_blockchain = self.blockchain.lock().unwrap();
let mut locked_mempool = self.tx_mempool.lock().unwrap();
let mut locked_state = self.ledger_state.lock().unwrap();
match msg {
Message::Ping(nonce) => {
debug!("Ping: {}", nonce);
......@@ -125,7 +130,7 @@ impl Context {
for blck in vec_blocks {
let mut blck_is_valid: bool = true;
for tx in &blck.content.data{
if !transaction_checks::is_tx_valid(tx){
if !utils::is_tx_valid(tx){
blck_is_valid = false;
debug!("Invalid tx in received block. Ignoring that block");
break;
......@@ -133,20 +138,23 @@ impl Context {
}
if blck_is_valid {
// added difficulty check in insert method
locked_blockchain.insert(&blck);
locked_blockchain.insert(&blck,&mut locked_mempool,&mut locked_state);
//locked_blockchain.insert(&blck,&locked_mempool);
//Sending getblocks message if block is orphan
get_block_hash.push(blck.header.parenthash);
if !locked_blockchain.chain.contains_key(&blck.header.parenthash){
get_block_hash.push(blck.header.parenthash);
self.server.broadcast(Message::GetBlocks(get_block_hash.clone()));
}
//broadcasting new block hashes
new_block_hash.push(blck.hash());
self.server.broadcast(Message::NewBlockHashes(new_block_hash.clone()));
//Updating mempool
/*//Updating mempool
for signed_tx in &blck.content.data {
let signed_tx_hash = signed_tx.hash();
match locked_mempool.tx_to_process.get(&signed_tx_hash){
......@@ -158,7 +166,7 @@ impl Context {
locked_mempool.tx_map.insert(signed_tx_hash, signed_tx.clone());
}
}
}
}*/
//Updating State
......@@ -202,26 +210,32 @@ impl Context {
}
Message::Transactions(vec_signed_txs) => {
debug!("Received Transactions");
let mut new_tx_hashes: Vec<H256> = vec![];
let mut tx_hashes_to_broadcast: Vec<H256> = vec![];
for signed_tx in vec_signed_txs {
if transaction_checks::is_tx_valid(&signed_tx){
if utils::is_tx_valid(&signed_tx){
let signed_tx_hash = signed_tx.hash();
match locked_mempool.tx_to_process.get(&signed_tx_hash){
Some(_tx_present) => debug!("tx_hash {} already present. Not adding to mempool",
signed_tx_hash),
None => {
info!("tx_hash {} is being added to mempool", signed_tx_hash);
new_tx_hashes.push(signed_tx_hash);
locked_mempool.tx_to_process.insert(signed_tx_hash, true);
locked_mempool.tx_map.insert(signed_tx_hash, signed_tx);
locked_mempool.tx_hash_queue.push_back(signed_tx_hash);
tx_hashes_to_broadcast.push(signed_tx_hash);
}
}
}
}
self.server.broadcast(Message::NewTransactionHashes(new_tx_hashes.clone()));
if tx_hashes_to_broadcast.len() != 0{
self.server.broadcast(Message::NewTransactionHashes(tx_hashes_to_broadcast.clone()));
}
}
}
std::mem::drop(locked_state);
std::mem::drop(locked_mempool);
std::mem::drop(locked_blockchain);
}
}
}
......@@ -9,7 +9,7 @@ use crate::crypto::hash::{self, H256, Hashable};
use crate::crypto::address::{self, H160};
#[derive(Serialize, Deserialize, Debug, Default,Clone)]
#[derive(Serialize, Deserialize, Debug, Default,Clone, Eq, PartialEq, Hash)]
pub struct UtxoInput{
pub tx_hash: H256,
pub idx: u8,
......
use crate::transaction::{self, SignedTransaction};
pub fn is_tx_valid(signed_tx: &SignedTransaction) -> bool {
//verify whether the tx is signed properly
return transaction::verify(&signed_tx.tx, &signed_tx.signature, &signed_tx.public_key);
}
use crate::network::server::Handle as ServerHandle;
use crate::blockchain::Blockchain;
use crate::ledger_state::{BlockState,State};
use crate::block::*;
use crate::transaction::{self,*};
use crate::crypto::hash::{H256, Hashable};
use crate::crypto::address::{*};
use crate::network::message::Message;
use log::{debug,info};
use rand::Rng;
......@@ -10,6 +12,10 @@ use crossbeam::channel::{unbounded, Receiver, Sender, TryRecvError};
use ring::signature::{self,Ed25519KeyPair, Signature, KeyPair};
use crate::mempool::TransactionMempool;
use crate::crypto::key_pair;
use crate::crypto::address::{self,*};
use std::borrow::Borrow;
use std::collections::HashMap;
extern crate chrono;
use chrono::prelude::*;
......@@ -19,13 +25,13 @@ use std::thread;
use std::sync::{Arc, Mutex};
enum ControlSignal {
Start(u64), // the number controls the lambda of interval between block generation
Start(u64,u64), // the number controls the lambda of interval between block generation
Exit,
}
enum OperatingState {
Paused,
Run(u64),
Run(u64,u64),
ShutDown,
}
......@@ -35,6 +41,8 @@ pub struct Context {
operating_state: OperatingState,
server: ServerHandle,
mempool: Arc<Mutex<TransactionMempool>>,
ledger_state: Arc<Mutex<BlockState>>,
blockchain: Arc<Mutex<Blockchain>>,
}
#[derive(Clone)]
......@@ -46,7 +54,9 @@ pub struct Handle {
pub fn new(
server: &ServerHandle,
mempool: &Arc<Mutex<TransactionMempool>>
mempool: &Arc<Mutex<TransactionMempool>>,
ledger_state: &Arc<Mutex<BlockState>>,
blockchain: &Arc<Mutex<Blockchain>>
) -> (Context, Handle) {
let (signal_chan_sender, signal_chan_receiver) = unbounded();
......@@ -55,6 +65,8 @@ pub fn new(
operating_state: OperatingState::Paused,
server: server.clone(),
mempool: Arc::clone(mempool),
ledger_state: Arc::clone(ledger_state),
blockchain: Arc::clone(blockchain),
};
let handle = Handle {
......@@ -69,9 +81,9 @@ impl Handle {
self.control_chan.send(ControlSignal::Exit).unwrap();
}
pub fn start(&self, lambda: u64) {
pub fn start(&self, lambda: u64,index: u64) {
self.control_chan
.send(ControlSignal::Start(lambda))
.send(ControlSignal::Start(lambda,index))
.unwrap();
}
}
......@@ -93,15 +105,43 @@ impl Context {
info!("Generator shutting down");
self.operating_state = OperatingState::ShutDown;
}
ControlSignal::Start(i) => {
info!("Generator starting in continuous mode with lambda {}", i);
self.operating_state = OperatingState::Run(i);
ControlSignal::Start(i,j) => {
info!("Generator starting in continuous mode with lambda {} and index {}", i,j);
self.operating_state = OperatingState::Run(i,j);
}
}
}
fn gen_loop(&mut self) {
// main mining loop
// public_key:key.public_key().as_ref().to_vec()
/*let public_key1: Vec<u8> = b"AAAAC3NzaC1lZDI1NTE5AAAAICYqyx/qrxvVPB2lPvV3ZmTH+uYwB6wL1hkBlGaYPmGu".to_vec();
let public_key2: Vec<u8> = b"AAAAC3NzaC1lZDI1NTE5AAAAIDfqgH+ezyswXrz2YNDkkYXCTCTMi+Ms6GWW5NQXNUc4".to_vec();
let public_key3: Vec<u8> = b"AAAAC3NzaC1lZDI1NTE5AAAAIMborH2X51+g+ziV0LmZY8p90+eEP/9jPAOUauBPorL/".to_vec();
let address1 = address::address_from_public_key_vec_ref(&public_key1);
let address2 = address::address_from_public_key_vec_ref(&public_key2);
let address3 = address::address_from_public_key_vec_ref(&public_key3);*/
let key_pair1 = signature::Ed25519KeyPair::from_pkcs8([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 187, 131, 74, 161, 134, 11, 240, 6, 188, 109, 18, 108, 124, 219, 167, 164, 215, 125, 168, 79, 204, 194, 232, 91, 58, 186, 181, 230, 212, 78, 163, 28, 161, 35, 3, 33, 0, 233, 72, 146, 218, 220, 235, 17, 123, 202, 112, 119, 63, 134, 105, 134, 71, 34, 185, 71, 193, 59, 66, 43, 137, 50, 194, 120, 234, 97, 132, 235, 159].as_ref().into()).unwrap();
let key_pair2 = signature::Ed25519KeyPair::from_pkcs8([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 154, 186, 73, 239, 105, 129, 142, 211, 156, 79, 213, 209, 229, 87, 22, 92, 113, 203, 244, 222, 244, 33, 199, 254, 130, 102, 178, 65, 198, 67, 20, 132, 161, 35, 3, 33, 0, 161, 153, 171, 27, 96, 146, 25, 237, 5, 189, 186, 116, 0, 24, 2, 8, 28, 143, 5, 119, 20, 47, 142, 186, 55, 234, 189, 167, 154, 15, 210, 97].as_ref().into()).unwrap();
let key_pair3 = signature::Ed25519KeyPair::from_pkcs8([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 147, 195, 231, 118, 135, 29, 32, 40, 23, 117, 107, 218, 6, 220, 198, 50, 81, 113, 167, 122, 175, 161, 118, 93, 191, 137, 50, 125, 203, 69, 70, 42, 161, 35, 3, 33, 0, 125, 80, 160, 138, 247, 46, 227, 162, 118, 51, 64, 42, 174, 60, 87, 134, 77, 60, 225, 11, 189, 222, 22, 185, 65, 10, 67, 78, 250, 41, 188, 60].as_ref().into()).unwrap();
let vector1 = [48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 187, 131, 74, 161, 134, 11, 240, 6, 188, 109, 18, 108, 124, 219, 167, 164, 215, 125, 168, 79, 204, 194, 232, 91, 58, 186, 181, 230, 212, 78, 163, 28, 161, 35, 3, 33, 0, 233, 72, 146, 218, 220, 235, 17, 123, 202, 112, 119, 63, 134, 105, 134, 71, 34, 185, 71, 193, 59, 66, 43, 137, 50, 194, 120, 234, 97, 132, 235, 159];
let vector2 = [48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 154, 186, 73, 239, 105, 129, 142, 211, 156, 79, 213, 209, 229, 87, 22, 92, 113, 203, 244, 222, 244, 33, 199, 254, 130, 102, 178, 65, 198, 67, 20, 132, 161, 35, 3, 33, 0, 161, 153, 171, 27, 96, 146, 25, 237, 5, 189, 186, 116, 0, 24, 2, 8, 28, 143, 5, 119, 20, 47, 142, 186, 55, 234, 189, 167, 154, 15, 210, 97];
let vector3 = [48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 147, 195, 231, 118, 135, 29, 32, 40, 23, 117, 107, 218, 6, 220, 198, 50, 81, 113, 167, 122, 175, 161, 118, 93, 191, 137, 50, 125, 203, 69, 70, 42, 161, 35, 3, 33, 0, 125, 80, 160, 138, 247, 46, 227, 162, 118, 51, 64, 42, 174, 60, 87, 134, 77, 60, 225, 11, 189, 222, 22, 185, 65, 10, 67, 78, 250, 41, 188, 60];
let address1 = address::address_from_public_key_vec_ref(&key_pair1.public_key().as_ref().to_vec());
let address2 = address::address_from_public_key_vec_ref(&key_pair2.public_key().as_ref().to_vec());
let address3 = address::address_from_public_key_vec_ref(&key_pair3.public_key().as_ref().to_vec());
let mut index:u64 = 0;
let mut time_i:u64 = 0;
loop {
// check and react to control signals
match self.operating_state {
......@@ -124,10 +164,69 @@ impl Context {
if let OperatingState::ShutDown = self.operating_state {
return;
}
if let OperatingState::Run(i,j) = self.operating_state {
index = j;
time_i =i;
}
// actual transaction generation
//getting tip state
let locked_state = self.ledger_state.lock().unwrap();
let locked_blockchain = self.blockchain.lock().unwrap();
let mut locked_mempool = self.mempool.lock().unwrap();
let tiphash = locked_blockchain.tiphash;
let mut map_state:HashMap<UtxoInput, UtxoOutput> = HashMap::new();
let mut tip_state:State = State{state_map:map_state};
if locked_state.block_state_map.contains_key(&tiphash){
tip_state = locked_state.block_state_map.get(&tiphash).unwrap().clone();
}
else{
info!("Tiphash not present in state_map");
}
let mut ref_addr:H160=generate_random_address() ;
let mut send_addr:H160=generate_random_address() ;
let mut key:signature::Ed25519KeyPair=key_pair::random();
match index {
0 => {ref_addr = address1;send_addr=address3;key = signature::Ed25519KeyPair::from_pkcs8(vector1.as_ref().into()).unwrap(); },
1 => {ref_addr = address2;send_addr=address3;key = signature::Ed25519KeyPair::from_pkcs8(vector2.as_ref().into()).unwrap(); },
2 => {ref_addr = address3;send_addr=address3;key = signature::Ed25519KeyPair::from_pkcs8(vector3.as_ref().into()).unwrap(); },
_ => println!("Invalid index"),
}
let mut tx_buffer : Vec<H256> = vec![];
for x in 0..10 {
info!("About to generate tx");
let mut balance:u32 = 0;
for (input,output) in tip_state.state_map.iter() {
if output.receipient_addr == ref_addr {
let mut vec_input:Vec<UtxoInput> = vec![];
let mut vec_output:Vec<UtxoOutput> = vec![];
vec_input.push(input.clone());
let mut new_output = output.clone();
new_output.receipient_addr = send_addr;
balance += new_output.value;
vec_output.push(new_output);
let t = Transaction{tx_input:vec_input,tx_output:vec_output};
let sig = sign(&t, &key);
let signed_tx = SignedTransaction{tx:t,signature:sig.as_ref().to_vec(),public_key:key.public_key().as_ref().to_vec()};
// if locked_mempool.tx_to_process.contains_key(&signed_tx.hash()){
// continue;
// } else {
tx_buffer.push(signed_tx.hash());
println!("Adding transaction with hash {} to mempool in tx_generator",signed_tx.hash());
locked_mempool.tx_to_process.insert(signed_tx.hash(),true);
locked_mempool.tx_map.insert(signed_tx.hash(),signed_tx.clone());
locked_mempool.tx_hash_queue.push_back(signed_tx.hash());
// }
}
}
info!("Balance of this node is: {}",balance);
/*for x in 0..10 {
let t = transaction::generate_random_transaction();
let key = key_pair::random();
let sig = sign(&t, &key);
......@@ -144,20 +243,29 @@ impl Context {
locked_mempool.tx_hash_queue.push_back(signed_tx.hash());
}
}
}*/
if tx_buffer.len()>0 {
self.server.broadcast(Message::NewTransactionHashes(tx_buffer));
}
std::mem::drop(locked_mempool);
std::mem::drop(locked_blockchain);
std::mem::drop(locked_state);
if let OperatingState::Run(i) = self.operating_state {
/*if let OperatingState::Run(i,j) = self.operating_state {
if i != 0 {
let interval = time::Duration::from_micros(i as u64);
thread::sleep(interval);
}
}*/
if time_i != 0 {
let interval = time::Duration::from_micros(time_i);
thread::sleep(interval);
}
......
use crate::transaction::{self, SignedTransaction};
use crate::block::Block;
use crate::ledger_state::State;
use crate::crypto::address;
use crate::mempool::TransactionMempool;
use crate::crypto::hash::{H256,Hashable};
use log::debug;
pub fn is_tx_valid(signed_tx: &SignedTransaction) -> bool {
//verify whether the tx is signed properly
return transaction::verify(&signed_tx.tx, &signed_tx.signature, &signed_tx.public_key);
}
pub fn is_blck_valid(block: &Block, parent_state: &State) -> bool {
for signed_tx in &block.content.data {
debug!("current signed_tx {:?}", signed_tx);
if !is_tx_valid(signed_tx){
debug!("tx didn't pass signature check!");
return false;
}
//Couple of checks
//1. Owner match
//2. Input/Output total match
//3. Double Spend
let owner_address = address::address_from_public_key_vec_ref(&signed_tx.public_key);
let mut total_input_value = 0;
for input in &signed_tx.tx.tx_input {
debug!("current tx_input {:?}", input);
if !parent_state.state_map.contains_key(&input){
debug!("tx is double spend as input is not there in State!");
return false;
}
let output = &parent_state.state_map[&input];
if output.receipient_addr != owner_address {
debug!("owner of tx input doesn't match to previous tx output");
debug!("input addreess {:?}", owner_address);
debug!("output address {:?}", output.receipient_addr);
return false;
}
total_input_value = output.value;
}
let mut total_output_value = 0;
for output in &signed_tx.tx.tx_output {
total_output_value += output.value;
}
if total_input_value != total_output_value {
debug!("Input sum didn't match to output sum for tx");
return false;
}
}
true
}
pub fn mempool_update(block: &Block, mempool: &mut TransactionMempool){
//Updating mempool
for signed_tx in &block.content.data {
let signed_tx_hash = signed_tx.hash();
match mempool.tx_to_process.get(&signed_tx_hash){
Some(_tx_present) => {
mempool.tx_to_process.insert(signed_tx_hash, false);
},
None => {
mempool.tx_to_process.insert(signed_tx_hash, false);
mempool.tx_map.insert(signed_tx_hash, signed_tx.clone());
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment