[beta] Backports (#8916)
* `duration_ns: u64 -> duration: Duration` (#8457) * duration_ns: u64 -> duration: Duration * format on millis {:.2} -> {} * Keep all enacted blocks notify in order (#8524) * Keep all enacted blocks notify in order * Collect is unnecessary * Update ChainNotify to use ChainRouteType * Fix all ethcore fn defs * Wrap the type within ChainRoute * Fix private-tx and sync api * Fix secret_store API * Fix updater API * Fix rpc api * Fix informant api * Eagerly cache enacted/retracted and remove contain_enacted/retracted * Fix indent * tests: should use full expr form for struct constructor * Use into_enacted_retracted to further avoid copy * typo: not a function * rpc/tests: ChainRoute -> ChainRoute::new * Handle removed logs in filter changes and add geth compatibility field (#8796) * Add removed geth compatibility field in log * Fix mocked tests * Add field block hash in PollFilter * Store last block hash info for log filters * Implement canon route * Use canon logs for fetching reorg logs Light client removed logs fetching is disabled. It looks expensive. * Make sure removed flag is set * Address grumbles * Fixed AuthorityRound deadlock on shutdown, closes #8088 (#8803) * CI: Fix docker tags (#8822) * scripts: enable docker builds for beta and stable * scripts: docker latest should be beta not master * scripts: docker latest is master * ethcore: fix ancient block error msg handling (#8832) * Disable parallel verification and skip verifiying already imported txs. (#8834) * Reject transactions that are already in pool without verifying them. * Avoid verifying already imported transactions. * Fix concurrent access to signer queue (#8854) * Fix concurrent access to signer queue * Put request back to the queue if confirmation failed * typo: fix docs and rename functions to be more specific `request_notify` does not need to be public, and it's renamed to `notify_result`. `notify` is renamed to `notify_message`. * Change trace info "Transaction" -> "Request" * Don't allocate in expect_valid_rlp unless necessary (#8867) * don't allocate via format! in case there's no error * fix test? * fixed ipc leak, closes #8774 (#8876) * Add new ovh bootnodes and fix port for foundation bootnode 3.2 (#8886) * Add new ovh bootnodes and fix port for foundation bootnode 3.2 * Remove old bootnodes. * Remove duplicate 1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082 * Block 0 is valid in queries (#8891) Early exit for block nr 0 leads to spurious error about pruning: `…your node is running with state pruning…`. Fixes #7547, #8762 * Add ETC Cooperative-run load balanced parity node (#8892) * Minor fix in chain supplier and light provider (#8906) * fix chain supplier increment * fix light provider block_headers * Check whether we need resealing in miner and unwrap has_account in account_provider (#8853) * Remove unused Result wrap in has_account * Check whether we need to reseal for external transactions * Fix reference to has_account interface * typo: missing ) * Refactor duplicates to prepare_and_update_sealing * Fix build * Allow disabling local-by-default for transactions with new config entry (#8882) * Add tx_queue_allow_unknown_local config option - Previous commit messages: dispatcher checks if we have the sender account Add `tx_queue_allow_unknown_local` to MinerOptions Add `tx_queue_allow_unknown_local` to config fix order in MinerOptions to match Configuration add cli flag for tx_queue_allow_unknown_local Update refs to `tx_queue_allow_unknown_local` Add tx_queue_allow_unknown_local to config test revert changes to dispatcher Move tx_queue_allow_unknown_local to `import_own_transaction` Fix var name if statement should return the values derp de derp derp derp semicolons Reset dispatch file to how it was before fix compile issues + change from FLAG to ARG add test and use `into` import MinerOptions, clone the secret Fix tests? Compiler/linter issues fixed Fix linter msg - case of constants IT LIVES refactor to omit yucky explict return update comments Fix based on diff AccountProvider.has_account method * Refactor flag name + don't change import_own_tx behaviour fix arg name Note: force commit to try and get gitlab tests working again 😠 * Add fn to TestMinerService * Avoid race condition from trusted sources - refactor the miner tests a bit to cut down on code reuse - add `trusted` param to dispatch_transaction and import_claimed_local_transaction Add param to `import_claimed_local_transaction` Fix fn sig in tests
This commit is contained in:
committed by
Afri Schoedon
parent
f26a7fe6fa
commit
cc44ae9cb5
@@ -17,6 +17,9 @@
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::H256;
|
||||
use transaction::UnverifiedTransaction;
|
||||
use blockchain::ImportRoute;
|
||||
use std::time::Duration;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Messages to broadcast via chain
|
||||
pub enum ChainMessageType {
|
||||
@@ -28,6 +31,89 @@ pub enum ChainMessageType {
|
||||
SignedPrivateTransaction(Vec<u8>),
|
||||
}
|
||||
|
||||
/// Route type to indicate whether it is enacted or retracted.
|
||||
#[derive(Clone)]
|
||||
pub enum ChainRouteType {
|
||||
/// Enacted block
|
||||
Enacted,
|
||||
/// Retracted block
|
||||
Retracted
|
||||
}
|
||||
|
||||
/// A complete chain enacted retracted route.
|
||||
#[derive(Default, Clone)]
|
||||
pub struct ChainRoute {
|
||||
route: Vec<(H256, ChainRouteType)>,
|
||||
enacted: Vec<H256>,
|
||||
retracted: Vec<H256>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [ImportRoute]> for ChainRoute {
|
||||
fn from(import_results: &'a [ImportRoute]) -> ChainRoute {
|
||||
ChainRoute::new(import_results.iter().flat_map(|route| {
|
||||
route.retracted.iter().map(|h| (*h, ChainRouteType::Retracted))
|
||||
.chain(route.enacted.iter().map(|h| (*h, ChainRouteType::Enacted)))
|
||||
}).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl ChainRoute {
|
||||
/// Create a new ChainRoute based on block hash and route type pairs.
|
||||
pub fn new(route: Vec<(H256, ChainRouteType)>) -> Self {
|
||||
let (enacted, retracted) = Self::to_enacted_retracted(&route);
|
||||
|
||||
Self { route, enacted, retracted }
|
||||
}
|
||||
|
||||
/// Gather all non-duplicate enacted and retracted blocks.
|
||||
fn to_enacted_retracted(route: &[(H256, ChainRouteType)]) -> (Vec<H256>, Vec<H256>) {
|
||||
fn map_to_vec(map: Vec<(H256, bool)>) -> Vec<H256> {
|
||||
map.into_iter().map(|(k, _v)| k).collect()
|
||||
}
|
||||
|
||||
// Because we are doing multiple inserts some of the blocks that were enacted in import `k`
|
||||
// could be retracted in import `k+1`. This is why to understand if after all inserts
|
||||
// the block is enacted or retracted we iterate over all routes and at the end final state
|
||||
// will be in the hashmap
|
||||
let map = route.iter().fold(HashMap::new(), |mut map, route| {
|
||||
match &route.1 {
|
||||
&ChainRouteType::Enacted => {
|
||||
map.insert(route.0, true);
|
||||
},
|
||||
&ChainRouteType::Retracted => {
|
||||
map.insert(route.0, false);
|
||||
},
|
||||
}
|
||||
map
|
||||
});
|
||||
|
||||
// Split to enacted retracted (using hashmap value)
|
||||
let (enacted, retracted) = map.into_iter().partition(|&(_k, v)| v);
|
||||
// And convert tuples to keys
|
||||
(map_to_vec(enacted), map_to_vec(retracted))
|
||||
}
|
||||
|
||||
/// Consume route and return the enacted retracted form.
|
||||
pub fn into_enacted_retracted(self) -> (Vec<H256>, Vec<H256>) {
|
||||
(self.enacted, self.retracted)
|
||||
}
|
||||
|
||||
/// All non-duplicate enacted blocks.
|
||||
pub fn enacted(&self) -> &[H256] {
|
||||
&self.enacted
|
||||
}
|
||||
|
||||
/// All non-duplicate retracted blocks.
|
||||
pub fn retracted(&self) -> &[H256] {
|
||||
&self.retracted
|
||||
}
|
||||
|
||||
/// All blocks in the route.
|
||||
pub fn route(&self) -> &[(H256, ChainRouteType)] {
|
||||
&self.route
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents what has to be handled by actor listening to chain events
|
||||
pub trait ChainNotify : Send + Sync {
|
||||
/// fires when chain has new blocks.
|
||||
@@ -35,12 +121,11 @@ pub trait ChainNotify : Send + Sync {
|
||||
&self,
|
||||
_imported: Vec<H256>,
|
||||
_invalid: Vec<H256>,
|
||||
_enacted: Vec<H256>,
|
||||
_retracted: Vec<H256>,
|
||||
_route: ChainRoute,
|
||||
_sealed: Vec<H256>,
|
||||
// Block bytes.
|
||||
_proposed: Vec<Bytes>,
|
||||
_duration: u64,
|
||||
_duration: Duration,
|
||||
) {
|
||||
// does nothing by default
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::{HashSet, HashMap, BTreeMap, BTreeSet, VecDeque};
|
||||
use std::collections::{HashSet, BTreeMap, BTreeSet, VecDeque};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::time::{Instant};
|
||||
use std::time::{Instant, Duration};
|
||||
|
||||
// util
|
||||
use hash::keccak;
|
||||
@@ -33,7 +33,7 @@ use util_error::UtilError;
|
||||
// other
|
||||
use ethereum_types::{H256, Address, U256};
|
||||
use block::{IsBlock, LockedBlock, Drain, ClosedBlock, OpenBlock, enact_verified, SealedBlock};
|
||||
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute, TransactionAddress};
|
||||
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute, TransactionAddress};
|
||||
use client::ancient_import::AncientVerifier;
|
||||
use client::Error as ClientError;
|
||||
use client::{
|
||||
@@ -46,8 +46,8 @@ use client::{
|
||||
use client::{
|
||||
BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient,
|
||||
TraceFilter, CallAnalytics, BlockImportError, Mode,
|
||||
ChainNotify, PruningInfo, ProvingBlockChainClient, EngineInfo, ChainMessageType,
|
||||
IoClient,
|
||||
ChainMessageType, ChainNotify, ChainRoute, PruningInfo, ProvingBlockChainClient,
|
||||
EngineInfo, IoClient,
|
||||
};
|
||||
use encoded;
|
||||
use engines::{EthEngine, EpochTransition};
|
||||
@@ -125,7 +125,7 @@ impl<'a> ::std::ops::Sub<&'a ClientReport> for ClientReport {
|
||||
self.blocks_imported -= other.blocks_imported;
|
||||
self.transactions_applied -= other.transactions_applied;
|
||||
self.gas_processed = self.gas_processed - other.gas_processed;
|
||||
self.state_db_mem = higher_mem - lower_mem;
|
||||
self.state_db_mem = higher_mem - lower_mem;
|
||||
|
||||
self
|
||||
}
|
||||
@@ -257,32 +257,6 @@ impl Importer {
|
||||
})
|
||||
}
|
||||
|
||||
fn calculate_enacted_retracted(&self, import_results: &[ImportRoute]) -> (Vec<H256>, Vec<H256>) {
|
||||
fn map_to_vec(map: Vec<(H256, bool)>) -> Vec<H256> {
|
||||
map.into_iter().map(|(k, _v)| k).collect()
|
||||
}
|
||||
|
||||
// In ImportRoute we get all the blocks that have been enacted and retracted by single insert.
|
||||
// Because we are doing multiple inserts some of the blocks that were enacted in import `k`
|
||||
// could be retracted in import `k+1`. This is why to understand if after all inserts
|
||||
// the block is enacted or retracted we iterate over all routes and at the end final state
|
||||
// will be in the hashmap
|
||||
let map = import_results.iter().fold(HashMap::new(), |mut map, route| {
|
||||
for hash in &route.enacted {
|
||||
map.insert(hash.clone(), true);
|
||||
}
|
||||
for hash in &route.retracted {
|
||||
map.insert(hash.clone(), false);
|
||||
}
|
||||
map
|
||||
});
|
||||
|
||||
// Split to enacted retracted (using hashmap value)
|
||||
let (enacted, retracted) = map.into_iter().partition(|&(_k, v)| v);
|
||||
// And convert tuples to keys
|
||||
(map_to_vec(enacted), map_to_vec(retracted))
|
||||
}
|
||||
|
||||
/// This is triggered by a message coming from a block queue when the block is ready for insertion
|
||||
pub fn import_verified_blocks(&self, client: &Client) -> usize {
|
||||
|
||||
@@ -343,27 +317,22 @@ impl Importer {
|
||||
self.block_queue.mark_as_bad(&invalid_blocks);
|
||||
}
|
||||
let is_empty = self.block_queue.mark_as_good(&imported_blocks);
|
||||
let duration_ns = {
|
||||
let elapsed = start.elapsed();
|
||||
elapsed.as_secs() * 1_000_000_000 + elapsed.subsec_nanos() as u64
|
||||
};
|
||||
(imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, duration_ns, is_empty)
|
||||
(imported_blocks, import_results, invalid_blocks, imported, proposed_blocks, start.elapsed(), is_empty)
|
||||
};
|
||||
|
||||
{
|
||||
if !imported_blocks.is_empty() && is_empty {
|
||||
let (enacted, retracted) = self.calculate_enacted_retracted(&import_results);
|
||||
let route = ChainRoute::from(import_results.as_ref());
|
||||
|
||||
if is_empty {
|
||||
self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, &enacted, &retracted, false);
|
||||
self.miner.chain_new_blocks(client, &imported_blocks, &invalid_blocks, route.enacted(), route.retracted(), false);
|
||||
}
|
||||
|
||||
client.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
imported_blocks.clone(),
|
||||
invalid_blocks.clone(),
|
||||
enacted.clone(),
|
||||
retracted.clone(),
|
||||
route.clone(),
|
||||
Vec::new(),
|
||||
proposed_blocks.clone(),
|
||||
duration,
|
||||
@@ -1030,7 +999,8 @@ impl Client {
|
||||
/// Otherwise, this can fail (but may not) if the DB prunes state.
|
||||
pub fn state_at_beginning(&self, id: BlockId) -> Option<State<StateDB>> {
|
||||
match self.block_number(id) {
|
||||
None | Some(0) => None,
|
||||
None => None,
|
||||
Some(0) => self.state_at(id),
|
||||
Some(n) => self.state_at(BlockId::Number(n - 1)),
|
||||
}
|
||||
}
|
||||
@@ -1446,7 +1416,7 @@ impl Call for Client {
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, t: &SignedTransaction, state: &Self::State, header: &Header) -> Result<U256, CallError> {
|
||||
let (mut upper, max_upper, env_info) = {
|
||||
let (mut upper, max_upper, env_info) = {
|
||||
let init = *header.gas_limit();
|
||||
let max = init * U256::from(10);
|
||||
|
||||
@@ -2041,15 +2011,16 @@ impl IoClient for Client {
|
||||
let first = queued.write().1.pop_front();
|
||||
if let Some((header, block_bytes, receipts_bytes)) = first {
|
||||
let hash = header.hash();
|
||||
client.importer.import_old_block(
|
||||
let result = client.importer.import_old_block(
|
||||
&header,
|
||||
&block_bytes,
|
||||
&receipts_bytes,
|
||||
&**client.db.read(),
|
||||
&*client.chain.read()
|
||||
).ok().map_or((), |e| {
|
||||
&*client.chain.read(),
|
||||
);
|
||||
if let Err(e) = result {
|
||||
error!(target: "client", "Error importing ancient block: {}", e);
|
||||
});
|
||||
}
|
||||
// remove from pending
|
||||
queued.write().0.remove(&hash);
|
||||
} else {
|
||||
@@ -2171,20 +2142,16 @@ impl ImportSealedBlock for Client {
|
||||
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
|
||||
route
|
||||
};
|
||||
let (enacted, retracted) = self.importer.calculate_enacted_retracted(&[route]);
|
||||
self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], &enacted, &retracted, self.engine.seals_internally().is_some());
|
||||
let route = ChainRoute::from([route].as_ref());
|
||||
self.importer.miner.chain_new_blocks(self, &[h.clone()], &[], route.enacted(), route.retracted(), true);
|
||||
self.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
vec![h.clone()],
|
||||
vec![],
|
||||
enacted.clone(),
|
||||
retracted.clone(),
|
||||
route.clone(),
|
||||
vec![h.clone()],
|
||||
vec![],
|
||||
{
|
||||
let elapsed = start.elapsed();
|
||||
elapsed.as_secs() * 1_000_000_000 + elapsed.subsec_nanos() as u64
|
||||
},
|
||||
start.elapsed(),
|
||||
);
|
||||
});
|
||||
self.db.read().flush().expect("DB flush failed.");
|
||||
@@ -2194,15 +2161,15 @@ impl ImportSealedBlock for Client {
|
||||
|
||||
impl BroadcastProposalBlock for Client {
|
||||
fn broadcast_proposal_block(&self, block: SealedBlock) {
|
||||
const DURATION_ZERO: Duration = Duration::from_millis(0);
|
||||
self.notify(|notify| {
|
||||
notify.new_blocks(
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
ChainRoute::default(),
|
||||
vec![],
|
||||
vec![block.rlp_bytes()],
|
||||
0,
|
||||
DURATION_ZERO,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ pub use self::error::Error;
|
||||
pub use self::evm_test_client::{EvmTestClient, EvmTestError, TransactResult};
|
||||
pub use self::io_message::ClientIoMessage;
|
||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||
pub use self::chain_notify::{ChainNotify, ChainMessageType};
|
||||
pub use self::chain_notify::{ChainNotify, ChainRoute, ChainRouteType, ChainMessageType};
|
||||
pub use self::traits::{
|
||||
Nonce, Balance, ChainInfo, BlockInfo, ReopenBlock, PrepareOpenBlock, CallContract, TransactionInfo, RegistryInfo, ScheduleInfo, ImportSealedBlock, BroadcastProposalBlock, ImportBlock,
|
||||
StateOrBlock, StateClient, Call, EngineInfo, AccountData, BlockChain, BlockProducer, SealedBlockImporter
|
||||
|
||||
Reference in New Issue
Block a user