mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Started putting in place the adapter between the chain and p2p modules to forward blocks and transactions. Cleaned up chain store references.
This commit is contained in:
parent
2e6d3d9fdb
commit
e688ff99e6
15 changed files with 137 additions and 61 deletions
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
//! Implementation of the chain block acceptance (or refusal) pipeline.
|
//! Implementation of the chain block acceptance (or refusal) pipeline.
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use secp;
|
use secp;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
|
@ -36,9 +38,9 @@ bitflags! {
|
||||||
|
|
||||||
/// Contextual information required to process a new block and either reject or
|
/// Contextual information required to process a new block and either reject or
|
||||||
/// accept it.
|
/// accept it.
|
||||||
pub struct BlockContext<'a> {
|
pub struct BlockContext {
|
||||||
opts: Options,
|
opts: Options,
|
||||||
store: &'a ChainStore,
|
store: Arc<ChainStore>,
|
||||||
head: Tip,
|
head: Tip,
|
||||||
tip: Option<Tip>,
|
tip: Option<Tip>,
|
||||||
}
|
}
|
||||||
|
@ -59,7 +61,7 @@ pub enum Error {
|
||||||
StoreErr(types::Error),
|
StoreErr(types::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_block(b: &Block, store: &ChainStore, opts: Options) -> Result<(), Error> {
|
pub fn process_block(b: &Block, store: Arc<ChainStore>, opts: Options) -> Result<(), Error> {
|
||||||
// TODO should just take a promise for a block with a full header so we don't
|
// TODO should just take a promise for a block with a full header so we don't
|
||||||
// spend resources reading the full block when its header is invalid
|
// spend resources reading the full block when its header is invalid
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ pub struct ChainKVStore {
|
||||||
db: grin_store::Store,
|
db: grin_store::Store,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for ChainKVStore {}
|
||||||
|
unsafe impl Send for ChainKVStore {}
|
||||||
|
|
||||||
impl ChainKVStore {
|
impl ChainKVStore {
|
||||||
pub fn new(root_path: String) -> Result<ChainKVStore, Error> {
|
pub fn new(root_path: String) -> Result<ChainKVStore, Error> {
|
||||||
let db = try!(grin_store::Store::open(format!("{}/{}", root_path, STORE_SUBPATH).as_str())
|
let db = try!(grin_store::Store::open(format!("{}/{}", root_path, STORE_SUBPATH).as_str())
|
||||||
|
|
|
@ -133,7 +133,7 @@ pub enum Error {
|
||||||
|
|
||||||
/// Trait the chain pipeline requires an implementor for in order to process
|
/// Trait the chain pipeline requires an implementor for in order to process
|
||||||
/// blocks.
|
/// blocks.
|
||||||
pub trait ChainStore: Send {
|
pub trait ChainStore: Send + Sync {
|
||||||
/// Get the tip that's also the head of the chain
|
/// Get the tip that's also the head of the chain
|
||||||
fn head(&self) -> Result<Tip, Error>;
|
fn head(&self) -> Result<Tip, Error>;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ extern crate grin_chain;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate secp256k1zkp as secp;
|
extern crate secp256k1zkp as secp;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use rand::os::OsRng;
|
use rand::os::OsRng;
|
||||||
|
|
||||||
use grin_chain::types::*;
|
use grin_chain::types::*;
|
||||||
|
@ -26,7 +27,6 @@ use grin_core::consensus;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn mine_empty_chain() {
|
fn mine_empty_chain() {
|
||||||
let curve = secp::Secp256k1::with_caps(secp::ContextFlag::Commit);
|
|
||||||
let mut rng = OsRng::new().unwrap();
|
let mut rng = OsRng::new().unwrap();
|
||||||
let store = grin_chain::store::ChainKVStore::new(".grin".to_string()).unwrap();
|
let store = grin_chain::store::ChainKVStore::new(".grin".to_string()).unwrap();
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ fn mine_empty_chain() {
|
||||||
let mut prev = gen;
|
let mut prev = gen;
|
||||||
let secp = secp::Secp256k1::with_caps(secp::ContextFlag::Commit);
|
let secp = secp::Secp256k1::with_caps(secp::ContextFlag::Commit);
|
||||||
let reward_key = secp::key::SecretKey::new(&secp, &mut rng);
|
let reward_key = secp::key::SecretKey::new(&secp, &mut rng);
|
||||||
|
let arc_store = Arc::new(store);
|
||||||
|
|
||||||
for n in 1..4 {
|
for n in 1..4 {
|
||||||
let mut b = core::Block::new(&prev.header, vec![], reward_key).unwrap();
|
let mut b = core::Block::new(&prev.header, vec![], reward_key).unwrap();
|
||||||
|
@ -55,10 +56,10 @@ fn mine_empty_chain() {
|
||||||
b.header.pow = proof;
|
b.header.pow = proof;
|
||||||
b.header.nonce = nonce;
|
b.header.nonce = nonce;
|
||||||
b.header.target = diff_target;
|
b.header.target = diff_target;
|
||||||
grin_chain::pipe::process_block(&b, &store, grin_chain::pipe::EASY_POW).unwrap();
|
grin_chain::pipe::process_block(&b, arc_store.clone(), grin_chain::pipe::EASY_POW).unwrap();
|
||||||
|
|
||||||
// checking our new head
|
// checking our new head
|
||||||
let head = store.head().unwrap();
|
let head = arc_store.clone().head().unwrap();
|
||||||
assert_eq!(head.height, n);
|
assert_eq!(head.height, n);
|
||||||
assert_eq!(head.last_block_h, b.hash());
|
assert_eq!(head.last_block_h, b.hash());
|
||||||
|
|
||||||
|
|
42
grin/src/adapters.rs
Normal file
42
grin/src/adapters.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2016 The Grin Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use chain;
|
||||||
|
use core::core;
|
||||||
|
use p2p::NetAdapter;
|
||||||
|
|
||||||
|
pub struct NetToChainAdapter {
|
||||||
|
chain_store: Arc<chain::ChainStore>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetAdapter for NetToChainAdapter {
|
||||||
|
fn transaction_received(&self, tx: core::Transaction) {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
fn block_received(&self, b: core::Block) {
|
||||||
|
// if let Err(e) = chain::process_block(&b, self.chain_store,
|
||||||
|
// chain::pipe::NONE) {
|
||||||
|
// debug!("Block {} refused by chain: {}", b.hash(), e);
|
||||||
|
// }
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetToChainAdapter {
|
||||||
|
pub fn new(chain_store: Arc<chain::ChainStore>) -> NetToChainAdapter {
|
||||||
|
NetToChainAdapter { chain_store: chain_store }
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ extern crate grin_p2p as p2p;
|
||||||
extern crate grin_store as store;
|
extern crate grin_store as store;
|
||||||
extern crate secp256k1zkp as secp;
|
extern crate secp256k1zkp as secp;
|
||||||
|
|
||||||
|
mod adapters;
|
||||||
mod miner;
|
mod miner;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
|
|
|
@ -30,15 +30,13 @@ use secp;
|
||||||
|
|
||||||
pub struct Miner {
|
pub struct Miner {
|
||||||
chain_head: Arc<Mutex<chain::Tip>>,
|
chain_head: Arc<Mutex<chain::Tip>>,
|
||||||
chain_store: Arc<Mutex<chain::ChainStore>>,
|
chain_store: Arc<chain::ChainStore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Miner {
|
impl Miner {
|
||||||
/// Creates a new Miner. Needs references to the chain state and its
|
/// Creates a new Miner. Needs references to the chain state and its
|
||||||
/// storage.
|
/// storage.
|
||||||
pub fn new(chain_head: Arc<Mutex<chain::Tip>>,
|
pub fn new(chain_head: Arc<Mutex<chain::Tip>>, chain_store: Arc<chain::ChainStore>) -> Miner {
|
||||||
chain_store: Arc<Mutex<chain::ChainStore>>)
|
|
||||||
-> Miner {
|
|
||||||
Miner {
|
Miner {
|
||||||
chain_head: chain_head,
|
chain_head: chain_head,
|
||||||
chain_store: chain_store,
|
chain_store: chain_store,
|
||||||
|
@ -54,7 +52,7 @@ impl Miner {
|
||||||
let head: core::BlockHeader;
|
let head: core::BlockHeader;
|
||||||
let mut latest_hash: Hash;
|
let mut latest_hash: Hash;
|
||||||
{
|
{
|
||||||
head = self.chain_store.lock().unwrap().head_header().unwrap();
|
head = self.chain_store.head_header().unwrap();
|
||||||
latest_hash = self.chain_head.lock().unwrap().last_block_h;
|
latest_hash = self.chain_head.lock().unwrap().last_block_h;
|
||||||
}
|
}
|
||||||
let b = self.build_block(&head);
|
let b = self.build_block(&head);
|
||||||
|
@ -86,9 +84,7 @@ impl Miner {
|
||||||
// if we found a solution, push our block out
|
// if we found a solution, push our block out
|
||||||
if let Some(proof) = sol {
|
if let Some(proof) = sol {
|
||||||
info!("Found valid proof of work, adding block {}.", b.hash());
|
info!("Found valid proof of work, adding block {}.", b.hash());
|
||||||
if let Err(e) = chain::process_block(&b,
|
if let Err(e) = chain::process_block(&b, self.chain_store.clone(), chain::NONE) {
|
||||||
self.chain_store.lock().unwrap().deref(),
|
|
||||||
chain::NONE) {
|
|
||||||
error!("Error validating mined block: {:?}", e);
|
error!("Error validating mined block: {:?}", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,6 +23,7 @@ use std::thread;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use tokio_core::reactor;
|
use tokio_core::reactor;
|
||||||
|
|
||||||
|
use adapters::NetToChainAdapter;
|
||||||
use chain;
|
use chain;
|
||||||
use chain::ChainStore;
|
use chain::ChainStore;
|
||||||
use core;
|
use core;
|
||||||
|
@ -72,7 +73,7 @@ pub struct Server {
|
||||||
/// the reference copy of the current chain state
|
/// the reference copy of the current chain state
|
||||||
chain_head: Arc<Mutex<chain::Tip>>,
|
chain_head: Arc<Mutex<chain::Tip>>,
|
||||||
/// data store access
|
/// data store access
|
||||||
chain_store: Arc<Mutex<chain::ChainStore>>,
|
chain_store: Arc<chain::ChainStore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
|
@ -82,7 +83,8 @@ impl Server {
|
||||||
|
|
||||||
let mut evtlp = reactor::Core::new().unwrap();
|
let mut evtlp = reactor::Core::new().unwrap();
|
||||||
let handle = evtlp.handle();
|
let handle = evtlp.handle();
|
||||||
let server = Arc::new(p2p::Server::new(config.p2p_config));
|
let net_adapter = Arc::new(NetToChainAdapter::new(chain_store.clone()));
|
||||||
|
let server = Arc::new(p2p::Server::new(config.p2p_config, net_adapter));
|
||||||
evtlp.run(server.start(handle.clone())).unwrap();
|
evtlp.run(server.start(handle.clone())).unwrap();
|
||||||
|
|
||||||
warn!("Grin server started.");
|
warn!("Grin server started.");
|
||||||
|
@ -91,7 +93,7 @@ impl Server {
|
||||||
evt_handle: handle.clone(),
|
evt_handle: handle.clone(),
|
||||||
p2p: server,
|
p2p: server,
|
||||||
chain_head: Arc::new(Mutex::new(head)),
|
chain_head: Arc::new(Mutex::new(head)),
|
||||||
chain_store: Arc::new(Mutex::new(chain_store)),
|
chain_store: chain_store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +123,7 @@ pub struct ServerFut {
|
||||||
/// the reference copy of the current chain state
|
/// the reference copy of the current chain state
|
||||||
chain_head: Arc<Mutex<chain::Tip>>,
|
chain_head: Arc<Mutex<chain::Tip>>,
|
||||||
/// data store access
|
/// data store access
|
||||||
chain_store: Arc<Mutex<chain::ChainStore>>,
|
chain_store: Arc<chain::ChainStore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerFut {
|
impl ServerFut {
|
||||||
|
@ -129,7 +131,8 @@ impl ServerFut {
|
||||||
pub fn start(config: ServerConfig, evt_handle: &reactor::Handle) -> Result<Server, Error> {
|
pub fn start(config: ServerConfig, evt_handle: &reactor::Handle) -> Result<Server, Error> {
|
||||||
let (chain_store, head) = try!(store_head(&config));
|
let (chain_store, head) = try!(store_head(&config));
|
||||||
|
|
||||||
let server = Arc::new(p2p::Server::new(config.p2p_config));
|
let net_adapter = Arc::new(NetToChainAdapter::new(chain_store.clone()));
|
||||||
|
let server = Arc::new(p2p::Server::new(config.p2p_config, net_adapter));
|
||||||
evt_handle.spawn(server.start(evt_handle.clone()).map_err(|_| ()));
|
evt_handle.spawn(server.start(evt_handle.clone()).map_err(|_| ()));
|
||||||
|
|
||||||
warn!("Grin server started.");
|
warn!("Grin server started.");
|
||||||
|
@ -138,7 +141,7 @@ impl ServerFut {
|
||||||
evt_handle: evt_handle.clone(),
|
evt_handle: evt_handle.clone(),
|
||||||
p2p: server,
|
p2p: server,
|
||||||
chain_head: Arc::new(Mutex::new(head)),
|
chain_head: Arc::new(Mutex::new(head)),
|
||||||
chain_store: Arc::new(Mutex::new(chain_store)),
|
chain_store: chain_store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +163,8 @@ impl ServerFut {
|
||||||
|
|
||||||
// Helper function to create the chain storage and check if it already has a
|
// Helper function to create the chain storage and check if it already has a
|
||||||
// genesis block
|
// genesis block
|
||||||
fn store_head(config: &ServerConfig) -> Result<(chain::store::ChainKVStore, chain::Tip), Error> {
|
fn store_head(config: &ServerConfig)
|
||||||
|
-> Result<(Arc<chain::store::ChainKVStore>, chain::Tip), Error> {
|
||||||
let chain_store = try!(chain::store::ChainKVStore::new(config.db_root.clone())
|
let chain_store = try!(chain::store::ChainKVStore::new(config.db_root.clone())
|
||||||
.map_err(&Error::StoreErr));
|
.map_err(&Error::StoreErr));
|
||||||
|
|
||||||
|
@ -178,5 +182,5 @@ fn store_head(config: &ServerConfig) -> Result<(chain::store::ChainKVStore, chai
|
||||||
}
|
}
|
||||||
Err(e) => return Err(Error::StoreErr(e)),
|
Err(e) => return Err(Error::StoreErr(e)),
|
||||||
};
|
};
|
||||||
Ok((chain_store, head))
|
Ok((Arc::new(chain_store), head))
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,4 +44,4 @@ mod types;
|
||||||
|
|
||||||
pub use server::{Server, DummyAdapter};
|
pub use server::{Server, DummyAdapter};
|
||||||
pub use peer::Peer;
|
pub use peer::Peer;
|
||||||
pub use types::P2PConfig;
|
pub use types::{P2PConfig, NetAdapter};
|
||||||
|
|
|
@ -57,7 +57,10 @@ impl Peer {
|
||||||
Box::new(hs_peer)
|
Box::new(hs_peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self, conn: TcpStream, na: Arc<NetAdapter>) -> Box<Future<Item = (), Error = Error>> {
|
pub fn run(&self,
|
||||||
|
conn: TcpStream,
|
||||||
|
na: Arc<NetAdapter>)
|
||||||
|
-> Box<Future<Item = (), Error = Error>> {
|
||||||
self.proto.handle(conn, na)
|
self.proto.handle(conn, na)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,9 @@ impl ProtocolV1 {
|
||||||
})
|
})
|
||||||
.and_then(move |(reader, header)| {
|
.and_then(move |(reader, header)| {
|
||||||
// now that we have a size, proceed with the body
|
// now that we have a size, proceed with the body
|
||||||
read_exact(reader, vec![0u8; header.msg_len as usize]).map(|(reader, buf)| { (reader, header, buf) }).map_err(|e| ser::Error::IOErr(e))
|
read_exact(reader, vec![0u8; header.msg_len as usize])
|
||||||
|
.map(|(reader, buf)| (reader, header, buf))
|
||||||
|
.map_err(|e| ser::Error::IOErr(e))
|
||||||
})
|
})
|
||||||
.map(move |(reader, header, buf)| {
|
.map(move |(reader, header, buf)| {
|
||||||
// add the count of bytes received
|
// add the count of bytes received
|
||||||
|
@ -192,7 +194,11 @@ impl ProtocolV1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_payload(adapter: Arc<NetAdapter>, header: &MsgHeader, buf: Vec<u8>, sender: &mut UnboundedSender<Vec<u8>>) -> Result<(), ser::Error> {
|
fn handle_payload(adapter: Arc<NetAdapter>,
|
||||||
|
header: &MsgHeader,
|
||||||
|
buf: Vec<u8>,
|
||||||
|
sender: &mut UnboundedSender<Vec<u8>>)
|
||||||
|
-> Result<(), ser::Error> {
|
||||||
match header.msg_type {
|
match header.msg_type {
|
||||||
Type::Ping => {
|
Type::Ping => {
|
||||||
let data = try!(ser::ser_vec(&MsgHeader::new(Type::Pong, 0)));
|
let data = try!(ser::ser_vec(&MsgHeader::new(Type::Pong, 0)));
|
||||||
|
|
|
@ -45,6 +45,7 @@ impl NetAdapter for DummyAdapter {
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
config: P2PConfig,
|
config: P2PConfig,
|
||||||
peers: Arc<RwLock<Vec<Arc<Peer>>>>,
|
peers: Arc<RwLock<Vec<Arc<Peer>>>>,
|
||||||
|
adapter: Arc<NetAdapter>,
|
||||||
stop: RefCell<Option<futures::sync::oneshot::Sender<()>>>,
|
stop: RefCell<Option<futures::sync::oneshot::Sender<()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +55,11 @@ unsafe impl Send for Server {}
|
||||||
// TODO TLS
|
// TODO TLS
|
||||||
impl Server {
|
impl Server {
|
||||||
/// Creates a new idle p2p server with no peers
|
/// Creates a new idle p2p server with no peers
|
||||||
pub fn new(config: P2PConfig) -> Server {
|
pub fn new(config: P2PConfig, adapter: Arc<NetAdapter>) -> Server {
|
||||||
Server {
|
Server {
|
||||||
config: config,
|
config: config,
|
||||||
peers: Arc::new(RwLock::new(Vec::new())),
|
peers: Arc::new(RwLock::new(Vec::new())),
|
||||||
|
adapter: adapter,
|
||||||
stop: RefCell::new(None),
|
stop: RefCell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,10 +73,12 @@ impl Server {
|
||||||
|
|
||||||
let hs = Arc::new(Handshake::new());
|
let hs = Arc::new(Handshake::new());
|
||||||
let peers = self.peers.clone();
|
let peers = self.peers.clone();
|
||||||
|
let adapter = self.adapter.clone();
|
||||||
|
|
||||||
// main peer acceptance future handling handshake
|
// main peer acceptance future handling handshake
|
||||||
let hp = h.clone();
|
let hp = h.clone();
|
||||||
let peers = socket.incoming().map_err(|e| Error::IOErr(e)).map(move |(conn, addr)| {
|
let peers = socket.incoming().map_err(|e| Error::IOErr(e)).map(move |(conn, addr)| {
|
||||||
|
let adapter = adapter.clone();
|
||||||
let peers = peers.clone();
|
let peers = peers.clone();
|
||||||
|
|
||||||
// accept the peer and add it to the server map
|
// accept the peer and add it to the server map
|
||||||
|
@ -84,7 +88,7 @@ impl Server {
|
||||||
let timed_peer = with_timeout(Box::new(peer_accept), &hp);
|
let timed_peer = with_timeout(Box::new(peer_accept), &hp);
|
||||||
|
|
||||||
// run the main peer protocol
|
// run the main peer protocol
|
||||||
timed_peer.and_then(|(conn, peer)| peer.clone().run(conn, Arc::new(DummyAdapter {})))
|
timed_peer.and_then(move |(conn, peer)| peer.clone().run(conn, adapter))
|
||||||
});
|
});
|
||||||
|
|
||||||
// spawn each peer future to its own task
|
// spawn each peer future to its own task
|
||||||
|
@ -120,6 +124,8 @@ impl Server {
|
||||||
h: reactor::Handle)
|
h: reactor::Handle)
|
||||||
-> Box<Future<Item = (), Error = Error>> {
|
-> Box<Future<Item = (), Error = Error>> {
|
||||||
let peers = self.peers.clone();
|
let peers = self.peers.clone();
|
||||||
|
let adapter = self.adapter.clone();
|
||||||
|
|
||||||
let socket = TcpStream::connect(&addr, &h).map_err(|e| Error::IOErr(e));
|
let socket = TcpStream::connect(&addr, &h).map_err(|e| Error::IOErr(e));
|
||||||
let request = socket.and_then(move |socket| {
|
let request = socket.and_then(move |socket| {
|
||||||
let peers = peers.clone();
|
let peers = peers.clone();
|
||||||
|
@ -129,7 +135,7 @@ impl Server {
|
||||||
let peer_connect = add_to_peers(peers, Peer::connect(socket, &Handshake::new()));
|
let peer_connect = add_to_peers(peers, Peer::connect(socket, &Handshake::new()));
|
||||||
with_timeout(Box::new(peer_connect), &h)
|
with_timeout(Box::new(peer_connect), &h)
|
||||||
})
|
})
|
||||||
.and_then(|(socket, peer)| peer.run(socket, Arc::new(DummyAdapter {})));
|
.and_then(move |(socket, peer)| peer.run(socket, adapter));
|
||||||
Box::new(request)
|
Box::new(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,10 @@ pub trait Protocol {
|
||||||
/// be known already, usually passed during construction. Will typically
|
/// be known already, usually passed during construction. Will typically
|
||||||
/// block so needs to be called withing a coroutine. Should also be called
|
/// block so needs to be called withing a coroutine. Should also be called
|
||||||
/// only once.
|
/// only once.
|
||||||
fn handle(&self, conn: TcpStream, na: Arc<NetAdapter>) -> Box<Future<Item = (), Error = Error>>;
|
fn handle(&self,
|
||||||
|
conn: TcpStream,
|
||||||
|
na: Arc<NetAdapter>)
|
||||||
|
-> Box<Future<Item = (), Error = Error>>;
|
||||||
|
|
||||||
/// Sends a ping message to the remote peer.
|
/// Sends a ping message to the remote peer.
|
||||||
fn send_ping(&self) -> Result<(), Error>;
|
fn send_ping(&self) -> Result<(), Error>;
|
||||||
|
|
|
@ -37,7 +37,8 @@ fn peer_handshake() {
|
||||||
let mut evtlp = Core::new().unwrap();
|
let mut evtlp = Core::new().unwrap();
|
||||||
let handle = evtlp.handle();
|
let handle = evtlp.handle();
|
||||||
let p2p_conf = p2p::P2PConfig::default();
|
let p2p_conf = p2p::P2PConfig::default();
|
||||||
let server = p2p::Server::new(p2p_conf);
|
let net_adapter = Arc::new(p2p::DummyAdapter{});
|
||||||
|
let server = p2p::Server::new(p2p_conf, net_adapter.clone());
|
||||||
let run_server = server.start(handle.clone());
|
let run_server = server.start(handle.clone());
|
||||||
|
|
||||||
let phandle = handle.clone();
|
let phandle = handle.clone();
|
||||||
|
@ -51,7 +52,7 @@ fn peer_handshake() {
|
||||||
socket.and_then(move |socket| {
|
socket.and_then(move |socket| {
|
||||||
Peer::connect(socket, &p2p::handshake::Handshake::new())
|
Peer::connect(socket, &p2p::handshake::Handshake::new())
|
||||||
}).and_then(move |(socket, peer)| {
|
}).and_then(move |(socket, peer)| {
|
||||||
rhandle.spawn(peer.run(socket, Arc::new(p2p::DummyAdapter {})).map_err(|e| {
|
rhandle.spawn(peer.run(socket, net_adapter.clone()).map_err(|e| {
|
||||||
panic!("Client run failed: {}", e);
|
panic!("Client run failed: {}", e);
|
||||||
}));
|
}));
|
||||||
peer.send_ping().unwrap();
|
peer.send_ping().unwrap();
|
||||||
|
|
|
@ -50,6 +50,9 @@ pub struct Store {
|
||||||
rdb: RwLock<DB>,
|
rdb: RwLock<DB>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for Store {}
|
||||||
|
unsafe impl Send for Store {}
|
||||||
|
|
||||||
impl Store {
|
impl Store {
|
||||||
/// Opens a new RocksDB at the specified location.
|
/// Opens a new RocksDB at the specified location.
|
||||||
pub fn open(path: &str) -> Result<Store, Error> {
|
pub fn open(path: &str) -> Result<Store, Error> {
|
||||||
|
@ -90,8 +93,13 @@ impl Store {
|
||||||
self.get_ser_limited(key, 0)
|
self.get_ser_limited(key, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a `Readable` value from the db, provided its key, allowing to extract only partial data. The underlying Readable size must align accordingly. Encapsulates serialization.
|
/// Gets a `Readable` value from the db, provided its key, allowing to
|
||||||
pub fn get_ser_limited<T: ser::Readable<T>>(&self, key: &[u8], len: usize) -> Result<Option<T>, Error> {
|
/// extract only partial data. The underlying Readable size must align
|
||||||
|
/// accordingly. Encapsulates serialization.
|
||||||
|
pub fn get_ser_limited<T: ser::Readable<T>>(&self,
|
||||||
|
key: &[u8],
|
||||||
|
len: usize)
|
||||||
|
-> Result<Option<T>, Error> {
|
||||||
let data = try!(self.get(key));
|
let data = try!(self.get(key));
|
||||||
match data {
|
match data {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
|
|
Loading…
Reference in a new issue