diff --git a/chain/src/chain.rs b/chain/src/chain.rs index af903db2c6..ca5311595b 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -685,27 +685,6 @@ impl Chain { )) } - /// To support the ability to download the txhashset from multiple peers in parallel, - /// the peers must all agree on the exact binary representation of the txhashset. - /// This means compacting and rewinding to the exact same header. - /// Since compaction is a heavy operation, peers can agree to compact every 12 hours, - /// and no longer support requesting arbitrary txhashsets. - /// Here we return the header of the txhashset we are currently offering to peers. - pub fn txhashset_archive_header(&self) -> Result { - let sync_threshold = global::state_sync_threshold() as u64; - let body_head = self.head()?; - let archive_interval = global::txhashset_archive_interval(); - let mut txhashset_height = body_head.height.saturating_sub(sync_threshold); - txhashset_height = txhashset_height.saturating_sub(txhashset_height % archive_interval); - - debug!( - "txhashset_archive_header: body_head - {}, {}, txhashset height - {}", - body_head.last_block_h, body_head.height, txhashset_height, - ); - - self.get_header_by_height(txhashset_height) - } - // Special handling to make sure the whole kernel set matches each of its // roots in each block header, without truncation. We go back header by // header, rewind and check each root. This fixes a potential weakness in diff --git a/chain/src/txhashset/txhashset.rs b/chain/src/txhashset/txhashset.rs index f6cf46340c..23870f6c10 100644 --- a/chain/src/txhashset/txhashset.rs +++ b/chain/src/txhashset/txhashset.rs @@ -1432,10 +1432,10 @@ pub fn zip_read(root_dir: String, header: &BlockHeader) -> Result { } else { // clean up old zips. // Theoretically, we only need clean-up those zip files older than STATE_SYNC_THRESHOLD. - // But practically, these zip files are not small ones, we just keep the zips in last 24 hours + // But practically, these zip files are not small ones, we just keep the zips in last one hour let data_dir = Path::new(&root_dir); let pattern = format!("{}_", TXHASHSET_ZIP); - if let Ok(n) = clean_files_by_prefix(data_dir.clone(), &pattern, 24 * 60 * 60) { + if let Ok(n) = clean_files_by_prefix(data_dir.clone(), &pattern, 60 * 60) { debug!( "{} zip files have been clean up in folder: {:?}", n, data_dir diff --git a/chain/tests/chain_test_helper.rs b/chain/tests/chain_test_helper.rs deleted file mode 100644 index 314c577e11..0000000000 --- a/chain/tests/chain_test_helper.rs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2018 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; -use self::chain::types::Options; -use self::chain::Chain; -use self::core::core::verifier_cache::LruVerifierCache; -use self::core::core::Block; -use self::core::genesis; -use self::core::global::ChainTypes; -use self::core::libtx::{self, reward}; -use self::core::pow::Difficulty; -use self::core::{consensus, global, pow}; -use self::keychain::{ExtKeychainPath, Keychain}; -use self::util::RwLock; -use chrono::Duration; -use grin_chain as chain; -use grin_core as core; -use grin_keychain as keychain; -use grin_util as util; -use std::fs; -use std::sync::Arc; - -pub fn clean_output_dir(dir_name: &str) { - let _ = fs::remove_dir_all(dir_name); -} - -pub fn setup(dir_name: &str, genesis: Block) -> Chain { - util::init_test_logger(); - clean_output_dir(dir_name); - let verifier_cache = Arc::new(RwLock::new(LruVerifierCache::new())); - Chain::init( - dir_name.to_string(), - Arc::new(NoopAdapter {}), - genesis, - pow::verify_size, - verifier_cache, - false, - ) - .unwrap() -} - -/// Mine a chain of specified length to assist with automated tests. -/// Must call clean_output_dir at the end of your test. -pub fn mine_chain(dir_name: &str, chain_length: u64) -> Chain { - global::set_mining_mode(ChainTypes::AutomatedTesting); - - // add coinbase data from the dev genesis block - let mut genesis = genesis::genesis_dev(); - let keychain = keychain::ExtKeychain::from_random_seed(false).unwrap(); - let key_id = keychain::ExtKeychain::derive_key_id(0, 1, 0, 0, 0); - let reward = reward::output(&keychain, &key_id, 0, false).unwrap(); - genesis = genesis.with_reward(reward.0, reward.1); - - let mut chain = setup(dir_name, pow::mine_genesis_block().unwrap()); - chain.set_txhashset_roots(&mut genesis).unwrap(); - genesis.header.output_mmr_size = 1; - genesis.header.kernel_mmr_size = 1; - - // get a valid PoW - pow::pow_size( - &mut genesis.header, - Difficulty::unit(), - global::proofsize(), - global::min_edge_bits(), - ) - .unwrap(); - - mine_some_on_top(&mut chain, chain_length, &keychain); - chain -} - -fn mine_some_on_top(chain: &mut Chain, chain_length: u64, keychain: &K) -where - K: Keychain, -{ - for n in 1..chain_length { - 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(); - let reward = libtx::reward::output(keychain, &pk, 0, false).unwrap(); - let mut b = - core::core::Block::new(&prev, vec![], next_header_info.clone().difficulty, reward) - .unwrap(); - b.header.timestamp = prev.timestamp + Duration::seconds(160); - 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, Options::MINE).unwrap(); - } -} diff --git a/chain/tests/test_txhashset_archive.rs b/chain/tests/test_txhashset_archive.rs deleted file mode 100644 index 9a6708c2f8..0000000000 --- a/chain/tests/test_txhashset_archive.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2018 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. - -mod chain_test_helper; - -use self::chain_test_helper::{clean_output_dir, mine_chain}; - -#[test] -fn test() { - let chain = mine_chain(".txhashset_archive_test", 35); - let header = chain.txhashset_archive_header().unwrap(); - assert_eq!(10, header.height); - clean_output_dir(".txhashset_archive_test"); -} diff --git a/core/src/global.rs b/core/src/global.rs index eda529a8ac..b85adca68c 100644 --- a/core/src/global.rs +++ b/core/src/global.rs @@ -51,10 +51,7 @@ pub const AUTOMATED_TESTING_COINBASE_MATURITY: u64 = 3; pub const USER_TESTING_COINBASE_MATURITY: u64 = 3; /// Testing cut through horizon in blocks -pub const AUTOMATED_TESTING_CUT_THROUGH_HORIZON: u32 = 20; - -/// Testing cut through horizon in blocks -pub const USER_TESTING_CUT_THROUGH_HORIZON: u32 = 70; +pub const TESTING_CUT_THROUGH_HORIZON: u32 = 70; /// Testing state sync threshold in blocks pub const TESTING_STATE_SYNC_THRESHOLD: u32 = 20; @@ -85,12 +82,6 @@ pub const PEER_EXPIRATION_REMOVE_TIME: i64 = PEER_EXPIRATION_DAYS * 24 * 3600; /// For a node configured as "archival_mode = true" only the txhashset will be compacted. pub const COMPACTION_CHECK: u64 = DAY_HEIGHT; -/// Automated testing number of blocks to reuse a txhashset zip for. -pub const AUTOMATED_TESTING_TXHASHSET_ARCHIVE_INTERVAL: u64 = 10; - -/// Number of blocks to reuse a txhashset zip for. -pub const TXHASHSET_ARCHIVE_INTERVAL: u64 = 12 * 60; - /// Types of chain a server can run with, dictates the genesis block and /// and mining parameters used. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -254,8 +245,8 @@ pub fn max_block_weight() -> usize { pub fn cut_through_horizon() -> u32 { let param_ref = CHAIN_TYPE.read(); match *param_ref { - ChainTypes::AutomatedTesting => AUTOMATED_TESTING_CUT_THROUGH_HORIZON, - ChainTypes::UserTesting => USER_TESTING_CUT_THROUGH_HORIZON, + ChainTypes::AutomatedTesting => TESTING_CUT_THROUGH_HORIZON, + ChainTypes::UserTesting => TESTING_CUT_THROUGH_HORIZON, _ => CUT_THROUGH_HORIZON, } } @@ -270,15 +261,6 @@ pub fn state_sync_threshold() -> u32 { } } -/// Number of blocks to reuse a txhashset zip for. -pub fn txhashset_archive_interval() -> u64 { - let param_ref = CHAIN_TYPE.read(); - match *param_ref { - ChainTypes::AutomatedTesting => AUTOMATED_TESTING_TXHASHSET_ARCHIVE_INTERVAL, - _ => TXHASHSET_ARCHIVE_INTERVAL, - } -} - /// Are we in automated testing mode? pub fn is_automated_testing_mode() -> bool { let param_ref = CHAIN_TYPE.read(); diff --git a/core/src/pow.rs b/core/src/pow.rs index 671aed5aff..311ba23e6f 100644 --- a/core/src/pow.rs +++ b/core/src/pow.rs @@ -71,6 +71,7 @@ pub fn verify_size(bh: &BlockHeader) -> Result<(), Error> { pub fn mine_genesis_block() -> Result { let mut gen = genesis::genesis_dev(); if global::is_user_testing_mode() || global::is_automated_testing_mode() { + gen = genesis::genesis_dev(); gen.header.timestamp = Utc::now(); } diff --git a/p2p/src/peer.rs b/p2p/src/peer.rs index 5095c85642..f1d5fc85ca 100644 --- a/p2p/src/peer.rs +++ b/p2p/src/peer.rs @@ -562,10 +562,6 @@ impl ChainAdapter for TrackingAdapter { self.adapter.txhashset_read(h) } - fn txhashset_archive_header(&self) -> Result { - self.adapter.txhashset_archive_header() - } - fn txhashset_receive_ready(&self) -> bool { self.adapter.txhashset_receive_ready() } diff --git a/p2p/src/peers.rs b/p2p/src/peers.rs index a2fc7c51b6..a8668aade8 100644 --- a/p2p/src/peers.rs +++ b/p2p/src/peers.rs @@ -674,10 +674,6 @@ impl ChainAdapter for Peers { self.adapter.txhashset_read(h) } - fn txhashset_archive_header(&self) -> Result { - self.adapter.txhashset_archive_header() - } - fn txhashset_receive_ready(&self) -> bool { self.adapter.txhashset_receive_ready() } diff --git a/p2p/src/protocol.rs b/p2p/src/protocol.rs index edc9052777..61e6dc78b3 100644 --- a/p2p/src/protocol.rs +++ b/p2p/src/protocol.rs @@ -293,22 +293,20 @@ impl MessageHandler for Protocol { Type::TxHashSetRequest => { let sm_req: TxHashSetRequest = msg.body()?; - - let txhashset_header = self.adapter.txhashset_archive_header()?; - let txhashset_header_hash = txhashset_header.hash(); debug!( - "handle_payload: txhashset request for {} at {}, response with {} at {}", - sm_req.hash, sm_req.height, txhashset_header.height, txhashset_header_hash, + "handle_payload: txhashset req for {} at {}", + sm_req.hash, sm_req.height ); - let txhashset = self.adapter.txhashset_read(txhashset_header_hash); + + let txhashset = self.adapter.txhashset_read(sm_req.hash); if let Some(txhashset) = txhashset { let file_sz = txhashset.reader.metadata()?.len(); let mut resp = Response::new( Type::TxHashSetArchive, &TxHashSetArchive { - height: txhashset_header.height as u64, - hash: txhashset_header_hash, + height: sm_req.height as u64, + hash: sm_req.hash, bytes: file_sz, }, writer, diff --git a/p2p/src/serv.rs b/p2p/src/serv.rs index 7da4eebbaf..471ea94abb 100644 --- a/p2p/src/serv.rs +++ b/p2p/src/serv.rs @@ -302,10 +302,6 @@ impl ChainAdapter for DummyAdapter { unimplemented!() } - fn txhashset_archive_header(&self) -> Result { - unimplemented!() - } - fn txhashset_receive_ready(&self) -> bool { false } diff --git a/p2p/src/types.rs b/p2p/src/types.rs index 94531e42e2..1afa9a136c 100644 --- a/p2p/src/types.rs +++ b/p2p/src/types.rs @@ -536,9 +536,6 @@ pub trait ChainAdapter: Sync + Send { /// at the provided block hash. fn txhashset_read(&self, h: Hash) -> Option; - /// Header of the txhashset archive currently being served to peers. - fn txhashset_archive_header(&self) -> Result; - /// Whether the node is ready to accept a new txhashset. If this isn't the /// case, the archive is provided without being requested and likely an /// attack attempt. This should be checked *before* downloading the whole diff --git a/servers/src/common/adapters.rs b/servers/src/common/adapters.rs index 4228033446..91f20975a7 100644 --- a/servers/src/common/adapters.rs +++ b/servers/src/common/adapters.rs @@ -372,10 +372,6 @@ impl p2p::ChainAdapter for NetToChainAdapter { } } - fn txhashset_archive_header(&self) -> Result { - self.chain().txhashset_archive_header() - } - fn txhashset_receive_ready(&self) -> bool { match self.sync_state.status() { SyncStatus::TxHashsetDownload { .. } => true, diff --git a/servers/src/grin/sync/state_sync.rs b/servers/src/grin/sync/state_sync.rs index 0c06254baf..4a6d688efc 100644 --- a/servers/src/grin/sync/state_sync.rs +++ b/servers/src/grin/sync/state_sync.rs @@ -160,9 +160,6 @@ impl StateSync { fn request_state(&self, header_head: &chain::Tip) -> Result, p2p::Error> { let threshold = global::state_sync_threshold() as u64; - let archive_interval = global::txhashset_archive_interval(); - let mut txhashset_height = header_head.height.saturating_sub(threshold); - txhashset_height = txhashset_height.saturating_sub(txhashset_height % archive_interval); if let Some(peer) = self.peers.most_work_peer() { // ask for txhashset at state_sync_threshold @@ -176,7 +173,7 @@ impl StateSync { ); p2p::Error::Internal })?; - while txhashset_head.height > txhashset_height { + for _ in 0..threshold { txhashset_head = self .chain .get_previous_header(&txhashset_head)