Formatting.

This commit is contained in:
Ignotus Peverell 2016-12-13 19:21:49 -08:00
parent 19a700b81e
commit 8a255c0218
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211
8 changed files with 120 additions and 113 deletions

View file

@ -59,7 +59,8 @@ pub fn next_target(ts: i64, prev_ts: i64, prev_target: Target, prev_cuckoo_sz: u
// increase the cuckoo size when the target gets lower than the soft min as
// long as we're not at the max size already; target gets 2x to compensate for
// increased next_target
let soft_min = SOFT_MIN_TARGET >> (((prev_cuckoo_sz - cmp::min(DEFAULT_SIZESHIFT, prev_cuckoo_sz)) * 8) as usize);
let soft_min = SOFT_MIN_TARGET >>
(((prev_cuckoo_sz - cmp::min(DEFAULT_SIZESHIFT, prev_cuckoo_sz)) * 8) as usize);
let (ptarget, clen) = if prev_target < soft_min && prev_cuckoo_sz < MAX_SIZESHIFT {
(prev_target << 1, prev_cuckoo_sz + 1)
} else {
@ -88,16 +89,12 @@ pub fn next_target(ts: i64, prev_ts: i64, prev_target: Target, prev_cuckoo_sz: u
}
/// Max target hash, lowest next_target
pub const MAX_TARGET: Target = Target([0xf, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]);
pub const MAX_TARGET: Target = Target([0xf, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// Target limit under which we start increasing the size shift on Cuckoo cycle.
pub const SOFT_MIN_TARGET: Target = Target([0, 0, 0xf, 0xff, 0xff, 0xff, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]);
pub const SOFT_MIN_TARGET: Target = Target([0, 0, 0xf, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// Default number of blocks in the past when cross-block cut-through will start
/// happening. Needs to be long enough to not overlap with a long reorg.
@ -107,7 +104,8 @@ pub const SOFT_MIN_TARGET: Target = Target([0, 0, 0xf, 0xff, 0xff, 0xff, 0, 0, 0
/// easier to reason about.
pub const CUT_THROUGH_HORIZON: u32 = 48 * 3600 / (BLOCK_TIME_SEC as u32);
/// The maximum size we're willing to accept for any message. Enforced by the peer-to-peer networking layer only for DoS protection.
/// The maximum size we're willing to accept for any message. Enforced by the
/// peer-to-peer networking layer only for DoS protection.
pub const MAX_MSG_LEN: u64 = 20_000_000;
#[cfg(test)]

View file

@ -85,11 +85,11 @@ impl Target {
(exp, res)
}
/// Truncates the target to its maximum precision.
pub fn truncate(&self) -> Target {
let (e, m) = self.split();
Target::join(e, m).unwrap()
}
/// Truncates the target to its maximum precision.
pub fn truncate(&self) -> Target {
let (e, m) = self.split();
Target::join(e, m).unwrap()
}
}
impl Index<usize> for Target {

View file

@ -34,7 +34,7 @@ pub fn genesis() -> core::Block {
height: 0,
previous: core::hash::Hash([0xff; 32]),
timestamp: time::Tm {
tm_year: 1997-1900,
tm_year: 1997 - 1900,
tm_mon: 7,
tm_mday: 4,
..time::empty_tm()

View file

@ -11,7 +11,8 @@ grin_p2p = { path = "../p2p" }
secp256k1zkp = { path = "../secp256k1zkp" }
env_logger="^0.3.5"
futures = "^0.1.6"
log = "^0.3"
mioco = "^0.8"
time = "^0.1"
tokio-core="^0.1.1"
rand = "^0.3"

View file

@ -24,9 +24,10 @@
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate mioco;
extern crate futures;
extern crate rand;
extern crate time;
extern crate tokio_core;
extern crate grin_chain as chain;
extern crate grin_core as core;

View file

@ -48,7 +48,7 @@ impl Miner {
/// Starts the mining loop, building a new block on top of the existing
/// chain anytime required and looking for PoW solution.
pub fn run_loop(&self) {
info!("Starting miner loop.");
info!("Starting miner loop.");
loop {
// get the latest chain state and build a block on top of it
let head: core::BlockHeader;
@ -64,7 +64,8 @@ impl Miner {
// transactions) and as long as the head hasn't changed
let deadline = time::get_time().sec + 2;
let mut sol = None;
debug!("Mining at Cuckoo{} for at most 2 secs.", b.header.cuckoo_len);
debug!("Mining at Cuckoo{} for at most 2 secs.",
b.header.cuckoo_len);
while head.hash() == latest_hash && time::get_time().sec < deadline {
let pow_hash = pow_header.hash();
let mut miner = cuckoo::Miner::new(pow_hash.to_slice(),
@ -84,15 +85,15 @@ impl Miner {
// if we found a solution, push our block out
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,
self.chain_store.lock().unwrap().deref(),
chain::NONE) {
error!("Error validating mined block: {:?}", e);
}
} else {
debug!("No solution found, continuing...")
}
debug!("No solution found, continuing...")
}
}
}

View file

@ -12,109 +12,117 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//! Grin server implementation, glues the different parts of the system (mostly the peer-to-peer server, the blockchain and the transaction pool) and acts as a facade.
//! Grin server implementation, glues the different parts of the system (mostly
//! the peer-to-peer server, the blockchain and the transaction pool) and acts
//! as a facade.
use mioco;
use std::io;
use std::net::ToSocketAddrs;
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
use std::thread;
use tokio_core::reactor;
use chain;
use chain::ChainStore;
use core;
use miner;
use p2p;
/// Errors than can be reported by a server implementation, mostly wraps underlying components errors.
/// Errors than can be reported by a server implementation, mostly wraps
/// underlying components errors.
#[derive(Debug)]
pub enum Error {
/// Error when trying to add a block to the chain
ChainErr(chain::pipe::Error),
/// Peer connection error
PeerErr(core::ser::Error),
/// Data store error
/// Error when trying to add a block to the chain
ChainErr(chain::pipe::Error),
/// Peer connection error
PeerErr(core::ser::Error),
/// Data store error
StoreErr(chain::types::Error),
}
/// Full server configuration, aggregating configurations required for the different components.
/// Full server configuration, aggregating configurations required for the
/// different components.
#[derive(Debug, Clone)]
pub struct ServerConfig {
/// Directory under which the rocksdb stores will be created
pub db_root: String,
/// Allows overriding the default cuckoo cycle size
pub cuckoo_size: u8,
/// Configuration for the peer-to-peer server
pub p2p_config: p2p::P2PConfig,
/// Directory under which the rocksdb stores will be created
pub db_root: String,
/// Allows overriding the default cuckoo cycle size
pub cuckoo_size: u8,
/// Configuration for the peer-to-peer server
pub p2p_config: p2p::P2PConfig,
}
impl Default for ServerConfig {
fn default() -> ServerConfig {
ServerConfig{
db_root: ".grin".to_string(),
cuckoo_size: 0,
p2p_config: p2p::P2PConfig::default(),
}
}
fn default() -> ServerConfig {
ServerConfig {
db_root: ".grin".to_string(),
cuckoo_size: 0,
p2p_config: p2p::P2PConfig::default(),
}
}
}
/// Grin server holding internal structures.
pub struct Server {
config: ServerConfig,
/// handle to our network server
p2p: Arc<p2p::Server>,
/// the reference copy of the current chain state
chain_head: Arc<Mutex<chain::Tip>>,
/// data store access
chain_store: Arc<Mutex<chain::ChainStore>>,
config: ServerConfig,
evt_handle: reactor::Handle,
/// handle to our network server
p2p: Arc<p2p::Server>,
/// the reference copy of the current chain state
chain_head: Arc<Mutex<chain::Tip>>,
/// data store access
chain_store: Arc<Mutex<chain::ChainStore>>,
}
impl Server {
/// Instantiates and starts a new server.
pub fn start(config: ServerConfig) -> Result<Server, Error> {
let chain_store = try!(chain::store::ChainKVStore::new(config.db_root.clone()).map_err(&Error::StoreErr));
/// Instantiates and starts a new server.
pub fn start(config: ServerConfig) -> Result<Server, Error> {
let chain_store = try!(chain::store::ChainKVStore::new(config.db_root.clone())
.map_err(&Error::StoreErr));
// check if we have a head in store, otherwise the genesis block is it
let head = match chain_store.head() {
Ok(tip) => tip,
Err(chain::types::Error::NotFoundErr) => {
let mut gen = core::genesis::genesis();
if config.cuckoo_size > 0 {
gen.header.cuckoo_len = config.cuckoo_size;
}
let tip = chain::types::Tip::new(gen.hash());
try!(chain_store.save_tip(&tip).map_err(&Error::StoreErr));
tip
},
Err(e) => return Err(Error::StoreErr(e)),
};
// check if we have a head in store, otherwise the genesis block is it
let head = match chain_store.head() {
Ok(tip) => tip,
Err(chain::types::Error::NotFoundErr) => {
let mut gen = core::genesis::genesis();
if config.cuckoo_size > 0 {
gen.header.cuckoo_len = config.cuckoo_size;
}
let tip = chain::types::Tip::new(gen.hash());
try!(chain_store.save_tip(&tip).map_err(&Error::StoreErr));
tip
}
Err(e) => return Err(Error::StoreErr(e)),
};
let server = Arc::new(p2p::Server::new(config.p2p_config));
let in_server = server.clone();
mioco::spawn(move || -> io::Result<()> {
try!(in_server.start().map_err(|_| io::Error::last_os_error()));
Ok(())
});
let mut evtlp = reactor::Core::new().unwrap();
let handle = evtlp.handle();
let server = Arc::new(p2p::Server::new(config.p2p_config));
evtlp.run(server.start(handle.clone())).unwrap();
warn!("Grin server started.");
Ok(Server{
config: config,
p2p: server,
chain_head: Arc::new(Mutex::new(head)),
chain_store: Arc::new(Mutex::new(chain_store)),
})
}
Ok(Server {
config: config,
evt_handle: handle.clone(),
p2p: server,
chain_head: Arc::new(Mutex::new(head)),
chain_store: Arc::new(Mutex::new(chain_store)),
})
}
/// Asks the server to connect to a peer at the provided network address.
pub fn connect_peer<A: ToSocketAddrs>(&self, addr: A) -> Result<(), Error> {
self.p2p.connect_peer(addr).map_err(&Error::PeerErr)
}
/// Asks the server to connect to a peer at the provided network address.
pub fn connect_peer(&self, addr: SocketAddr) -> Result<(), Error> {
let handle = self.evt_handle.clone();
handle.spawn(self.p2p.connect_peer(addr, handle.clone()));
Ok(())
}
/// Start mining for blocks on a separate thread. Relies on a toy miner, mostly for testing.
pub fn start_miner(&self) {
let miner = miner::Miner::new(self.chain_head.clone(), self.chain_store.clone());
thread::spawn(move || {
miner.run_loop();
});
}
/// Start mining for blocks on a separate thread. Relies on a toy miner,
/// mostly for testing.
pub fn start_miner(&self) {
let miner = miner::Miner::new(self.chain_head.clone(), self.chain_store.clone());
thread::spawn(move || {
miner.run_loop();
});
}
}

View file

@ -16,20 +16,20 @@ extern crate grin_grin as grin;
extern crate grin_core as core;
extern crate grin_p2p as p2p;
extern crate grin_chain as chain;
extern crate mioco;
extern crate env_logger;
use std::io;
use std::thread;
use std::time;
#[test]
fn simulate_servers() {
env_logger::init().unwrap();
mioco::start(move || -> io::Result<()> {
// instantiates 5 servers on different ports
let mut servers = vec![];
for n in 0..5 {
// instantiates 5 servers on different ports
let mut servers = vec![];
for n in 0..5 {
thread::spawn(move || {
let s = grin::Server::start(
grin::ServerConfig{
db_root: format!("target/grin-{}", n),
@ -37,21 +37,19 @@ fn simulate_servers() {
p2p_config: p2p::P2PConfig{port: 10000+n, ..p2p::P2PConfig::default()}
}).unwrap();
servers.push(s);
}
});
}
mioco::sleep(time::Duration::from_millis(100));
thread::sleep(time::Duration::from_millis(100));
// everyone connects to everyone else
for n in 0..5 {
for m in 0..5 {
if m == n { continue }
let addr = format!("{}:{}", "127.0.0.1", 10000+m);
servers[n].connect_peer(addr.as_str()).unwrap();
mioco::sleep(time::Duration::from_millis(100));
println!("c {}", m);
}
// everyone connects to everyone else
for n in 0..5 {
for m in 0..5 {
if m == n { continue }
let addr = format!("{}:{}", "127.0.0.1", 10000+m);
servers[n].connect_peer(addr.parse().unwrap()).unwrap();
println!("c {}", m);
}
Ok(())
});
}
}