grin/chain/tests/mine_simple_chain.rs

814 lines
24 KiB
Rust
Raw Normal View History

// Copyright 2019 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 self::chain::types::{NoopAdapter, Tip};
use self::chain::Chain;
use self::core::core::hash::Hashed;
use self::core::core::verifier_cache::LruVerifierCache;
use self::core::core::{Block, BlockHeader, KernelFeatures, OutputIdentifier, Transaction};
use self::core::global::ChainTypes;
use self::core::libtx::{self, build, ProofBuilder};
use self::core::pow::Difficulty;
use self::core::{consensus, global, pow};
use self::keychain::{ExtKeychain, ExtKeychainPath, Keychain};
2019-05-25 19:13:09 +03:00
use self::util::RwLock;
use chrono::Duration;
use grin_chain as chain;
use grin_chain::{BlockStatus, ChainAdapter, Options};
use grin_core as core;
use grin_keychain as keychain;
use grin_util as util;
use std::sync::Arc;
mod chain_test_helper;
use self::chain_test_helper::{clean_output_dir, init_chain, mine_chain};
/// Adapter to retrieve last status
pub struct StatusAdapter {
pub last_status: RwLock<Option<BlockStatus>>,
}
impl StatusAdapter {
pub fn new(last_status: RwLock<Option<BlockStatus>>) -> Self {
StatusAdapter { last_status }
}
}
impl ChainAdapter for StatusAdapter {
fn block_accepted(&self, _b: &Block, status: BlockStatus, _opts: Options) {
*self.last_status.write() = Some(status);
}
}
/// Creates a `Chain` instance with `StatusAdapter` attached to it.
fn setup_with_status_adapter(dir_name: &str, genesis: Block, adapter: Arc<StatusAdapter>) -> Chain {
util::init_test_logger();
clean_output_dir(dir_name);
let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
let chain = chain::Chain::init(
dir_name.to_string(),
adapter,
genesis,
pow::verify_size,
verifier_cache,
false,
)
.unwrap();
chain
}
#[test]
fn mine_empty_chain() {
let chain_dir = ".grin.empty";
clean_output_dir(chain_dir);
let chain = mine_chain(chain_dir, 1);
assert_eq!(chain.head().unwrap().height, 0);
clean_output_dir(chain_dir);
}
#[test]
fn mine_short_chain() {
let chain_dir = ".grin.genesis";
clean_output_dir(chain_dir);
let chain = mine_chain(chain_dir, 4);
assert_eq!(chain.head().unwrap().height, 3);
clean_output_dir(chain_dir);
2016-10-21 03:06:12 +03:00
}
// Convenience wrapper for processing a full block on the test chain.
fn process_header(chain: &Chain, header: &BlockHeader) {
chain
.process_block_header(header, chain::Options::SKIP_POW)
.unwrap();
}
// Convenience wrapper for processing a block header on the test chain.
fn process_block(chain: &Chain, block: &Block) {
chain
.process_block(block.clone(), chain::Options::SKIP_POW)
.unwrap();
}
//
// a - b - c
// \
// - b'
//
// Process in the following order -
// 1. block_a
// 2. block_b
// 3. block_b'
// 4. header_c
// 5. block_c
//
#[test]
fn test_block_a_block_b_block_b_fork_header_c_fork_block_c() {
let chain_dir = ".grin.block_a_block_b_block_b_fork_header_c_fork_block_c";
clean_output_dir(chain_dir);
global::set_mining_mode(ChainTypes::AutomatedTesting);
let kc = ExtKeychain::from_random_seed(false).unwrap();
let genesis = pow::mine_genesis_block().unwrap();
let last_status = RwLock::new(None);
let adapter = Arc::new(StatusAdapter::new(last_status));
let chain = setup_with_status_adapter(chain_dir, genesis.clone(), adapter.clone());
let block_a = prepare_block(&kc, &chain.head_header().unwrap(), &chain, 1);
process_block(&chain, &block_a);
let block_b = prepare_block(&kc, &block_a.header, &chain, 2);
let block_b_fork = prepare_block(&kc, &block_a.header, &chain, 2);
process_block(&chain, &block_b);
process_block(&chain, &block_b_fork);
let block_c = prepare_block(&kc, &block_b.header, &chain, 3);
process_header(&chain, &block_c.header);
assert_eq!(chain.head().unwrap(), Tip::from_header(&block_b.header));
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_c.header)
);
process_block(&chain, &block_c);
assert_eq!(chain.head().unwrap(), Tip::from_header(&block_c.header));
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_c.header)
);
clean_output_dir(chain_dir);
}
//
// a - b
// \
// - b' - c'
//
// Process in the following order -
// 1. block_a
// 2. block_b
// 3. block_b'
// 4. header_c'
// 5. block_c'
//
#[test]
fn test_block_a_block_b_block_b_fork_header_c_fork_block_c_fork() {
let chain_dir = ".grin.block_a_block_b_block_b_fork_header_c_fork_block_c_fork";
clean_output_dir(chain_dir);
global::set_mining_mode(ChainTypes::AutomatedTesting);
let kc = ExtKeychain::from_random_seed(false).unwrap();
let genesis = pow::mine_genesis_block().unwrap();
let last_status = RwLock::new(None);
let adapter = Arc::new(StatusAdapter::new(last_status));
let chain = setup_with_status_adapter(chain_dir, genesis.clone(), adapter.clone());
let block_a = prepare_block(&kc, &chain.head_header().unwrap(), &chain, 1);
process_block(&chain, &block_a);
let block_b = prepare_block(&kc, &block_a.header, &chain, 2);
let block_b_fork = prepare_block(&kc, &block_a.header, &chain, 2);
process_block(&chain, &block_b);
process_block(&chain, &block_b_fork);
let block_c_fork = prepare_block(&kc, &block_b_fork.header, &chain, 3);
process_header(&chain, &block_c_fork.header);
assert_eq!(chain.head().unwrap(), Tip::from_header(&block_b.header));
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_c_fork.header)
);
process_block(&chain, &block_c_fork);
assert_eq!(
chain.head().unwrap(),
Tip::from_header(&block_c_fork.header)
);
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_c_fork.header)
);
clean_output_dir(chain_dir);
}
//
// a - b - c
// \
// - b'
//
// Process in the following order -
// 1. block_a
// 2. header_b
// 3. header_b_fork
// 4. block_b_fork
// 5. block_b
// 6. block_c
//
#[test]
fn test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c() {
let chain_dir = ".grin.test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c";
clean_output_dir(chain_dir);
global::set_mining_mode(ChainTypes::AutomatedTesting);
let kc = ExtKeychain::from_random_seed(false).unwrap();
let genesis = pow::mine_genesis_block().unwrap();
let last_status = RwLock::new(None);
let adapter = Arc::new(StatusAdapter::new(last_status));
let chain = setup_with_status_adapter(chain_dir, genesis.clone(), adapter.clone());
let block_a = prepare_block(&kc, &chain.head_header().unwrap(), &chain, 1);
process_block(&chain, &block_a);
let block_b = prepare_block(&kc, &block_a.header, &chain, 2);
let block_b_fork = prepare_block(&kc, &block_a.header, &chain, 2);
process_header(&chain, &block_b.header);
process_header(&chain, &block_b_fork.header);
process_block(&chain, &block_b_fork);
process_block(&chain, &block_b);
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_b.header)
);
assert_eq!(
chain.head().unwrap(),
Tip::from_header(&block_b_fork.header)
);
let block_c = prepare_block(&kc, &block_b.header, &chain, 3);
process_block(&chain, &block_c);
assert_eq!(chain.head().unwrap(), Tip::from_header(&block_c.header));
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_c.header)
);
clean_output_dir(chain_dir);
}
//
// a - b
// \
// - b' - c'
//
// Process in the following order -
// 1. block_a
// 2. header_b
// 3. header_b_fork
// 4. block_b_fork
// 5. block_b
// 6. block_c_fork
//
#[test]
fn test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c_fork() {
let chain_dir = ".grin.test_block_a_header_b_header_b_fork_block_b_fork_block_b_block_c_fork";
clean_output_dir(chain_dir);
global::set_mining_mode(ChainTypes::AutomatedTesting);
let kc = ExtKeychain::from_random_seed(false).unwrap();
let genesis = pow::mine_genesis_block().unwrap();
let last_status = RwLock::new(None);
let adapter = Arc::new(StatusAdapter::new(last_status));
let chain = setup_with_status_adapter(chain_dir, genesis.clone(), adapter.clone());
let block_a = prepare_block(&kc, &chain.head_header().unwrap(), &chain, 1);
process_block(&chain, &block_a);
let block_b = prepare_block(&kc, &block_a.header, &chain, 2);
let block_b_fork = prepare_block(&kc, &block_a.header, &chain, 2);
process_header(&chain, &block_b.header);
process_header(&chain, &block_b_fork.header);
process_block(&chain, &block_b_fork);
process_block(&chain, &block_b);
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_b.header)
);
assert_eq!(
chain.head().unwrap(),
Tip::from_header(&block_b_fork.header)
);
let block_c_fork = prepare_block(&kc, &block_b_fork.header, &chain, 3);
process_block(&chain, &block_c_fork);
assert_eq!(
chain.head().unwrap(),
Tip::from_header(&block_c_fork.header)
);
assert_eq!(
chain.header_head().unwrap(),
Tip::from_header(&block_c_fork.header)
);
clean_output_dir(chain_dir);
}
#[test]
// This test creates a reorg at REORG_DEPTH by mining a block with difficulty that
// exceeds original chain total difficulty.
//
// Illustration of reorg with NUM_BLOCKS_MAIN = 6 and REORG_DEPTH = 5:
//
// difficulty: 1 2 3 4 5 6
//
// / [ 2 ] - [ 3 ] - [ 4 ] - [ 5 ] - [ 6 ] <- original chain
// [ Genesis ] -[ 1 ]- *
// ^ \ [ 2' ] - ................................ <- reorg chain with depth 5
// |
// difficulty: 1 | 24
// |
// \----< Fork point and chain reorg
fn mine_reorg() {
// Test configuration
const NUM_BLOCKS_MAIN: u64 = 6; // Number of blocks to mine in main chain
const REORG_DEPTH: u64 = 5; // Number of blocks to be discarded from main chain after reorg
const DIR_NAME: &str = ".grin_reorg";
clean_output_dir(DIR_NAME);
global::set_mining_mode(ChainTypes::AutomatedTesting);
let kc = ExtKeychain::from_random_seed(false).unwrap();
let genesis = pow::mine_genesis_block().unwrap();
{
// Create chain that reports last block status
2019-05-25 19:13:09 +03:00
let last_status = RwLock::new(None);
let adapter = Arc::new(StatusAdapter::new(last_status));
let chain = setup_with_status_adapter(DIR_NAME, genesis.clone(), adapter.clone());
// Add blocks to main chain with gradually increasing difficulty
let mut prev = chain.head_header().unwrap();
for n in 1..=NUM_BLOCKS_MAIN {
let b = prepare_block(&kc, &prev, &chain, n);
prev = b.header.clone();
chain.process_block(b, chain::Options::SKIP_POW).unwrap();
}
let head = chain.head_header().unwrap();
assert_eq!(head.height, NUM_BLOCKS_MAIN);
assert_eq!(head.hash(), prev.hash());
// Reorg chain should exceed main chain's total difficulty to be considered
let reorg_difficulty = head.total_difficulty().to_num();
// Create one block for reorg chain forking off NUM_BLOCKS_MAIN - REORG_DEPTH height
let fork_head = chain
.get_header_by_height(NUM_BLOCKS_MAIN - REORG_DEPTH)
.unwrap();
let b = prepare_block(&kc, &fork_head, &chain, reorg_difficulty);
let reorg_head = b.header.clone();
chain.process_block(b, chain::Options::SKIP_POW).unwrap();
// Check that reorg is correctly reported in block status
assert_eq!(
*adapter.last_status.read(),
Some(BlockStatus::Reorg(REORG_DEPTH))
);
// Chain should be switched to the reorganized chain
let head = chain.head_header().unwrap();
assert_eq!(head.height, NUM_BLOCKS_MAIN - REORG_DEPTH + 1);
assert_eq!(head.hash(), reorg_head.hash());
}
// Cleanup chain directory
clean_output_dir(DIR_NAME);
}
#[test]
fn mine_forks() {
Wallet LMDB backend (#1151) * Migrate main node store to LMDB In preparation to using LMDB as a wallet database, migrate the node db. There's no point in having 2 key-value stores. In addition LMDB provides a few advantages as a node db, namely a much faster build (compared to RocksDb), lesser dependencies and transactions. * Migrated p2p store to lmdb, stuff compiles * More fixes, chain tests starting to pass * Fixed txhashset rollback messing with block save and general batch delimitation. Chain tests passing. * rustfmt * LMDB max map size of 10MB isn't really workable. Half TB seems reasonable. * Fix wallet tests * Rather crucial commit was missing * rustfmt * Fixing new merged tests following lmdb changes * rustfmt * * Make txhashset validation read-only on fast sync to avoid having a really long open transaction. * Fix deadlock in new block processing, batch should always be created within a txhashset lock (when they interact). * Comment about batch and txhashset interlacing * Fix store tests to use batch * Externalize wallet config and seed * Converted direct read access to file outputs map to an iterator * Cleaned up and simplified wallet Backend trait: * No more direct mutable access to internal structures (HashMap) * Batch interface for all writes * Remove unneeded read wrapper (read_wallet) * rustfmt * First (incomplete) pass at wallet LMDB backend * Progressing on lmdb backent iml * Added batch impl for LMDB wallet backend. Pretty much done with it, but not sure how to deal with commit (owned). * rustfmt * Wrapping LMDB batch around a refcell to work around borrow rules * Compilation up to grin chain
2018-06-22 11:08:06 +03:00
global::set_mining_mode(ChainTypes::AutomatedTesting);
{
let chain = init_chain(".grin2", pow::mine_genesis_block().unwrap());
let kc = ExtKeychain::from_random_seed(false).unwrap();
// add a first block to not fork genesis
let prev = chain.head_header().unwrap();
let b = prepare_block(&kc, &prev, &chain, 2);
chain.process_block(b, chain::Options::SKIP_POW).unwrap();
// mine and add a few blocks
for n in 1..4 {
// first block for one branch
let prev = chain.head_header().unwrap();
let b1 = prepare_block(&kc, &prev, &chain, 3 * n);
// process the first block to extend the chain
let bhash = b1.hash();
chain.process_block(b1, chain::Options::SKIP_POW).unwrap();
// checking our new head
let head = chain.head().unwrap();
assert_eq!(head.height, (n + 1) as u64);
assert_eq!(head.last_block_h, bhash);
assert_eq!(head.prev_block_h, prev.hash());
// 2nd block with higher difficulty for other branch
let b2 = prepare_block(&kc, &prev, &chain, 3 * n + 1);
// process the 2nd block to build a fork with more work
let bhash = b2.hash();
chain.process_block(b2, chain::Options::SKIP_POW).unwrap();
// checking head switch
let head = chain.head().unwrap();
assert_eq!(head.height, (n + 1) as u64);
assert_eq!(head.last_block_h, bhash);
assert_eq!(head.prev_block_h, prev.hash());
}
}
// Cleanup chain directory
clean_output_dir(".grin2");
}
#[test]
fn mine_losing_fork() {
Wallet LMDB backend (#1151) * Migrate main node store to LMDB In preparation to using LMDB as a wallet database, migrate the node db. There's no point in having 2 key-value stores. In addition LMDB provides a few advantages as a node db, namely a much faster build (compared to RocksDb), lesser dependencies and transactions. * Migrated p2p store to lmdb, stuff compiles * More fixes, chain tests starting to pass * Fixed txhashset rollback messing with block save and general batch delimitation. Chain tests passing. * rustfmt * LMDB max map size of 10MB isn't really workable. Half TB seems reasonable. * Fix wallet tests * Rather crucial commit was missing * rustfmt * Fixing new merged tests following lmdb changes * rustfmt * * Make txhashset validation read-only on fast sync to avoid having a really long open transaction. * Fix deadlock in new block processing, batch should always be created within a txhashset lock (when they interact). * Comment about batch and txhashset interlacing * Fix store tests to use batch * Externalize wallet config and seed * Converted direct read access to file outputs map to an iterator * Cleaned up and simplified wallet Backend trait: * No more direct mutable access to internal structures (HashMap) * Batch interface for all writes * Remove unneeded read wrapper (read_wallet) * rustfmt * First (incomplete) pass at wallet LMDB backend * Progressing on lmdb backent iml * Added batch impl for LMDB wallet backend. Pretty much done with it, but not sure how to deal with commit (owned). * rustfmt * Wrapping LMDB batch around a refcell to work around borrow rules * Compilation up to grin chain
2018-06-22 11:08:06 +03:00
global::set_mining_mode(ChainTypes::AutomatedTesting);
Re-launch floonet (#2249) * Fix secondary scaling bugs; rename is_testnet -> is_floonet (#2215) * add global::is_mainnet() * use it to change pre-genesis pow type * rename is_testnet -> is_floonet * Support multiple chain configurations (#2217) * Support multiple chain configurations Supports generating the proper configuration for each chain type (mainnet, floonet, usernet). Will run them by default under their respective root directory (~/.grin/main, ~/.grin/floo, etc). Assigned default ports for mainnet, overriding them to keep Floonet ports unchanged. For now, starting on mainnet will abort. * Fixed usernet command line help message. Fixes #2217 * Differing magic numbers for each chain type (#2208) * stick to e=H(R|P|m) when use schnorr signature (#2200) * stick to e=H(R|P|m) when use schnorr signature * (1)add verify_slate_messages for wallet receive (2)log the message content * remove debug log on verify_slate_messages * verify the sender's message signature when receive_tx in wallet listen * Revert "remove debug log on verify_slate_messages" This reverts commit 65ea32a407bfd57d02bf169803f1483ba611962e. * Revert "rustfmt" This reverts commit c380ab91856344b73595bb04eef1fc087dedd84d. * Revert "(1)add verify_slate_messages for wallet receive (2)log the message content" This reverts commit 9584ca7a893b22a768dea061039140033c07e8eb. * [re-floonet] Keychain Floonet BIP32 version/network option (#2235) * add 'is_floonet' property to keychain * fix hex encoding and tests * Fix couple floonet loose ends (#2230) * Fix couple floonet loose ends. Fixes #2216 * Doc fix for sig message * Refuse unkown kernel features (#2244) * Minor: magic number change for re-floonet * Set pre genesis is_secondary to true (#2247) * Minor: tx validation error display underlying * New floonet genesis * genesis rustfmt * Use chain-specific config for wallet toml gen * Fix default wallet_listener_url * New more reasonable genesis block, bumped version * genesis rustfmt * Couple minor fixes to genesis generation script
2018-12-29 01:46:21 +03:00
let kc = ExtKeychain::from_random_seed(false).unwrap();
{
let chain = init_chain(".grin3", pow::mine_genesis_block().unwrap());
// add a first block we'll be forking from
let prev = chain.head_header().unwrap();
let b1 = prepare_block(&kc, &prev, &chain, 2);
let b1head = b1.header.clone();
chain.process_block(b1, chain::Options::SKIP_POW).unwrap();
// prepare the 2 successor, sibling blocks, one with lower diff
let b2 = prepare_block(&kc, &b1head, &chain, 4);
let b2head = b2.header.clone();
let bfork = prepare_block(&kc, &b1head, &chain, 3);
// add higher difficulty first, prepare its successor, then fork
// with lower diff
chain.process_block(b2, chain::Options::SKIP_POW).unwrap();
assert_eq!(chain.head_header().unwrap().hash(), b2head.hash());
let b3 = prepare_block(&kc, &b2head, &chain, 5);
chain
.process_block(bfork, chain::Options::SKIP_POW)
.unwrap();
// adding the successor
let b3head = b3.header.clone();
chain.process_block(b3, chain::Options::SKIP_POW).unwrap();
assert_eq!(chain.head_header().unwrap().hash(), b3head.hash());
}
// Cleanup chain directory
clean_output_dir(".grin3");
}
#[test]
fn longer_fork() {
Wallet LMDB backend (#1151) * Migrate main node store to LMDB In preparation to using LMDB as a wallet database, migrate the node db. There's no point in having 2 key-value stores. In addition LMDB provides a few advantages as a node db, namely a much faster build (compared to RocksDb), lesser dependencies and transactions. * Migrated p2p store to lmdb, stuff compiles * More fixes, chain tests starting to pass * Fixed txhashset rollback messing with block save and general batch delimitation. Chain tests passing. * rustfmt * LMDB max map size of 10MB isn't really workable. Half TB seems reasonable. * Fix wallet tests * Rather crucial commit was missing * rustfmt * Fixing new merged tests following lmdb changes * rustfmt * * Make txhashset validation read-only on fast sync to avoid having a really long open transaction. * Fix deadlock in new block processing, batch should always be created within a txhashset lock (when they interact). * Comment about batch and txhashset interlacing * Fix store tests to use batch * Externalize wallet config and seed * Converted direct read access to file outputs map to an iterator * Cleaned up and simplified wallet Backend trait: * No more direct mutable access to internal structures (HashMap) * Batch interface for all writes * Remove unneeded read wrapper (read_wallet) * rustfmt * First (incomplete) pass at wallet LMDB backend * Progressing on lmdb backent iml * Added batch impl for LMDB wallet backend. Pretty much done with it, but not sure how to deal with commit (owned). * rustfmt * Wrapping LMDB batch around a refcell to work around borrow rules * Compilation up to grin chain
2018-06-22 11:08:06 +03:00
global::set_mining_mode(ChainTypes::AutomatedTesting);
Re-launch floonet (#2249) * Fix secondary scaling bugs; rename is_testnet -> is_floonet (#2215) * add global::is_mainnet() * use it to change pre-genesis pow type * rename is_testnet -> is_floonet * Support multiple chain configurations (#2217) * Support multiple chain configurations Supports generating the proper configuration for each chain type (mainnet, floonet, usernet). Will run them by default under their respective root directory (~/.grin/main, ~/.grin/floo, etc). Assigned default ports for mainnet, overriding them to keep Floonet ports unchanged. For now, starting on mainnet will abort. * Fixed usernet command line help message. Fixes #2217 * Differing magic numbers for each chain type (#2208) * stick to e=H(R|P|m) when use schnorr signature (#2200) * stick to e=H(R|P|m) when use schnorr signature * (1)add verify_slate_messages for wallet receive (2)log the message content * remove debug log on verify_slate_messages * verify the sender's message signature when receive_tx in wallet listen * Revert "remove debug log on verify_slate_messages" This reverts commit 65ea32a407bfd57d02bf169803f1483ba611962e. * Revert "rustfmt" This reverts commit c380ab91856344b73595bb04eef1fc087dedd84d. * Revert "(1)add verify_slate_messages for wallet receive (2)log the message content" This reverts commit 9584ca7a893b22a768dea061039140033c07e8eb. * [re-floonet] Keychain Floonet BIP32 version/network option (#2235) * add 'is_floonet' property to keychain * fix hex encoding and tests * Fix couple floonet loose ends (#2230) * Fix couple floonet loose ends. Fixes #2216 * Doc fix for sig message * Refuse unkown kernel features (#2244) * Minor: magic number change for re-floonet * Set pre genesis is_secondary to true (#2247) * Minor: tx validation error display underlying * New floonet genesis * genesis rustfmt * Use chain-specific config for wallet toml gen * Fix default wallet_listener_url * New more reasonable genesis block, bumped version * genesis rustfmt * Couple minor fixes to genesis generation script
2018-12-29 01:46:21 +03:00
let kc = ExtKeychain::from_random_seed(false).unwrap();
// to make it easier to compute the txhashset roots in the test, we
// prepare 2 chains, the 2nd will be have the forked blocks we can
// then send back on the 1st
Wallet LMDB backend (#1151) * Migrate main node store to LMDB In preparation to using LMDB as a wallet database, migrate the node db. There's no point in having 2 key-value stores. In addition LMDB provides a few advantages as a node db, namely a much faster build (compared to RocksDb), lesser dependencies and transactions. * Migrated p2p store to lmdb, stuff compiles * More fixes, chain tests starting to pass * Fixed txhashset rollback messing with block save and general batch delimitation. Chain tests passing. * rustfmt * LMDB max map size of 10MB isn't really workable. Half TB seems reasonable. * Fix wallet tests * Rather crucial commit was missing * rustfmt * Fixing new merged tests following lmdb changes * rustfmt * * Make txhashset validation read-only on fast sync to avoid having a really long open transaction. * Fix deadlock in new block processing, batch should always be created within a txhashset lock (when they interact). * Comment about batch and txhashset interlacing * Fix store tests to use batch * Externalize wallet config and seed * Converted direct read access to file outputs map to an iterator * Cleaned up and simplified wallet Backend trait: * No more direct mutable access to internal structures (HashMap) * Batch interface for all writes * Remove unneeded read wrapper (read_wallet) * rustfmt * First (incomplete) pass at wallet LMDB backend * Progressing on lmdb backent iml * Added batch impl for LMDB wallet backend. Pretty much done with it, but not sure how to deal with commit (owned). * rustfmt * Wrapping LMDB batch around a refcell to work around borrow rules * Compilation up to grin chain
2018-06-22 11:08:06 +03:00
let genesis = pow::mine_genesis_block().unwrap();
{
let chain = init_chain(".grin4", genesis.clone());
// add blocks to both chains, 20 on the main one, only the first 5
// for the forked chain
let mut prev = chain.head_header().unwrap();
for n in 0..10 {
let b = prepare_block(&kc, &prev, &chain, 2 * n + 2);
prev = b.header.clone();
chain.process_block(b, chain::Options::SKIP_POW).unwrap();
}
let forked_block = chain.get_header_by_height(5).unwrap();
let head = chain.head_header().unwrap();
assert_eq!(head.height, 10);
assert_eq!(head.hash(), prev.hash());
let mut prev = forked_block;
for n in 0..7 {
let b = prepare_block(&kc, &prev, &chain, 2 * n + 11);
prev = b.header.clone();
chain.process_block(b, chain::Options::SKIP_POW).unwrap();
}
let new_head = prev;
// After all this the chain should have switched to the fork.
let head = chain.head_header().unwrap();
assert_eq!(head.height, 12);
assert_eq!(head.hash(), new_head.hash());
}
// Cleanup chain directory
clean_output_dir(".grin4");
}
#[test]
fn spend_in_fork_and_compact() {
Wallet LMDB backend (#1151) * Migrate main node store to LMDB In preparation to using LMDB as a wallet database, migrate the node db. There's no point in having 2 key-value stores. In addition LMDB provides a few advantages as a node db, namely a much faster build (compared to RocksDb), lesser dependencies and transactions. * Migrated p2p store to lmdb, stuff compiles * More fixes, chain tests starting to pass * Fixed txhashset rollback messing with block save and general batch delimitation. Chain tests passing. * rustfmt * LMDB max map size of 10MB isn't really workable. Half TB seems reasonable. * Fix wallet tests * Rather crucial commit was missing * rustfmt * Fixing new merged tests following lmdb changes * rustfmt * * Make txhashset validation read-only on fast sync to avoid having a really long open transaction. * Fix deadlock in new block processing, batch should always be created within a txhashset lock (when they interact). * Comment about batch and txhashset interlacing * Fix store tests to use batch * Externalize wallet config and seed * Converted direct read access to file outputs map to an iterator * Cleaned up and simplified wallet Backend trait: * No more direct mutable access to internal structures (HashMap) * Batch interface for all writes * Remove unneeded read wrapper (read_wallet) * rustfmt * First (incomplete) pass at wallet LMDB backend * Progressing on lmdb backent iml * Added batch impl for LMDB wallet backend. Pretty much done with it, but not sure how to deal with commit (owned). * rustfmt * Wrapping LMDB batch around a refcell to work around borrow rules * Compilation up to grin chain
2018-06-22 11:08:06 +03:00
global::set_mining_mode(ChainTypes::AutomatedTesting);
util::init_test_logger();
// Cleanup chain directory
clean_output_dir(".grin6");
{
let chain = init_chain(".grin6", pow::mine_genesis_block().unwrap());
let prev = chain.head_header().unwrap();
let kc = ExtKeychain::from_random_seed(false).unwrap();
Master merge 2.0.0 (#2927) * create 2.0.0 branch * fix humansize version * update grin.yml version * PoW HardFork (#2866) * allow version 2 blocks for next 6 months * add cuckarood.rs with working tests * switch cuckaroo to cuckarood at right heights * reorder to reduce conditions * remove _ prefix on used args; fix typo * Make Valid Header Version dependant on ChainType * Rustfmt * Add tests, uncomment header v2 * Rustfmt * Add FLOONET_FIRST_HARD_FORK height and simplify logic * assume floonet stays closer to avg 60s block time * move floonet hf forward by half a day * update version in new block when previous no longer valid * my next commit:-) * micro optimization * Support new Bulletproof rewind scheme (#2848) * Update keychain with new rewind scheme * Refactor: proof builder trait * Update tests, cleanup * rustfmt * Move conversion of SwitchCommitmentType * Add proof build trait to tx builders * Cache hashes in proof builders * Proof builder tests * Add ViewKey struct * Fix some warnings * Zeroize proof builder secrets on drop * Modify mine_block to use wallet V2 API (#2892) * update mine_block to use V2 wallet API * rustfmt * Add version endpoint to node API, rename pool/push (#2897) * add node version API, tweak pool/push parameter * rustfmt * Upate version api call (#2899) * Update version number for next (potential) release * zeroize: Upgrade to v0.9 (#2914) * zeroize: Upgrade to v0.9 * missed Cargo.lock * [PENDING APPROVAL] put phase outs of C32 and beyond on hold (#2714) * put phase outs of C32 and beyond on hold * update tests for phaseouts on hold * Don't wait for p2p-server thread (#2917) Currently p2p.stop() stops and wait for all peers to exit, that's basically all we need. However we also run a TCP listener in this thread which is blocked on `accept` most of the time. We do an attempt to stop it but it would work only if we get an incoming connection during the shutdown, which is a week guarantee. This fix remove joining to p2p-server thread, it stops all peers and makes an attempt to stop the listener. Fixes [#2906] * rustfmt
2019-06-27 11:19:17 +03:00
let pb = ProofBuilder::new(&kc);
let mut fork_head = prev;
hash (features|commitment) in output mmr (#615) * experiment with lock_heights on outputs * playing around with lock_height as part of the switch commitment hash * cleanup * include features in the switch commit hash key * commit * rebase off master * commit * cleanup * missing docs * rework coinbase maturity test to build valid tx * pool and chain tests passing (inputs have switch commitments) * commit * cleanup * check inputs spending coinbase outputs have valid lock_heights * wip - got it building (tests still failing) * use zero key for non coinbase switch commit hash * fees and height wrong order... * send output lock_height over to wallet via api * no more header by height index workaround this for wallet refresh and wallet restore * refresh heights for unspent wallet outputs where missing * TODO - might be slow? * simplify - do not pass around lock_height for non coinbase outputs * commit * fix tests after merge * build input vs coinbase_input switch commit hash key encodes lock_height cleanup output by commit index (currently broken...) * is_unspent and get_unspent cleanup - we have no outputs, only switch_commit_hashes * separate concept of utxo vs output in the api utxos come from the sumtrees (and only the sumtrees, limited info) outputs come from blocks (and we need to look them up via block height) * cleanup * better api support for block outputs with range proofs * basic wallet operations appear to work restore is not working fully refresh refreshes heights correctly (at least appears to) * wallet refresh and wallet restore appear to be working now * fix core tests * fix some mine_simple_chain tests * fixup chain tests * rework so pool tests pass * wallet restore now safely habndles duplicate commitments (reused wallet keys) for coinbase outputs where lock_height is _very_ important * wip * validate_coinbase_maturity got things building tests are failing * lite vs full versions of is_unspent * builds and working locally zero-conf - what to do here? * handle zero-conf edge case (use latest block) * introduce OutputIdentifier, avoid leaking SumCommit everywhere * fix the bad merge * pool verifies coinbase maturity via is_matured this uses sumtree in a consistent way * cleanup * add docs, cleanup build warnings * fix core tests * fix chain tests * fix pool tests * cleanup debug logging that we no longer need * make out_block optional on an input (only care about it for spending coinbase outputs) * cleanup * bump the build
2018-01-17 06:03:40 +03:00
// mine the first block and keep track of the block_hash
// so we can spend the coinbase later
let b = prepare_block(&kc, &fork_head, &chain, 2);
let out_id = OutputIdentifier::from_output(&b.outputs()[0]);
assert!(out_id.features.is_coinbase());
fork_head = b.header.clone();
chain
.process_block(b.clone(), chain::Options::SKIP_POW)
.unwrap();
// now mine three further blocks
for n in 3..6 {
let b = prepare_block(&kc, &fork_head, &chain, n);
fork_head = b.header.clone();
chain.process_block(b, chain::Options::SKIP_POW).unwrap();
}
// Check the height of the "fork block".
assert_eq!(fork_head.height, 4);
let key_id2 = ExtKeychainPath::new(1, 2, 0, 0, 0).to_identifier();
let key_id30 = ExtKeychainPath::new(1, 30, 0, 0, 0).to_identifier();
let key_id31 = ExtKeychainPath::new(1, 31, 0, 0, 0).to_identifier();
let tx1 = build::transaction(
KernelFeatures::Plain { fee: 20000 },
vec![
build::coinbase_input(consensus::REWARD, key_id2.clone()),
build::output(consensus::REWARD - 20000, key_id30.clone()),
],
&kc,
Master merge 2.0.0 (#2927) * create 2.0.0 branch * fix humansize version * update grin.yml version * PoW HardFork (#2866) * allow version 2 blocks for next 6 months * add cuckarood.rs with working tests * switch cuckaroo to cuckarood at right heights * reorder to reduce conditions * remove _ prefix on used args; fix typo * Make Valid Header Version dependant on ChainType * Rustfmt * Add tests, uncomment header v2 * Rustfmt * Add FLOONET_FIRST_HARD_FORK height and simplify logic * assume floonet stays closer to avg 60s block time * move floonet hf forward by half a day * update version in new block when previous no longer valid * my next commit:-) * micro optimization * Support new Bulletproof rewind scheme (#2848) * Update keychain with new rewind scheme * Refactor: proof builder trait * Update tests, cleanup * rustfmt * Move conversion of SwitchCommitmentType * Add proof build trait to tx builders * Cache hashes in proof builders * Proof builder tests * Add ViewKey struct * Fix some warnings * Zeroize proof builder secrets on drop * Modify mine_block to use wallet V2 API (#2892) * update mine_block to use V2 wallet API * rustfmt * Add version endpoint to node API, rename pool/push (#2897) * add node version API, tweak pool/push parameter * rustfmt * Upate version api call (#2899) * Update version number for next (potential) release * zeroize: Upgrade to v0.9 (#2914) * zeroize: Upgrade to v0.9 * missed Cargo.lock * [PENDING APPROVAL] put phase outs of C32 and beyond on hold (#2714) * put phase outs of C32 and beyond on hold * update tests for phaseouts on hold * Don't wait for p2p-server thread (#2917) Currently p2p.stop() stops and wait for all peers to exit, that's basically all we need. However we also run a TCP listener in this thread which is blocked on `accept` most of the time. We do an attempt to stop it but it would work only if we get an incoming connection during the shutdown, which is a week guarantee. This fix remove joining to p2p-server thread, it stops all peers and makes an attempt to stop the listener. Fixes [#2906] * rustfmt
2019-06-27 11:19:17 +03:00
&pb,
)
.unwrap();
let next = prepare_block_tx(&kc, &fork_head, &chain, 7, vec![&tx1]);
let prev_main = next.header.clone();
chain
.process_block(next.clone(), chain::Options::SKIP_POW)
.unwrap();
chain.validate(false).unwrap();
let tx2 = build::transaction(
KernelFeatures::Plain { fee: 20000 },
vec![
build::input(consensus::REWARD - 20000, key_id30.clone()),
build::output(consensus::REWARD - 40000, key_id31.clone()),
],
&kc,
Master merge 2.0.0 (#2927) * create 2.0.0 branch * fix humansize version * update grin.yml version * PoW HardFork (#2866) * allow version 2 blocks for next 6 months * add cuckarood.rs with working tests * switch cuckaroo to cuckarood at right heights * reorder to reduce conditions * remove _ prefix on used args; fix typo * Make Valid Header Version dependant on ChainType * Rustfmt * Add tests, uncomment header v2 * Rustfmt * Add FLOONET_FIRST_HARD_FORK height and simplify logic * assume floonet stays closer to avg 60s block time * move floonet hf forward by half a day * update version in new block when previous no longer valid * my next commit:-) * micro optimization * Support new Bulletproof rewind scheme (#2848) * Update keychain with new rewind scheme * Refactor: proof builder trait * Update tests, cleanup * rustfmt * Move conversion of SwitchCommitmentType * Add proof build trait to tx builders * Cache hashes in proof builders * Proof builder tests * Add ViewKey struct * Fix some warnings * Zeroize proof builder secrets on drop * Modify mine_block to use wallet V2 API (#2892) * update mine_block to use V2 wallet API * rustfmt * Add version endpoint to node API, rename pool/push (#2897) * add node version API, tweak pool/push parameter * rustfmt * Upate version api call (#2899) * Update version number for next (potential) release * zeroize: Upgrade to v0.9 (#2914) * zeroize: Upgrade to v0.9 * missed Cargo.lock * [PENDING APPROVAL] put phase outs of C32 and beyond on hold (#2714) * put phase outs of C32 and beyond on hold * update tests for phaseouts on hold * Don't wait for p2p-server thread (#2917) Currently p2p.stop() stops and wait for all peers to exit, that's basically all we need. However we also run a TCP listener in this thread which is blocked on `accept` most of the time. We do an attempt to stop it but it would work only if we get an incoming connection during the shutdown, which is a week guarantee. This fix remove joining to p2p-server thread, it stops all peers and makes an attempt to stop the listener. Fixes [#2906] * rustfmt
2019-06-27 11:19:17 +03:00
&pb,
)
2018-03-04 03:19:54 +03:00
.unwrap();
let next = prepare_block_tx(&kc, &prev_main, &chain, 9, vec![&tx2]);
let prev_main = next.header.clone();
chain.process_block(next, chain::Options::SKIP_POW).unwrap();
// Full chain validation for completeness.
chain.validate(false).unwrap();
// mine 2 forked blocks from the first
let fork = prepare_block_tx(&kc, &fork_head, &chain, 6, vec![&tx1]);
let prev_fork = fork.header.clone();
chain.process_block(fork, chain::Options::SKIP_POW).unwrap();
let fork_next = prepare_block_tx(&kc, &prev_fork, &chain, 8, vec![&tx2]);
let prev_fork = fork_next.header.clone();
chain
.process_block(fork_next, chain::Options::SKIP_POW)
.unwrap();
Minimal Transaction Pool (#1067) * verify a tx like we verify a block (experimental) * first minimal_pool test up and running but not testing what we need to * rework tx_pool validation to use txhashset extension * minimal tx pool wired up but rough * works locally (rough statew though) delete "legacy" pool and graph code * rework the new pool into TransactionPool and Pool impls * rework pool to store pool entries with associated timer and source etc. * all_transactions * extra_txs so we can validate stempool against existing txpool * rework reconcile_block * txhashset apply_raw_tx can now rewind to a checkpoint (prev raw tx) * wip - txhashset tx tests * more flexible rewind on MMRs * add tests to cover apply_raw_txs on txhashset extension * add_to_stempool and add_to_txpool * deaggregate multi kernel tx when adding to txpoool * handle freshness in stempool handle propagation of stempool txs via dandelion monitor * patience timer and fluff if we cannot propagate to next relay * aggregate and fluff stempool is we have no relay * refactor coinbase maturity * rewrote basic tx pool tests to use a real txhashset via chain adapter * rework dandelion monitor to reflect recent discussion works locally but needs a cleanup * refactor dandelion_monitor - split out phases * more pool test coverage * remove old test code from pool (still wip) * block_building and block_reconciliation tests * tracked down chain test failure... * fix test_coinbase_maturity * dandelion_monitor now runs... * refactor dandelion config, shared across p2p and pool components * fix pool tests with new config * fix p2p tests * rework tx pool to deal with duplicate commitments (testnet2 limitation) * cleanup and address some PR feedback * add big comment about pre_tx...
2018-05-30 23:57:13 +03:00
chain.validate(false).unwrap();
// check state
let head = chain.head_header().unwrap();
assert_eq!(head.height, 6);
assert_eq!(head.hash(), prev_main.hash());
assert!(chain
.is_unspent(&OutputIdentifier::from_output(&tx2.outputs()[0]))
.is_ok());
assert!(chain
.is_unspent(&OutputIdentifier::from_output(&tx1.outputs()[0]))
.is_err());
// make the fork win
let fork_next = prepare_block(&kc, &prev_fork, &chain, 10);
let prev_fork = fork_next.header.clone();
chain
.process_block(fork_next, chain::Options::SKIP_POW)
.unwrap();
chain.validate(false).unwrap();
// check state
let head = chain.head_header().unwrap();
assert_eq!(head.height, 7);
assert_eq!(head.hash(), prev_fork.hash());
assert!(chain
.is_unspent(&OutputIdentifier::from_output(&tx2.outputs()[0]))
.is_ok());
assert!(chain
.is_unspent(&OutputIdentifier::from_output(&tx1.outputs()[0]))
.is_err());
// add 20 blocks to go past the test horizon
let mut prev = prev_fork;
for n in 0..20 {
let next = prepare_block(&kc, &prev, &chain, 11 + n);
prev = next.header.clone();
chain.process_block(next, chain::Options::SKIP_POW).unwrap();
}
chain.validate(false).unwrap();
if let Err(e) = chain.compact() {
panic!("Error compacting chain: {:?}", e);
}
if let Err(e) = chain.validate(false) {
panic!("Validation error after compacting chain: {:?}", e);
}
2018-06-22 16:04:51 +03:00
}
// Cleanup chain directory
clean_output_dir(".grin6");
}
/// Test ability to retrieve block headers for a given output
#[test]
fn output_header_mappings() {
global::set_mining_mode(ChainTypes::AutomatedTesting);
{
let chain = init_chain(
".grin_header_for_output",
pow::mine_genesis_block().unwrap(),
);
let keychain = ExtKeychain::from_random_seed(false).unwrap();
let mut reward_outputs = vec![];
for n in 1..15 {
let prev = chain.head_header().unwrap();
let next_header_info = consensus::next_difficulty(1, chain.difficulty_iter().unwrap());
let pk = ExtKeychainPath::new(1, n as u32, 0, 0, 0).to_identifier();
Master merge 2.0.0 (#2927) * create 2.0.0 branch * fix humansize version * update grin.yml version * PoW HardFork (#2866) * allow version 2 blocks for next 6 months * add cuckarood.rs with working tests * switch cuckaroo to cuckarood at right heights * reorder to reduce conditions * remove _ prefix on used args; fix typo * Make Valid Header Version dependant on ChainType * Rustfmt * Add tests, uncomment header v2 * Rustfmt * Add FLOONET_FIRST_HARD_FORK height and simplify logic * assume floonet stays closer to avg 60s block time * move floonet hf forward by half a day * update version in new block when previous no longer valid * my next commit:-) * micro optimization * Support new Bulletproof rewind scheme (#2848) * Update keychain with new rewind scheme * Refactor: proof builder trait * Update tests, cleanup * rustfmt * Move conversion of SwitchCommitmentType * Add proof build trait to tx builders * Cache hashes in proof builders * Proof builder tests * Add ViewKey struct * Fix some warnings * Zeroize proof builder secrets on drop * Modify mine_block to use wallet V2 API (#2892) * update mine_block to use V2 wallet API * rustfmt * Add version endpoint to node API, rename pool/push (#2897) * add node version API, tweak pool/push parameter * rustfmt * Upate version api call (#2899) * Update version number for next (potential) release * zeroize: Upgrade to v0.9 (#2914) * zeroize: Upgrade to v0.9 * missed Cargo.lock * [PENDING APPROVAL] put phase outs of C32 and beyond on hold (#2714) * put phase outs of C32 and beyond on hold * update tests for phaseouts on hold * Don't wait for p2p-server thread (#2917) Currently p2p.stop() stops and wait for all peers to exit, that's basically all we need. However we also run a TCP listener in this thread which is blocked on `accept` most of the time. We do an attempt to stop it but it would work only if we get an incoming connection during the shutdown, which is a week guarantee. This fix remove joining to p2p-server thread, it stops all peers and makes an attempt to stop the listener. Fixes [#2906] * rustfmt
2019-06-27 11:19:17 +03:00
let reward = libtx::reward::output(
&keychain,
&libtx::ProofBuilder::new(&keychain),
&pk,
0,
false,
)
.unwrap();
reward_outputs.push(reward.0.clone());
let mut b =
core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward)
.unwrap();
b.header.timestamp = prev.timestamp + Duration::seconds(60);
b.header.pow.secondary_scaling = next_header_info.secondary_scaling;
chain.set_txhashset_roots(&mut b).unwrap();
let edge_bits = if n == 2 {
global::min_edge_bits() + 1
} else {
global::min_edge_bits()
};
b.header.pow.proof.edge_bits = edge_bits;
pow::pow_size(
&mut b.header,
next_header_info.difficulty,
global::proofsize(),
edge_bits,
)
.unwrap();
b.header.pow.proof.edge_bits = edge_bits;
chain.process_block(b, chain::Options::MINE).unwrap();
let header_for_output = chain
.get_header_for_output(&OutputIdentifier::from_output(&reward_outputs[n - 1]))
.unwrap();
assert_eq!(header_for_output.height, n as u64);
chain.validate(false).unwrap();
}
// Check all output positions are as expected
for n in 1..15 {
let header_for_output = chain
.get_header_for_output(&OutputIdentifier::from_output(&reward_outputs[n - 1]))
.unwrap();
assert_eq!(header_for_output.height, n as u64);
}
}
// Cleanup chain directory
clean_output_dir(".grin_header_for_output");
}
fn prepare_block<K>(kc: &K, prev: &BlockHeader, chain: &Chain, diff: u64) -> Block
where
K: Keychain,
{
let mut b = prepare_block_nosum(kc, prev, diff, vec![]);
chain.set_txhashset_roots(&mut b).unwrap();
b
}
fn prepare_block_tx<K>(
kc: &K,
2018-03-04 03:19:54 +03:00
prev: &BlockHeader,
chain: &Chain,
diff: u64,
txs: Vec<&Transaction>,
) -> Block
where
K: Keychain,
{
let mut b = prepare_block_nosum(kc, prev, diff, txs);
chain.set_txhashset_roots(&mut b).unwrap();
b
}
fn prepare_block_nosum<K>(kc: &K, prev: &BlockHeader, diff: u64, txs: Vec<&Transaction>) -> Block
where
K: Keychain,
{
let proof_size = global::proofsize();
2018-10-10 12:11:01 +03:00
let key_id = ExtKeychainPath::new(1, diff as u32, 0, 0, 0).to_identifier();
let fees = txs.iter().map(|tx| tx.fee()).sum();
Master merge 2.0.0 (#2927) * create 2.0.0 branch * fix humansize version * update grin.yml version * PoW HardFork (#2866) * allow version 2 blocks for next 6 months * add cuckarood.rs with working tests * switch cuckaroo to cuckarood at right heights * reorder to reduce conditions * remove _ prefix on used args; fix typo * Make Valid Header Version dependant on ChainType * Rustfmt * Add tests, uncomment header v2 * Rustfmt * Add FLOONET_FIRST_HARD_FORK height and simplify logic * assume floonet stays closer to avg 60s block time * move floonet hf forward by half a day * update version in new block when previous no longer valid * my next commit:-) * micro optimization * Support new Bulletproof rewind scheme (#2848) * Update keychain with new rewind scheme * Refactor: proof builder trait * Update tests, cleanup * rustfmt * Move conversion of SwitchCommitmentType * Add proof build trait to tx builders * Cache hashes in proof builders * Proof builder tests * Add ViewKey struct * Fix some warnings * Zeroize proof builder secrets on drop * Modify mine_block to use wallet V2 API (#2892) * update mine_block to use V2 wallet API * rustfmt * Add version endpoint to node API, rename pool/push (#2897) * add node version API, tweak pool/push parameter * rustfmt * Upate version api call (#2899) * Update version number for next (potential) release * zeroize: Upgrade to v0.9 (#2914) * zeroize: Upgrade to v0.9 * missed Cargo.lock * [PENDING APPROVAL] put phase outs of C32 and beyond on hold (#2714) * put phase outs of C32 and beyond on hold * update tests for phaseouts on hold * Don't wait for p2p-server thread (#2917) Currently p2p.stop() stops and wait for all peers to exit, that's basically all we need. However we also run a TCP listener in this thread which is blocked on `accept` most of the time. We do an attempt to stop it but it would work only if we get an incoming connection during the shutdown, which is a week guarantee. This fix remove joining to p2p-server thread, it stops all peers and makes an attempt to stop the listener. Fixes [#2906] * rustfmt
2019-06-27 11:19:17 +03:00
let reward =
libtx::reward::output(kc, &libtx::ProofBuilder::new(kc), &key_id, fees, false).unwrap();
Minimal Transaction Pool (#1067) * verify a tx like we verify a block (experimental) * first minimal_pool test up and running but not testing what we need to * rework tx_pool validation to use txhashset extension * minimal tx pool wired up but rough * works locally (rough statew though) delete "legacy" pool and graph code * rework the new pool into TransactionPool and Pool impls * rework pool to store pool entries with associated timer and source etc. * all_transactions * extra_txs so we can validate stempool against existing txpool * rework reconcile_block * txhashset apply_raw_tx can now rewind to a checkpoint (prev raw tx) * wip - txhashset tx tests * more flexible rewind on MMRs * add tests to cover apply_raw_txs on txhashset extension * add_to_stempool and add_to_txpool * deaggregate multi kernel tx when adding to txpoool * handle freshness in stempool handle propagation of stempool txs via dandelion monitor * patience timer and fluff if we cannot propagate to next relay * aggregate and fluff stempool is we have no relay * refactor coinbase maturity * rewrote basic tx pool tests to use a real txhashset via chain adapter * rework dandelion monitor to reflect recent discussion works locally but needs a cleanup * refactor dandelion_monitor - split out phases * more pool test coverage * remove old test code from pool (still wip) * block_building and block_reconciliation tests * tracked down chain test failure... * fix test_coinbase_maturity * dandelion_monitor now runs... * refactor dandelion config, shared across p2p and pool components * fix pool tests with new config * fix p2p tests * rework tx pool to deal with duplicate commitments (testnet2 limitation) * cleanup and address some PR feedback * add big comment about pre_tx...
2018-05-30 23:57:13 +03:00
let mut b = match core::core::Block::new(
prev,
txs.into_iter().cloned().collect(),
Difficulty::from_num(diff),
reward,
) {
2018-03-04 03:19:54 +03:00
Err(e) => panic!("{:?}", e),
Ok(b) => b,
};
b.header.timestamp = prev.timestamp + Duration::seconds(60);
b.header.pow.total_difficulty = prev.total_difficulty() + Difficulty::from_num(diff);
b.header.pow.proof = pow::Proof::random(proof_size);
b
}
#[test]
#[ignore]
fn actual_diff_iter_output() {
global::set_mining_mode(ChainTypes::AutomatedTesting);
let genesis_block = pow::mine_genesis_block().unwrap();
let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new()));
let chain = chain::Chain::init(
"../.grin".to_string(),
Arc::new(NoopAdapter {}),
genesis_block,
pow::verify_size,
verifier_cache,
false,
)
.unwrap();
[1.1.0] Merge master into 1.1.0 (#2720) * cleanup legacy "3 dot" check (#2625) * Allow to peers behind NAT to get up to preferred_max connections (#2543) Allow to peers behind NAT to get up to preffered_max connections If peer has only outbound connections it's mot likely behind NAT and we should not stop it from getting more outbound connections * Reduce usage of unwrap in p2p crate (#2627) Also change store crate a bit * Simplify (and fix) output_pos cleanup during chain compaction (#2609) * expose leaf pos iterator use it for various things in txhashset when iterating over outputs * fix * cleanup * rebuild output_pos index (and clear it out first) when compacting the chain * fixup tests * refactor to match on (output, proof) tuple * add comments to compact() to explain what is going on. * get rid of some boxing around the leaf_set iterator * cleanup * [docs] Add switch commitment documentation (#2526) * remove references to no-longer existing switch commitment hash (as switch commitments were removed in ca8447f3bd49e80578770da841e5fbbac2c23cde and moved into the blinding factor of the Pedersen Commitment) * some rewording (points vs curves) and fix of small formatting issues * Add switch commitment documentation * [docs] Documents in grin repo had translated in Korean. (#2604) * Start to M/W intro translate in Korean * translate in Korean * add korean translation on intro * table_of_content.md translate in Korean. * table_of_content_KR.md finish translate in Korean, start to translate State_KR.md * add state_KR.md & commit some translation in State_KR.md * WIP stat_KR.md translation * add build_KR.md && stratum_KR.md * finish translate stratum_KR.md & table_of_content_KR.md * rename intro.KR.md to intro_KR.md * add intro_KR.md file path each language's intro.md * add Korean translation file path to stratum.md & table_of_contents.md * fix difference with grin/master * Fix TxHashSet file filter for Windows. (#2641) * Fix TxHashSet file filter for Windows. * rustfmt * Updating regexp * Adding in test case * Display the current download rate rather than the average when syncing the chain (#2633) * When syncing the chain, calculate the displayed download speed using the current rate from the most recent iteration, rather than the average download speed from the entire syncing process. * Replace the explicitly ignored variables in the pattern with an implicit ignore * remove root = true from editorconfig (#2655) * Add Medium post to intro (#2654) Spoke to @yeastplume who agreed it makes sense to add the "Grin Transactions Explained, Step-by-Step" Medium post to intro.md Open for suggestions on a better location. * add a new configure item for log_max_files (#2601) * add a new configure item for log_max_files * rustfmt * use a constant instead of multiple 32 * rustfmt * Fix the build warning of deprecated trim_right_matches (#2662) * [DOC] state.md, build.md and chain directory documents translate in Korean. (#2649) * add md files for translation. * start to translation fast-sync, code_structure. add file build_KR.md, states_KR.md * add dandelion_KR.md && simulation_KR.md for Korean translation. * add md files for translation. * start to translation fast-sync, code_structure. add file build_KR.md, states_KR.md * add dandelion_KR.md && simulation_KR.md for Korean translation. * remove some useless md files for translation. this is rearrange set up translation order. * add dot end of sentence & translate build.md in korean * remove fast-sync_KR.md * finish build_KR.md translation * finish build_KR.md translation * finish translation state_KR.md & add phrase in state.md to move other language md file * translate blocks_and_headers.md && chain_sync.md in Korean * add . in chain_sync.md , translation finished in doc/chain dir. * fix some miss typos * Api documentation fixes (#2646) * Fix the API documentation for Chain Validate (v1/chain/validate). It was documented as a POST, but it is actually a GET request, which can be seen in its handler ChainValidationHandler * Update the API V1 route list response to include the headers and merkleproof routes. Also clarify that for the chain/outputs route you must specify either byids or byheight to select outputs. * refactor(ci): reorganize CI related code (#2658) Break-down the CI related code into smaller more maintainable pieces. * Specify grin or nanogrins in API docs where applicable (#2642) * Set Content-Type in API client (#2680) * Reduce number of unwraps in chain crate (#2679) * fix: the restart of state sync doesn't work sometimes (#2687) * let check_txhashset_needed return true on abnormal case (#2684) * Reduce number of unwwaps in api crate (#2681) * Reduce number of unwwaps in api crate * Format use section * Small QoL improvements for wallet developers (#2651) * Small changes for wallet devs * Move create_nonce into Keychain trait * Replace match by map_err * Add flag to Slate to skip fee check * Fix secp dependency * Remove check_fee flag in Slate * Add Japanese edition of build.md (#2697) * catch the panic to avoid peer thread quit early (#2686) * catch the panic to avoid peer thread quit before taking the chance to ban * move catch wrapper logic down into the util crate * log the panic info * keep txhashset.rs untouched * remove a warning * [DOC] dandelion.md, simulation.md ,fast-sync.md and pruning.md documents translate in Korean. (#2678) * Show response code in API client error message (#2683) It's hard to investigate what happens when an API client error is printed out * Add some better logging for get_outputs_by_id failure states (#2705) * Switch commitment doc fixes (#2645) Fix some typos and remove the use of parentheses in a couple of places to make the reading flow a bit better. * docs: update/add new README.md badges (#2708) Replace existing badges with SVG counterparts and add a bunch of new ones. * Update intro.md (#2702) Add mention of censoring attack prevented by range proofs * use sandbox folder for txhashset validation on state sync (#2685) * use sandbox folder for txhashset validation on state sync * rustfmt * use temp directory as the sandbox instead actual db_root txhashset dir * rustfmt * move txhashset overwrite to the end of full validation * fix travis-ci test * rustfmt * fix: hashset have 2 folders including txhashset and header * rustfmt * (1)switch to rebuild_header_mmr instead of copy the sandbox header mmr (2)lock txhashset when overwriting and opening and rebuild * minor improve on sandbox_dir * add Japanese edition of state.md (#2703) * Attempt to fix broken TUI locale (#2713) Can confirm that on the same machine 1.0.2 TUI looks great and is broken on the current master. Bump of `cursive` version fixed it for me. Fixes #2676 * clean the header folder in sandbox (#2716) * forgot to clean the header folder in sandbox in #2685 * Reduce number of unwraps in servers crate (#2707) It doesn't include stratum server which is sufficiently changed in 1.1 branch and adapters, which is big enough for a separate PR. * rustfmt * change version to beta
2019-04-01 13:47:48 +03:00
let iter = chain.difficulty_iter().unwrap();
let mut last_time = 0;
let mut first = true;
for elem in iter.into_iter() {
if first {
last_time = elem.timestamp;
first = false;
}
println!(
"next_difficulty time: {}, diff: {}, duration: {} ",
elem.timestamp,
elem.difficulty.to_num(),
last_time - elem.timestamp
);
last_time = elem.timestamp;
}
}