Skip to content

Instantly share code, notes, and snippets.

@rahullenkala
Created July 15, 2019 09:15
Show Gist options
  • Save rahullenkala/9b7a1a6597af556a1eba44526cba7745 to your computer and use it in GitHub Desktop.
Save rahullenkala/9b7a1a6597af556a1eba44526cba7745 to your computer and use it in GitHub Desktop.
mod block;
pub use crate::block::Block;
extern crate bincode;
mod hashable;
use proc_macro2;
pub use crate::hashable::Hashable;
use futures::prelude::*;
use libp2p::{
PeerId,
Swarm,
NetworkBehaviour,
identity,
tokio_codec::{FramedRead,Framed, LinesCodec,BytesCodec}
};
pub struct Blockchain{
pub blocks:Vec<Block>,
}
fn main() {
env_logger::init();
// Create a random PeerId
let local_key = identity::Keypair::generate_ed25519();
let local_peer_id = PeerId::from(local_key.public());
println!("Local peer id: {:?}", local_peer_id);
// Set up a an encrypted DNS-enabled TCP Transport over the Mplex and Yamux protocols
let transport = libp2p::build_development_transport(local_key);
// Create a Floodsub topic
let floodsub_topic = libp2p::floodsub::TopicBuilder::new("chat").build();
// We create a custom network behaviour that combines floodsub and mDNS.
// In the future, we want to improve libp2p to make this easier to do.
#[derive(NetworkBehaviour)]
struct MyBehaviour<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite> {
floodsub: libp2p::floodsub::Floodsub<TSubstream>,
mdns: libp2p::mdns::Mdns<TSubstream>,
}
impl<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite> libp2p::core::swarm::NetworkBehaviourEventProcess<libp2p::mdns::MdnsEvent> for MyBehaviour<TSubstream> {
fn inject_event(&mut self, event: libp2p::mdns::MdnsEvent) {
match event {
libp2p::mdns::MdnsEvent::Discovered(list) => {
for (peer, _) in list {
self.floodsub.add_node_to_partial_view(peer);
}
},
libp2p::mdns::MdnsEvent::Expired(list) => {
for (peer, _) in list {
if !self.mdns.has_node(&peer) {
self.floodsub.remove_node_from_partial_view(&peer);
}
}
}
}
}
}
impl<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite> libp2p::core::swarm::NetworkBehaviourEventProcess<libp2p::floodsub::FloodsubEvent> for MyBehaviour<TSubstream> {
// Called when `floodsub` produces an event.
fn inject_event(&mut self, message: libp2p::floodsub::FloodsubEvent) {
if let libp2p::floodsub::FloodsubEvent::Message(message) = message {
println!("Received: '{:?}' from {:?}", String::from_utf8_lossy(&message.data), message.source);
}
}
}
// Create a Swarm to manage peers and events
let mut swarm = {
let mut behaviour = MyBehaviour {
floodsub: libp2p::floodsub::Floodsub::new(local_peer_id.clone()),
mdns: libp2p::mdns::Mdns::new().expect("Failed to create mDNS service"),
};
behaviour.floodsub.subscribe(floodsub_topic.clone());
libp2p::Swarm::new(transport, behaviour, local_peer_id)
};
// Reach out to another node if specified
if let Some(to_dial) = std::env::args().nth(1) {
let dialing = to_dial.clone();
match to_dial.parse() {
Ok(to_dial) => {
match libp2p::Swarm::dial_addr(&mut swarm, to_dial) {
Ok(_) => println!("Dialed {:?}", dialing),
Err(e) => println!("Dial {:?} failed: {:?}", dialing, e)
}
},
Err(err) => println!("Failed to parse address to dial: {:?}", err),
}
} let stdin = tokio_stdin_stdout::stdin(0);
let mut framed_stdin = FramedRead::new(stdin, LinesCodec::new());
// Listen on all interfaces and whatever port the OS assigns
libp2p::Swarm::listen_on(&mut swarm, "/ip4/0.0.0.0/tcp/0".parse().unwrap()).unwrap();
// Kick it off
let mut listening = false;
tokio::run(futures::future::poll_fn(move || -> Result<_, ()> {
loop {
match framed_stdin.poll().expect("Error while polling stdin") {
Async::Ready(Some(line)) => swarm.floodsub.publish(&floodsub_topic, line.as_bytes()),
Async::Ready(None) => panic!("Stdin closed"),
Async::NotReady => break,
};
}
loop {
match swarm.poll().expect("Error while polling swarm") {
Async::Ready(Some(_)) => {
},
Async::Ready(None) | Async::NotReady => {
if !listening {
if let Some(a) = Swarm::listeners(&swarm).next() {
println!("Listening on {:?}", a);
listening = true;
}
}
break
}
}
}
Ok(Async::NotReady)
}));
let mut block = Block::new(0, vec![0; 32],vec![0;32], "Genesis block!".to_owned(),0, 0x00000fffffffffffffffffffffffffff);
let h=block.hash();
//block.hash_value=h;
// println!("{:?}",&h);
block.mining();
println!("{:?}",&block);
let mut prevhash=block.hash_value.clone();
let mut blckchain=Blockchain {
blocks:vec![block],
};
for i in 1..=10 {
let mut block = Block::new(i, vec![0; 32],prevhash, "new block!".to_owned(),0, 0x0000ffffffffffffffffffffffffffff);
block.mining();
println!("{:?}",&block);
prevhash=block.hash_value.clone();
let payload = serde_json::to_string(&block).unwrap();
let bytes = bincode::serialize(&block).unwrap();
// let stdin = tokio_stdin_stdout::stdin(0);
// let stream: proc_macro2::TokenStream = payload.parse().unwrap();
framed_stdin=FramedRead::new(payload, LinesCodec::new()); //here is the error please look at line 94,95
// framed_stdin = Framed::new(bytes, BytesCodec::new());
//print!("{:?}",payload);
blckchain.blocks.push(block);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment