Apply new difficulty algo, remove configurable cuckoo size

Integrate the new difficulty calculation into the block chain
validation, the miner and tests. As the difficulty calculation
doesn't use varying Cuckoo sizes anymore and we narrowed down
reasonable final Cuckoo Cycle parameters, removed all Cuckoo
Cycle sizes from block headers.

Formalized easier Cuckoo Cycle sizes for testing (and possibly
testnet) by introducing a test mode in configuration. Updated
all tests.
This commit is contained in:
Ignotus Peverell 2017-06-19 08:59:56 -07:00
parent 163b1133a7
commit e8a6b61100
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211
14 changed files with 166 additions and 138 deletions

View file

@ -41,4 +41,4 @@ pub mod types;
// Re-export the base interface
pub use types::{ChainStore, Tip, ChainAdapter};
pub use pipe::{SYNC, NONE, process_block, process_block_header, Error};
pub use pipe::{SYNC, NONE, EASY_POW, process_block, process_block_header, Options, Error};

View file

@ -37,8 +37,10 @@ bitflags! {
const NONE = 0b00000001,
/// Runs without checking the Proof of Work, mostly to make testing easier.
const SKIP_POW = 0b00000010,
/// Runs PoW verification with a lower cycle size.
const EASY_POW = 0b00000100,
/// Adds block while in syncing mode.
const SYNC = 0b00000100,
const SYNC = 0b00001000,
}
}
@ -72,6 +74,7 @@ pub enum Error {
/// Internal issue when trying to save or load data from store
StoreErr(grin_store::Error),
SerErr(ser::Error),
Other(String),
}
impl From<grin_store::Error> for Error {
@ -201,17 +204,20 @@ fn validate_header(header: &BlockHeader, ctx: &mut BlockContext) -> Result<(), E
return Err(Error::WrongTotalDifficulty);
}
let (difficulty, cuckoo_sz) = consensus::next_target(header.timestamp.to_timespec().sec,
prev.timestamp.to_timespec().sec,
prev.difficulty,
prev.cuckoo_len);
let diff_iter = store::DifficultyIter::from(header.previous, ctx.store.clone());
let difficulty =
consensus::next_difficulty(diff_iter).map_err(|e| Error::Other(e.to_string()))?;
if header.difficulty < difficulty {
return Err(Error::DifficultyTooLow);
}
if header.cuckoo_len != cuckoo_sz {
return Err(Error::WrongCuckooSize);
}
if !pow::verify(header) {
let cycle_size = if ctx.opts.intersects(EASY_POW) {
consensus::TEST_SIZESHIFT
} else {
consensus::DEFAULT_SIZESHIFT
};
debug!("Validating block with cuckoo size {}", cycle_size);
if !pow::verify_size(header, cycle_size as u32) {
return Err(Error::InvalidPow);
}
}

View file

@ -14,11 +14,15 @@
//! Implements storage primitives required by the chain
use std::sync::Arc;
use secp::pedersen::Commitment;
use types::*;
use core::core::hash::{Hash, Hashed};
use core::core::{Block, BlockHeader, Output};
use core::consensus::TargetError;
use core::core::target::Difficulty;
use grin_store::{self, Error, to_key, u64_to_key, option_to_not_found};
const STORE_SUBPATH: &'static str = "chain";
@ -141,3 +145,41 @@ impl ChainStore for ChainKVStore {
Ok(())
}
}
/// An iterator on blocks, from latest to earliest, specialized to return
/// information pertaining to block difficulty calculation (timestamp and
/// previous difficulties). Mostly used by the consensus next difficulty
/// calculation.
pub struct DifficultyIter {
next: Hash,
store: Arc<ChainStore>,
}
impl DifficultyIter {
/// Build a new iterator using the provided chain store and starting from
/// the provided block hash.
pub fn from(start: Hash, store: Arc<ChainStore>) -> DifficultyIter {
DifficultyIter {
next: start,
store: store,
}
}
}
impl Iterator for DifficultyIter {
type Item = Result<(i64, Difficulty), TargetError>;
fn next(&mut self) -> Option<Self::Item> {
let bhe = self.store.get_block_header(&self.next);
match bhe {
Err(e) => Some(Err(TargetError(e.to_string()))),
Ok(bh) => {
if bh.height == 0 {
return None;
}
self.next = bh.previous;
Some(Ok((bh.timestamp.to_timespec().sec, bh.difficulty)))
}
}
}
}

View file

@ -24,6 +24,7 @@ use std::thread;
use rand::os::OsRng;
use grin_chain::types::*;
use grin_chain::store;
use grin_core::core::hash::Hashed;
use grin_core::core::target::Difficulty;
use grin_core::pow;
@ -38,9 +39,8 @@ fn mine_empty_chain() {
// save a genesis block
let mut gen = grin_core::genesis::genesis();
gen.header.cuckoo_len = 12;
let diff = gen.header.difficulty.clone();
pow::pow(&mut gen.header, diff).unwrap();
pow::pow_size(&mut gen.header, diff, consensus::TEST_SIZESHIFT as u32).unwrap();
store.save_block(&gen).unwrap();
// setup a new head tip
@ -58,17 +58,15 @@ fn mine_empty_chain() {
let mut b = core::Block::new(&prev.header, vec![], reward_key).unwrap();
b.header.timestamp = prev.header.timestamp + time::Duration::seconds(60);
let (difficulty, _) = consensus::next_target(b.header.timestamp.to_timespec().sec,
prev.header.timestamp.to_timespec().sec,
prev.header.difficulty.clone(),
prev.header.cuckoo_len);
let diff_iter = store::DifficultyIter::from(b.header.previous, arc_store.clone());
let difficulty = consensus::next_difficulty(diff_iter).unwrap();
b.header.difficulty = difficulty.clone();
pow::pow(&mut b.header, difficulty).unwrap();
pow::pow_size(&mut b.header, difficulty, consensus::TEST_SIZESHIFT as u32).unwrap();
grin_chain::pipe::process_block(&b,
arc_store.clone(),
adapter.clone(),
grin_chain::pipe::NONE)
grin_chain::pipe::EASY_POW)
.unwrap();
// checking our new head
@ -88,9 +86,8 @@ fn mine_forks() {
// save a genesis block
let mut gen = grin_core::genesis::genesis();
gen.header.cuckoo_len = 12;
let diff = gen.header.difficulty.clone();
pow::pow(&mut gen.header, diff).unwrap();
pow::pow_size(&mut gen.header, diff, consensus::TEST_SIZESHIFT as u32).unwrap();
store.save_block(&gen).unwrap();
// setup a new head tip

View file

@ -20,6 +20,7 @@
//! here.
use std::cmp;
use std::fmt;
use bigint::{BigInt, Sign};
@ -37,17 +38,11 @@ pub const BLOCK_TIME_SEC: i64 = 60;
/// Cuckoo-cycle proof size (cycle length)
pub const PROOFSIZE: usize = 42;
/// Origin Cuckoo Cycle size shift used by the genesis block.
pub const DEFAULT_SIZESHIFT: u8 = 25;
/// Default Cuckoo Cycle size shift used for mining and validating.
pub const DEFAULT_SIZESHIFT: u8 = 30;
/// Maximum Cuckoo Cycle size shift we'll ever use. We adopt a schedule that
/// progressively increases the size as the target becomes lower.
/// Start => 25
/// MAX_TARGET >> 12 => 26
/// MAX_TARGET >> 20 => 27
/// MAX_TARGET >> 28 => 28
/// MAX_TARGET >> 36 => 29
pub const MAX_SIZESHIFT: u8 = 29;
/// Lower Cuckoo size shift for tests and testnet
pub const TEST_SIZESHIFT: u8 = 12;
/// Default Cuckoo Cycle easiness, high enough to have good likeliness to find
/// a solution.
@ -75,11 +70,28 @@ pub const UPPER_TIME_BOUND: i64 = BLOCK_TIME_WINDOW * 4 / 3;
pub const LOWER_TIME_BOUND: i64 = BLOCK_TIME_WINDOW * 5 / 6;
/// Error when computing the next difficulty adjustment.
#[derive(Debug, Clone)]
pub struct TargetError {
err: String,
pub struct TargetError(pub String);
impl fmt::Display for TargetError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Error computing new difficulty: {}", self.0)
}
}
pub fn next_target2<T>(cursor: T) -> Result<Difficulty, TargetError>
/// Computes the proof-of-work difficulty that the next block should comply
/// with. Takes an iterator over past blocks, from latest (highest height) to
/// oldest (lowest height). The iterator produces pairs of timestamp and
/// difficulty for each block.
///
/// The difficulty calculation is based on both Digishield and GravityWave
/// family of difficulty computation, coming to something very close to Zcash.
/// The refence difficulty is an average of the difficulty over a window of
/// 23 blocks. The corresponding timespan is calculated by using the
/// difference between the median timestamps at the beginning and the end
/// of the window.
pub fn next_difficulty<T>(cursor: T) -> Result<Difficulty, TargetError>
where T: IntoIterator<Item = Result<(i64, Difficulty), TargetError>>
{
@ -141,46 +153,6 @@ pub fn next_target2<T>(cursor: T) -> Result<Difficulty, TargetError>
Difficulty::from_num(adj_ts as u32))
}
/// Difficulty adjustment somewhat inspired by Ethereum's. Tuned to add or
/// remove 1/1024th of the target for each 10 seconds of deviation from the 30
/// seconds block time. Increases Cuckoo size shift by one when next_target
/// reaches soft max.
pub fn next_target(ts: i64,
prev_ts: i64,
prev_diff: Difficulty,
prev_cuckoo_sz: u8)
-> (Difficulty, u8) {
let one = BigInt::new(Sign::Plus, vec![1]);
let two = BigInt::new(Sign::Plus, vec![2]);
let ten = BigInt::new(Sign::Plus, vec![10]);
// 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 = one.clone() <<
(((prev_cuckoo_sz - cmp::min(DEFAULT_SIZESHIFT, prev_cuckoo_sz)) *
8 + 16) as usize);
let prev_diff = BigInt::from_biguint(Sign::Plus, prev_diff.into_biguint());
let (pdiff, clen) = if prev_diff > soft_min && prev_cuckoo_sz < MAX_SIZESHIFT {
(prev_diff / two, prev_cuckoo_sz + 1)
} else {
(prev_diff, prev_cuckoo_sz)
};
// signed deviation from desired value divided by ten and bounded in [-6, 6]
let delta = cmp::max(cmp::min((ts - prev_ts - (BLOCK_TIME_SEC as i64)), 60), -60);
let delta_bigi = BigInt::new(if delta >= 0 { Sign::Plus } else { Sign::Minus },
vec![delta.abs() as u32]);
let new_diff = pdiff.clone() - ((pdiff >> 10) + one.clone()) * delta_bigi / ten;
// cannot be lower than one
if new_diff < one {
(Difficulty::one(), clen)
} else {
(Difficulty::from_biguint(new_diff.to_biguint().unwrap()), clen)
}
}
#[cfg(test)]
mod test {
use core::target::Difficulty;

View file

@ -43,8 +43,6 @@ pub struct BlockHeader {
pub previous: Hash,
/// Timestamp at which the block was built.
pub timestamp: time::Tm,
/// Length of the cuckoo cycle used to mine this block.
pub cuckoo_len: u8,
/// Merkle root of the UTXO set
pub utxo_merkle: Hash,
/// Merkle tree of hashes for all inputs, outputs and kernels in the block
@ -67,7 +65,6 @@ impl Default for BlockHeader {
height: 0,
previous: ZERO_HASH,
timestamp: time::at_utc(time::Timespec { sec: 0, nsec: 0 }),
cuckoo_len: 20, // only for tests
difficulty: Difficulty::one(),
total_difficulty: Difficulty::one(),
utxo_merkle: ZERO_HASH,
@ -86,7 +83,6 @@ impl Writeable for BlockHeader {
[write_u64, self.height],
[write_fixed_bytes, &self.previous],
[write_i64, self.timestamp.to_timespec().sec],
[write_u8, self.cuckoo_len],
[write_fixed_bytes, &self.utxo_merkle],
[write_fixed_bytes, &self.tx_merkle],
[write_u8, self.features.bits()]);
@ -107,7 +103,7 @@ impl Readable for BlockHeader {
fn read(reader: &mut Reader) -> Result<BlockHeader, ser::Error> {
let height = try!(reader.read_u64());
let previous = try!(Hash::read(reader));
let (timestamp, cuckoo_len) = ser_multiread!(reader, read_i64, read_u8);
let timestamp = reader.read_i64()?;
let utxo_merkle = try!(Hash::read(reader));
let tx_merkle = try!(Hash::read(reader));
let (features, nonce) = ser_multiread!(reader, read_u8, read_u64);
@ -122,7 +118,6 @@ impl Readable for BlockHeader {
sec: timestamp,
nsec: 0,
}),
cuckoo_len: cuckoo_len,
utxo_merkle: utxo_merkle,
tx_merkle: tx_merkle,
features: BlockFeatures::from_bits(features).ok_or(ser::Error::CorruptedData)?,
@ -284,7 +279,6 @@ impl Block {
timestamp: time::now(),
previous: prev.hash(),
total_difficulty: prev.pow.to_difficulty() + prev.total_difficulty.clone(),
cuckoo_len: prev.cuckoo_len,
..Default::default()
},
inputs: inputs,

View file

@ -34,7 +34,6 @@ pub fn genesis() -> core::Block {
tm_mday: 4,
..time::empty_tm()
},
cuckoo_len: DEFAULT_SIZESHIFT,
difficulty: Difficulty::one(),
total_difficulty: Difficulty::one(),
utxo_merkle: [].hash(),

View file

@ -33,11 +33,6 @@ use core::hash::Hashed;
use core::target::Difficulty;
use pow::cuckoo::{Cuckoo, Miner, Error};
/// Validates the proof of work of a given header.
pub fn verify(bh: &BlockHeader) -> bool {
verify_size(bh, bh.cuckoo_len as u32)
}
/// Validates the proof of work of a given header, and that the proof of work
/// satisfies the requirements of the header.
pub fn verify_size(bh: &BlockHeader, cuckoo_sz: u32) -> bool {
@ -49,21 +44,15 @@ pub fn verify_size(bh: &BlockHeader, cuckoo_sz: u32) -> bool {
Cuckoo::new(&bh.hash()[..], cuckoo_sz).verify(bh.pow, EASINESS as u64)
}
/// Runs a naive single-threaded proof of work computation over the provided
/// block, until the required difficulty target is reached. May take a
/// while for a low target...
pub fn pow(bh: &mut BlockHeader, diff: Difficulty) -> Result<(), Error> {
let cuckoo_len = bh.cuckoo_len as u32;
pow_size(bh, diff, cuckoo_len)
}
/// Same as default pow function but uses the much easier Cuckoo20 (mostly for
/// Uses the much easier Cuckoo20 (mostly for
/// tests).
pub fn pow20(bh: &mut BlockHeader, diff: Difficulty) -> Result<(), Error> {
pow_size(bh, diff, 20)
}
/// Actual pow function, takes an arbitrary pow size as input
/// Runs a naive single-threaded proof of work computation over the provided
/// block, until the required difficulty target is reached. May take a
/// while for a low target...
pub fn pow_size(bh: &mut BlockHeader, diff: Difficulty, sizeshift: u32) -> Result<(), Error> {
let start_nonce = bh.nonce;

View file

@ -32,6 +32,7 @@ use sync;
/// blocks and transactions are received and forwards to the chain and pool
/// implementations.
pub struct NetToChainAdapter {
test_mode: bool,
/// the reference copy of the current chain state
chain_head: Arc<Mutex<chain::Tip>>,
chain_store: Arc<chain::ChainStore>,
@ -64,12 +65,7 @@ impl NetAdapter for NetToChainAdapter {
// pushing the new block through the chain pipeline
let store = self.chain_store.clone();
let chain_adapter = self.chain_adapter.clone();
let opts = if self.syncer.borrow().syncing() {
chain::SYNC
} else {
chain::NONE
};
let res = chain::process_block(&b, store, chain_adapter, opts);
let res = chain::process_block(&b, store, chain_adapter, self.chain_opts());
// log errors and update the shared head reference on success
if let Err(e) = res {
@ -86,19 +82,13 @@ impl NetAdapter for NetToChainAdapter {
}
fn headers_received(&self, bhs: Vec<core::BlockHeader>) {
let opts = if self.syncer.borrow().syncing() {
chain::SYNC
} else {
chain::NONE
};
// try to add each header to our header chain
let mut added_hs = vec![];
for bh in bhs {
let store = self.chain_store.clone();
let chain_adapter = self.chain_adapter.clone();
let res = chain::process_block_header(&bh, store, chain_adapter, opts);
let res = chain::process_block_header(&bh, store, chain_adapter, self.chain_opts());
match res {
Ok(_) => {
added_hs.push(bh.hash());
@ -216,13 +206,15 @@ impl NetAdapter for NetToChainAdapter {
}
impl NetToChainAdapter {
pub fn new(chain_head: Arc<Mutex<chain::Tip>>,
pub fn new(test_mode: bool,
chain_head: Arc<Mutex<chain::Tip>>,
chain_store: Arc<chain::ChainStore>,
chain_adapter: Arc<ChainToPoolAndNetAdapter>,
tx_pool: Arc<RwLock<pool::TransactionPool<PoolToChainAdapter>>>,
peer_store: Arc<PeerStore>)
-> NetToChainAdapter {
NetToChainAdapter {
test_mode: test_mode,
chain_head: chain_head,
chain_store: chain_store,
chain_adapter: chain_adapter,
@ -232,6 +224,8 @@ impl NetToChainAdapter {
}
}
/// Start syncing the chain by instantiating and running the Syncer in the
/// background (a new thread is created).
pub fn start_sync(&self, sync: sync::Syncer) {
let arc_sync = Arc::new(sync);
self.syncer.init(arc_sync.clone());
@ -239,6 +233,19 @@ impl NetToChainAdapter {
arc_sync.run();
});
}
/// Prepare options for the chain pipeline
fn chain_opts(&self) -> chain::Options {
let mut opts = if self.syncer.borrow().syncing() {
chain::SYNC
} else {
chain::NONE
};
if self.test_mode {
opts = opts | chain::EASY_POW;
}
opts
}
}
/// Implementation of the ChainAdapter for the network. Gets notified when the

View file

@ -82,15 +82,14 @@ impl Miner {
let deadline = time::get_time().sec + 2;
let mut sol = None;
debug!("Mining at Cuckoo{} for at most 2 secs on block {} at difficulty {}.",
b.header.cuckoo_len,
self.config.cuckoo_size,
latest_hash,
b.header.difficulty);
let mut iter_count = 0;
while head.hash() == latest_hash && time::get_time().sec < deadline {
let pow_hash = b.hash();
let mut miner = cuckoo::Miner::new(&pow_hash[..],
consensus::EASINESS,
b.header.cuckoo_len as u32);
let mut miner =
cuckoo::Miner::new(&pow_hash[..], consensus::EASINESS, self.config.cuckoo_size);
if let Ok(proof) = miner.mine() {
if proof.to_difficulty() >= b.header.difficulty {
sol = Some(proof);
@ -108,10 +107,15 @@ impl Miner {
if let Some(proof) = sol {
info!("Found valid proof of work, adding block {}.", b.hash());
b.header.pow = proof;
let opts = if self.config.cuckoo_size < consensus::DEFAULT_SIZESHIFT as u32 {
chain::EASY_POW
} else {
chain::NONE
};
let res = chain::process_block(&b,
self.chain_store.clone(),
self.chain_adapter.clone(),
chain::NONE);
opts);
if let Err(e) = res {
error!("Error validating mined block: {:?}", e);
} else if let Ok(Some(tip)) = res {
@ -138,8 +142,9 @@ impl Miner {
if now_sec == head_sec {
now_sec += 1;
}
let (difficulty, cuckoo_len) =
consensus::next_target(now_sec, head_sec, head.difficulty.clone(), head.cuckoo_len);
let diff_iter = chain::store::DifficultyIter::from(head.hash(), self.chain_store.clone());
let difficulty = consensus::next_difficulty(diff_iter).unwrap();
let txs_box = self.tx_pool.read().unwrap().prepare_mineable_transactions(MAX_TX);
let txs = txs_box.iter().map(|tx| tx.as_ref()).collect();
@ -155,7 +160,6 @@ impl Miner {
let mut rng = rand::OsRng::new().unwrap();
b.header.nonce = rng.gen();
b.header.cuckoo_len = cuckoo_len;
b.header.difficulty = difficulty;
b.header.timestamp = time::at(time::Timespec::new(now_sec, 0));
b

View file

@ -29,7 +29,7 @@ use adapters::*;
use api;
use chain;
use chain::ChainStore;
use core;
use core::{self, consensus};
use core::core::hash::Hashed;
use miner;
use p2p;
@ -58,8 +58,10 @@ pub struct Server {
impl Server {
/// Instantiates and starts a new server.
pub fn start(config: ServerConfig) -> Result<Server, Error> {
pub fn start(mut config: ServerConfig) -> Result<Server, Error> {
check_config(&mut config);
let mut evtlp = reactor::Core::new().unwrap();
let mining_config = config.mining_config.clone();
let serv = Server::future(config, &evtlp.handle())?;
if mining_config.enable_mining {
@ -79,7 +81,9 @@ impl Server {
}
/// Instantiates a new server associated with the provided future reactor.
pub fn future(config: ServerConfig, evt_handle: &reactor::Handle) -> Result<Server, Error> {
pub fn future(mut config: ServerConfig, evt_handle: &reactor::Handle) -> Result<Server, Error> {
check_config(&mut config);
let (chain_store, head) = try!(store_head(&config));
let shared_head = Arc::new(Mutex::new(head));
@ -90,7 +94,8 @@ impl Server {
let tx_pool = Arc::new(RwLock::new(pool::TransactionPool::new(pool_adapter)));
let chain_adapter = Arc::new(ChainToPoolAndNetAdapter::new(tx_pool.clone()));
let net_adapter = Arc::new(NetToChainAdapter::new(shared_head.clone(),
let net_adapter = Arc::new(NetToChainAdapter::new(config.test_mode,
shared_head.clone(),
chain_store.clone(),
chain_adapter.clone(),
tx_pool.clone(),
@ -176,14 +181,14 @@ fn store_head(config: &ServerConfig)
Err(store::Error::NotFoundErr) => {
info!("No genesis block found, creating and saving one.");
let mut gen = core::genesis::genesis();
if config.cuckoo_size > 0 {
gen.header.cuckoo_len = config.cuckoo_size;
let diff = gen.header.difficulty.clone();
core::pow::pow(&mut gen.header, diff).unwrap();
}
try!(chain_store.save_block(&gen).map_err(&Error::Store));
let diff = gen.header.difficulty.clone();
core::pow::pow_size(&mut gen.header,
diff,
config.mining_config.cuckoo_size as u32)
.unwrap();
chain_store.save_block(&gen).map_err(&Error::Store)?;
let tip = chain::types::Tip::new(gen.hash());
try!(chain_store.save_head(&tip).map_err(&Error::Store));
chain_store.save_head(&tip).map_err(&Error::Store)?;
info!("Saved genesis block with hash {}", gen.hash());
tip
}
@ -200,3 +205,12 @@ fn store_head(config: &ServerConfig)
Ok((Arc::new(chain_store), head))
}
fn check_config(config: &mut ServerConfig) {
// applying test/normal config
config.mining_config.cuckoo_size = if config.test_mode {
consensus::TEST_SIZESHIFT as u32
} else {
consensus::DEFAULT_SIZESHIFT as u32
};
}

View file

@ -77,9 +77,6 @@ pub struct ServerConfig {
/// Network address for the Rest API HTTP server.
pub api_http_addr: String,
/// Allows overriding the default cuckoo cycle size
pub cuckoo_size: u8,
/// Capabilities expose by this node, also conditions which other peers this
/// node will have an affinity toward when connection.
pub capabilities: p2p::Capabilities,
@ -92,6 +89,9 @@ pub struct ServerConfig {
/// Configuration for the mining daemon
pub mining_config: MinerConfig,
/// Setup the server for tests and testnet
pub test_mode: bool,
}
/// Mining configuration
@ -106,6 +106,9 @@ pub struct MinerConfig {
/// Attributes the reward to a random private key instead of contacting the
/// wallet receiver. Mostly used for tests.
pub burn_reward: bool,
/// Size of Cuckoo Cycle to mine on
pub cuckoo_size: u32,
}
impl Default for ServerConfig {
@ -113,11 +116,11 @@ impl Default for ServerConfig {
ServerConfig {
db_root: ".grin".to_string(),
api_http_addr: "127.0.0.1:13415".to_string(),
cuckoo_size: 0,
capabilities: p2p::FULL_NODE,
seeding_type: Seeding::None,
p2p_config: p2p::P2PConfig::default(),
mining_config: MinerConfig::default(),
test_mode: true,
}
}
}
@ -128,6 +131,7 @@ impl Default for MinerConfig {
enable_mining: false,
wallet_receiver_url: "http://localhost:13416".to_string(),
burn_reward: false,
cuckoo_size: 0,
}
}
}

View file

@ -41,6 +41,7 @@ use secp::Secp256k1;
use secp::key::SecretKey;
use tiny_keccak::Keccak;
use core::consensus;
use wallet::WalletConfig;
@ -75,7 +76,6 @@ impl LocalServerContainer {
grin::ServerConfig{
api_http_addr: api_addr,
db_root: format!("{}/grin-prop", working_dir),
cuckoo_size: 12,
p2p_config: p2p::P2PConfig{port: server_port, ..p2p::P2PConfig::default()},
..Default::default()
}, &event_loop.handle()).unwrap();
@ -223,6 +223,7 @@ impl LocalServerContainerPool {
enable_mining: true,
burn_reward: true,
wallet_receiver_url : format!("http://{}", wallet_url),
cuckoo_size: consensus::TEST_SIZESHIFT as u32,
..Default::default()
};
if s.enable_wallet == true {
@ -285,6 +286,7 @@ fn simulate_block_propagation() {
let miner_config = grin::MinerConfig{
enable_mining: true,
burn_reward: true,
cuckoo_size: consensus::TEST_SIZESHIFT as u32,
..Default::default()
};
@ -295,7 +297,6 @@ fn simulate_block_propagation() {
grin::ServerConfig{
api_http_addr: format!("127.0.0.1:{}", 20000+n),
db_root: format!("target/grin-prop-{}", n),
cuckoo_size: 12,
p2p_config: p2p::P2PConfig{port: 10000+n, ..p2p::P2PConfig::default()},
..Default::default()
}, &handle).unwrap();
@ -335,6 +336,7 @@ fn simulate_full_sync() {
let miner_config = grin::MinerConfig{
enable_mining: true,
burn_reward: true,
cuckoo_size: consensus::TEST_SIZESHIFT as u32,
..Default::default()
};
@ -344,7 +346,6 @@ fn simulate_full_sync() {
let s = grin::Server::future(
grin::ServerConfig{
db_root: format!("target/grin-sync-{}", n),
cuckoo_size: 12,
p2p_config: p2p::P2PConfig{port: 11000+n, ..p2p::P2PConfig::default()},
..Default::default()
}, &handle).unwrap();
@ -378,7 +379,6 @@ fn simulate_seeding() {
let s = grin::Server::future(
grin::ServerConfig{
db_root: format!("target/grin-seed-{}", n),
cuckoo_size: 12,
p2p_config: p2p::P2PConfig{port: 12000+n, ..p2p::P2PConfig::default()},
seeding_type: grin::Seeding::List(vec!["127.0.0.1:12000".to_string()]),
..Default::default()

View file

@ -282,7 +282,7 @@ fn read_config() -> grin::ServerConfig {
fn default_config() -> grin::ServerConfig {
grin::ServerConfig {
cuckoo_size: 12,
test_mode: true,
seeding_type: grin::Seeding::WebStatic,
..Default::default()
}