Implement eth/64, remove eth/62 (#46)
Co-authored-by: Artem Vorotnikov <artem@vorotnikov.me>
This commit is contained in:
parent
b54ddd027d
commit
1c82a0733f
4487
Cargo.lock
generated
4487
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,7 @@ len-caching-lock = { path = "../util/len-caching-lock" }
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
lru-cache = "0.1"
|
lru-cache = "0.1"
|
||||||
macros = { path = "../util/macros" }
|
macros = { path = "../util/macros" }
|
||||||
|
maplit = "1"
|
||||||
memory-cache = { path = "../util/memory-cache" }
|
memory-cache = { path = "../util/memory-cache" }
|
||||||
memory-db = { path = "../util/memory-db" }
|
memory-db = { path = "../util/memory-db" }
|
||||||
num_cpus = "1.2"
|
num_cpus = "1.2"
|
||||||
|
@ -83,6 +83,7 @@ extern crate keccak_hasher;
|
|||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
extern crate len_caching_lock;
|
extern crate len_caching_lock;
|
||||||
extern crate lru_cache;
|
extern crate lru_cache;
|
||||||
|
extern crate maplit;
|
||||||
extern crate memory_cache;
|
extern crate memory_cache;
|
||||||
extern crate memory_db;
|
extern crate memory_db;
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
|
@ -16,7 +16,13 @@
|
|||||||
|
|
||||||
//! Parameters for a block chain.
|
//! Parameters for a block chain.
|
||||||
|
|
||||||
use std::{collections::BTreeMap, convert::TryFrom, io::Read, path::Path, sync::Arc};
|
use std::{
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
convert::TryFrom,
|
||||||
|
io::Read,
|
||||||
|
path::Path,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use ethereum_types::{Address, Bloom, H256, U256};
|
use ethereum_types::{Address, Bloom, H256, U256};
|
||||||
@ -37,6 +43,7 @@ use error::Error;
|
|||||||
use executive::Executive;
|
use executive::Executive;
|
||||||
use factory::Factories;
|
use factory::Factories;
|
||||||
use machine::EthereumMachine;
|
use machine::EthereumMachine;
|
||||||
|
use maplit::btreeset;
|
||||||
use pod_state::PodState;
|
use pod_state::PodState;
|
||||||
use spec::{seal::Generic as GenericSeal, Genesis};
|
use spec::{seal::Generic as GenericSeal, Genesis};
|
||||||
use state::{backend::Basic as BasicBackend, Backend, State, Substate};
|
use state::{backend::Basic as BasicBackend, Backend, State, Substate};
|
||||||
@ -436,6 +443,9 @@ pub struct Spec {
|
|||||||
/// Each seal field, expressed as RLP, concatenated.
|
/// Each seal field, expressed as RLP, concatenated.
|
||||||
pub seal_rlp: Bytes,
|
pub seal_rlp: Bytes,
|
||||||
|
|
||||||
|
/// List of hard forks in the network.
|
||||||
|
pub hard_forks: BTreeSet<BlockNumber>,
|
||||||
|
|
||||||
/// Contract constructors to be executed on genesis.
|
/// Contract constructors to be executed on genesis.
|
||||||
constructors: Vec<(Address, Bytes)>,
|
constructors: Vec<(Address, Bytes)>,
|
||||||
|
|
||||||
@ -464,6 +474,7 @@ impl Clone for Spec {
|
|||||||
timestamp: self.timestamp.clone(),
|
timestamp: self.timestamp.clone(),
|
||||||
extra_data: self.extra_data.clone(),
|
extra_data: self.extra_data.clone(),
|
||||||
seal_rlp: self.seal_rlp.clone(),
|
seal_rlp: self.seal_rlp.clone(),
|
||||||
|
hard_forks: self.hard_forks.clone(),
|
||||||
constructors: self.constructors.clone(),
|
constructors: self.constructors.clone(),
|
||||||
state_root_memo: RwLock::new(*self.state_root_memo.read()),
|
state_root_memo: RwLock::new(*self.state_root_memo.read()),
|
||||||
genesis_state: self.genesis_state.clone(),
|
genesis_state: self.genesis_state.clone(),
|
||||||
@ -508,9 +519,11 @@ fn load_from(spec_params: SpecParams, s: ethjson::spec::Spec) -> Result<Spec, Er
|
|||||||
let GenericSeal(seal_rlp) = g.seal.into();
|
let GenericSeal(seal_rlp) = g.seal.into();
|
||||||
let params = CommonParams::from(s.params);
|
let params = CommonParams::from(s.params);
|
||||||
|
|
||||||
|
let (engine, hard_forks) = Spec::engine(spec_params, s.engine, params, builtins);
|
||||||
|
|
||||||
let mut s = Spec {
|
let mut s = Spec {
|
||||||
name: s.name.clone().into(),
|
name: s.name.clone().into(),
|
||||||
engine: Spec::engine(spec_params, s.engine, params, builtins),
|
engine,
|
||||||
data_dir: s.data_dir.unwrap_or(s.name).into(),
|
data_dir: s.data_dir.unwrap_or(s.name).into(),
|
||||||
nodes: s.nodes.unwrap_or_else(Vec::new),
|
nodes: s.nodes.unwrap_or_else(Vec::new),
|
||||||
parent_hash: g.parent_hash,
|
parent_hash: g.parent_hash,
|
||||||
@ -523,6 +536,7 @@ fn load_from(spec_params: SpecParams, s: ethjson::spec::Spec) -> Result<Spec, Er
|
|||||||
timestamp: g.timestamp,
|
timestamp: g.timestamp,
|
||||||
extra_data: g.extra_data,
|
extra_data: g.extra_data,
|
||||||
seal_rlp: seal_rlp,
|
seal_rlp: seal_rlp,
|
||||||
|
hard_forks,
|
||||||
constructors: s
|
constructors: s
|
||||||
.accounts
|
.accounts
|
||||||
.constructors()
|
.constructors()
|
||||||
@ -586,19 +600,75 @@ impl Spec {
|
|||||||
engine_spec: ethjson::spec::Engine,
|
engine_spec: ethjson::spec::Engine,
|
||||||
params: CommonParams,
|
params: CommonParams,
|
||||||
builtins: BTreeMap<Address, Builtin>,
|
builtins: BTreeMap<Address, Builtin>,
|
||||||
) -> Arc<dyn EthEngine> {
|
) -> (Arc<dyn EthEngine>, BTreeSet<BlockNumber>) {
|
||||||
|
let mut hard_forks = btreeset![
|
||||||
|
params.eip150_transition,
|
||||||
|
params.eip160_transition,
|
||||||
|
params.eip161abc_transition,
|
||||||
|
params.eip161d_transition,
|
||||||
|
params.eip98_transition,
|
||||||
|
params.eip658_transition,
|
||||||
|
params.eip155_transition,
|
||||||
|
params.validate_receipts_transition,
|
||||||
|
params.validate_chain_id_transition,
|
||||||
|
params.eip140_transition,
|
||||||
|
params.eip210_transition,
|
||||||
|
params.eip211_transition,
|
||||||
|
params.eip214_transition,
|
||||||
|
params.eip145_transition,
|
||||||
|
params.eip1052_transition,
|
||||||
|
params.eip1283_transition,
|
||||||
|
params.eip1283_disable_transition,
|
||||||
|
params.eip1283_reenable_transition,
|
||||||
|
params.eip1014_transition,
|
||||||
|
params.eip1706_transition,
|
||||||
|
params.eip1344_transition,
|
||||||
|
params.eip1884_transition,
|
||||||
|
params.eip2028_transition,
|
||||||
|
params.eip2315_transition,
|
||||||
|
params.dust_protection_transition,
|
||||||
|
params.wasm_activation_transition,
|
||||||
|
params.kip4_transition,
|
||||||
|
params.kip6_transition,
|
||||||
|
params.max_code_size_transition,
|
||||||
|
params.transaction_permission_contract_transition,
|
||||||
|
];
|
||||||
|
// BUG: Rinkeby has homestead transition at block 1 but we can't reflect that in specs for non-Ethash networks
|
||||||
|
if params.network_id == 0x4 {
|
||||||
|
hard_forks.insert(1);
|
||||||
|
}
|
||||||
|
|
||||||
let machine = Self::machine(&engine_spec, params, builtins);
|
let machine = Self::machine(&engine_spec, params, builtins);
|
||||||
|
|
||||||
match engine_spec {
|
let engine: Arc<dyn EthEngine> = match engine_spec {
|
||||||
ethjson::spec::Engine::Null(null) => {
|
ethjson::spec::Engine::Null(null) => {
|
||||||
Arc::new(NullEngine::new(null.params.into(), machine))
|
Arc::new(NullEngine::new(null.params.into(), machine))
|
||||||
}
|
}
|
||||||
ethjson::spec::Engine::Ethash(ethash) => Arc::new(::ethereum::Ethash::new(
|
ethjson::spec::Engine::Ethash(ethash) => {
|
||||||
spec_params.cache_dir,
|
// Specific transitions for Ethash-based networks
|
||||||
ethash.params.into(),
|
for block in &[
|
||||||
machine,
|
ethash.params.homestead_transition,
|
||||||
spec_params.optimization_setting,
|
ethash.params.dao_hardfork_transition,
|
||||||
)),
|
] {
|
||||||
|
if let Some(block) = *block {
|
||||||
|
hard_forks.insert(block.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ethereum's difficulty bomb delay is a fork too
|
||||||
|
if let Some(delays) = ðash.params.difficulty_bomb_delays {
|
||||||
|
for delay in delays.keys().copied() {
|
||||||
|
hard_forks.insert(delay.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Arc::new(::ethereum::Ethash::new(
|
||||||
|
spec_params.cache_dir,
|
||||||
|
ethash.params.into(),
|
||||||
|
machine,
|
||||||
|
spec_params.optimization_setting,
|
||||||
|
))
|
||||||
|
}
|
||||||
ethjson::spec::Engine::InstantSeal(Some(instant_seal)) => {
|
ethjson::spec::Engine::InstantSeal(Some(instant_seal)) => {
|
||||||
Arc::new(InstantSeal::new(instant_seal.params.into(), machine))
|
Arc::new(InstantSeal::new(instant_seal.params.into(), machine))
|
||||||
}
|
}
|
||||||
@ -614,7 +684,12 @@ impl Spec {
|
|||||||
AuthorityRound::new(authority_round.params.into(), machine)
|
AuthorityRound::new(authority_round.params.into(), machine)
|
||||||
.expect("Failed to start AuthorityRound consensus engine.")
|
.expect("Failed to start AuthorityRound consensus engine.")
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// Dummy value is a filler for non-existent transitions
|
||||||
|
hard_forks.remove(&BlockNumber::max_value());
|
||||||
|
|
||||||
|
(engine, hard_forks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// given a pre-constructor state, run all the given constructors and produce a new state and
|
// given a pre-constructor state, run all the given constructors and produce a new state and
|
||||||
|
@ -15,6 +15,8 @@ ethcore = { path = ".." }
|
|||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
ethcore-network = { path = "../../util/network" }
|
ethcore-network = { path = "../../util/network" }
|
||||||
ethcore-network-devp2p = { path = "../../util/network-devp2p" }
|
ethcore-network-devp2p = { path = "../../util/network-devp2p" }
|
||||||
|
ethereum-forkid = "0.2"
|
||||||
|
primitive_types07 = { package = "primitive-types", version = "0.7"}
|
||||||
ethereum-types = "0.4"
|
ethereum-types = "0.4"
|
||||||
ethkey = { path = "../../accounts/ethkey" }
|
ethkey = { path = "../../accounts/ethkey" }
|
||||||
ethstore = { path = "../../accounts/ethstore" }
|
ethstore = { path = "../../accounts/ethstore" }
|
||||||
@ -30,6 +32,7 @@ parity-bytes = "0.1"
|
|||||||
parking_lot = "0.7"
|
parking_lot = "0.7"
|
||||||
rand = "0.4"
|
rand = "0.4"
|
||||||
rlp = { version = "0.3.0", features = ["ethereum"] }
|
rlp = { version = "0.3.0", features = ["ethereum"] }
|
||||||
|
rlp04 = { package = "rlp", version = "0.4" }
|
||||||
trace-time = "0.1"
|
trace-time = "0.1"
|
||||||
triehash-ethereum = {version = "0.2", path = "../../util/triehash-ethereum" }
|
triehash-ethereum = {version = "0.2", path = "../../util/triehash-ethereum" }
|
||||||
stats = { path = "../../util/stats" }
|
stats = { path = "../../util/stats" }
|
||||||
|
@ -22,7 +22,7 @@ use network::{
|
|||||||
NonReservedPeerMode, PeerId, ProtocolId,
|
NonReservedPeerMode, PeerId, ProtocolId,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, HashMap},
|
collections::{BTreeMap, BTreeSet, HashMap},
|
||||||
io,
|
io,
|
||||||
ops::RangeInclusive,
|
ops::RangeInclusive,
|
||||||
sync::{atomic, mpsc, Arc},
|
sync::{atomic, mpsc, Arc},
|
||||||
@ -30,8 +30,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use chain::{
|
use chain::{
|
||||||
ChainSyncApi, SyncState, SyncStatus as EthSyncStatus, ETH_PROTOCOL_VERSION_62,
|
fork_filter::ForkFilterApi, ChainSyncApi, SyncState, SyncStatus as EthSyncStatus,
|
||||||
ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2,
|
ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_64, PAR_PROTOCOL_VERSION_1,
|
||||||
|
PAR_PROTOCOL_VERSION_2,
|
||||||
};
|
};
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
client::{BlockChainClient, ChainMessageType, ChainNotify, NewBlocks},
|
client::{BlockChainClient, ChainMessageType, ChainNotify, NewBlocks},
|
||||||
@ -215,6 +216,8 @@ pub struct Params {
|
|||||||
pub config: SyncConfig,
|
pub config: SyncConfig,
|
||||||
/// Blockchain client.
|
/// Blockchain client.
|
||||||
pub chain: Arc<dyn BlockChainClient>,
|
pub chain: Arc<dyn BlockChainClient>,
|
||||||
|
/// Forks.
|
||||||
|
pub forks: BTreeSet<BlockNumber>,
|
||||||
/// Snapshot service.
|
/// Snapshot service.
|
||||||
pub snapshot_service: Arc<dyn SnapshotService>,
|
pub snapshot_service: Arc<dyn SnapshotService>,
|
||||||
/// Network layer configuration.
|
/// Network layer configuration.
|
||||||
@ -240,7 +243,14 @@ impl EthSync {
|
|||||||
connection_filter: Option<Arc<dyn ConnectionFilter>>,
|
connection_filter: Option<Arc<dyn ConnectionFilter>>,
|
||||||
) -> Result<Arc<EthSync>, Error> {
|
) -> Result<Arc<EthSync>, Error> {
|
||||||
let (priority_tasks_tx, priority_tasks_rx) = mpsc::channel();
|
let (priority_tasks_tx, priority_tasks_rx) = mpsc::channel();
|
||||||
let sync = ChainSyncApi::new(params.config, &*params.chain, priority_tasks_rx);
|
let fork_filter = ForkFilterApi::new(&*params.chain, params.forks);
|
||||||
|
|
||||||
|
let sync = ChainSyncApi::new(
|
||||||
|
params.config,
|
||||||
|
&*params.chain,
|
||||||
|
fork_filter,
|
||||||
|
priority_tasks_rx,
|
||||||
|
);
|
||||||
let service = NetworkService::new(
|
let service = NetworkService::new(
|
||||||
params.network_config.clone().into_basic()?,
|
params.network_config.clone().into_basic()?,
|
||||||
connection_filter,
|
connection_filter,
|
||||||
@ -559,7 +569,7 @@ impl ChainNotify for EthSync {
|
|||||||
.register_protocol(
|
.register_protocol(
|
||||||
self.eth_handler.clone(),
|
self.eth_handler.clone(),
|
||||||
self.subprotocol_name,
|
self.subprotocol_name,
|
||||||
&[ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63],
|
&[ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_64],
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|e| warn!("Error registering ethereum protocol: {:?}", e));
|
.unwrap_or_else(|e| warn!("Error registering ethereum protocol: {:?}", e));
|
||||||
// register the warp sync subprotocol
|
// register the warp sync subprotocol
|
||||||
|
@ -99,6 +99,12 @@ pub enum BlockDownloaderImportError {
|
|||||||
Useless,
|
Useless,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<rlp04::DecoderError> for BlockDownloaderImportError {
|
||||||
|
fn from(_: rlp04::DecoderError) -> BlockDownloaderImportError {
|
||||||
|
BlockDownloaderImportError::Invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<rlp::DecoderError> for BlockDownloaderImportError {
|
impl From<rlp::DecoderError> for BlockDownloaderImportError {
|
||||||
fn from(_: rlp::DecoderError) -> BlockDownloaderImportError {
|
fn from(_: rlp::DecoderError) -> BlockDownloaderImportError {
|
||||||
BlockDownloaderImportError::Invalid
|
BlockDownloaderImportError::Invalid
|
||||||
|
114
ethcore/sync/src/chain/fork_filter.rs
Normal file
114
ethcore/sync/src/chain/fork_filter.rs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
//! This module contains a wrapper that connects this codebase with `ethereum-forkid` crate which provides `FORK_ID`
|
||||||
|
//! to support Ethereum network protocol, version 64 and above.
|
||||||
|
|
||||||
|
// Re-export ethereum-forkid crate contents here.
|
||||||
|
pub use ethereum_forkid::{BlockNumber, ForkId, RejectReason};
|
||||||
|
|
||||||
|
use ethcore::client::ChainInfo;
|
||||||
|
use ethereum_forkid::ForkFilter;
|
||||||
|
|
||||||
|
/// Wrapper around fork filter that provides integration with `ForkFilter`.
|
||||||
|
pub struct ForkFilterApi {
|
||||||
|
inner: ForkFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ForkFilterApi {
|
||||||
|
/// Create `ForkFilterApi` from `ChainInfo` and an `Iterator` over the hard forks.
|
||||||
|
pub fn new<C: ?Sized + ChainInfo, I: IntoIterator<Item = BlockNumber>>(
|
||||||
|
client: &C,
|
||||||
|
forks: I,
|
||||||
|
) -> Self {
|
||||||
|
let chain_info = client.chain_info();
|
||||||
|
let genesis_hash = primitive_types07::H256::from_slice(&chain_info.genesis_hash.0);
|
||||||
|
Self {
|
||||||
|
inner: ForkFilter::new(chain_info.best_block_number, genesis_hash, forks),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
/// Dummy version of ForkFilterApi with no forks.
|
||||||
|
pub fn new_dummy<C: ?Sized + ChainInfo>(client: &C) -> Self {
|
||||||
|
let chain_info = client.chain_info();
|
||||||
|
Self {
|
||||||
|
inner: ForkFilter::new(
|
||||||
|
chain_info.best_block_number,
|
||||||
|
primitive_types07::H256::from_slice(&chain_info.genesis_hash.0),
|
||||||
|
vec![],
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_head<C: ?Sized + ChainInfo>(&mut self, client: &C) {
|
||||||
|
self.inner.set_head(client.chain_info().best_block_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper for `ForkFilter::current`
|
||||||
|
pub fn current<C: ?Sized + ChainInfo>(&mut self, client: &C) -> ForkId {
|
||||||
|
self.update_head(client);
|
||||||
|
self.inner.current()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper for `ForkFilter::is_compatible`
|
||||||
|
pub fn is_compatible<C: ?Sized + ChainInfo>(
|
||||||
|
&mut self,
|
||||||
|
client: &C,
|
||||||
|
fork_id: ForkId,
|
||||||
|
) -> Result<(), RejectReason> {
|
||||||
|
self.update_head(client);
|
||||||
|
self.inner.is_compatible(fork_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use ethcore::{client::TestBlockChainClient, ethereum, spec::Spec};
|
||||||
|
|
||||||
|
fn test_spec<F: Fn() -> Spec>(spec_builder: F, forks: Vec<BlockNumber>) {
|
||||||
|
let spec = (spec_builder)();
|
||||||
|
let genesis_hash = spec.genesis_header().hash();
|
||||||
|
let spec_forks = spec.hard_forks.clone();
|
||||||
|
let client = TestBlockChainClient::new_with_spec(spec);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ForkFilterApi::new(&client, spec_forks).inner,
|
||||||
|
ForkFilter::new(
|
||||||
|
0,
|
||||||
|
primitive_types07::H256::from_slice(&genesis_hash.0),
|
||||||
|
forks
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ethereum_spec() {
|
||||||
|
test_spec(
|
||||||
|
|| ethereum::new_foundation(&String::new()),
|
||||||
|
vec![
|
||||||
|
1_150_000, 1_920_000, 2_463_000, 2_675_000, 4_370_000, 7_280_000, 9_069_000,
|
||||||
|
9_200_000,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ropsten_spec() {
|
||||||
|
test_spec(
|
||||||
|
|| ethereum::new_ropsten(&String::new()),
|
||||||
|
vec![10, 1_700_000, 4_230_000, 4_939_394, 6_485_846, 7_117_117],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rinkeby_spec() {
|
||||||
|
test_spec(
|
||||||
|
|| ethereum::new_rinkeby(&String::new()),
|
||||||
|
vec![1, 2, 3, 1_035_301, 3_660_663, 4_321_234, 5_435_345],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goerli_spec() {
|
||||||
|
test_spec(|| ethereum::new_goerli(&String::new()), vec![1_561_651])
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use api::PAR_PROTOCOL;
|
use api::{ETH_PROTOCOL, PAR_PROTOCOL};
|
||||||
use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAction};
|
use block_sync::{BlockDownloaderImportError as DownloaderImportError, DownloadAction};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use enum_primitive::FromPrimitive;
|
use enum_primitive::FromPrimitive;
|
||||||
@ -42,7 +42,7 @@ use super::sync_packet::{
|
|||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
BlockSet, ChainSync, ForkConfirmation, PacketProcessError, PeerAsking, PeerInfo, SyncRequester,
|
BlockSet, ChainSync, ForkConfirmation, PacketProcessError, PeerAsking, PeerInfo, SyncRequester,
|
||||||
SyncState, ETH_PROTOCOL_VERSION_62, ETH_PROTOCOL_VERSION_63, MAX_NEW_BLOCK_AGE, MAX_NEW_HASHES,
|
SyncState, ETH_PROTOCOL_VERSION_63, ETH_PROTOCOL_VERSION_64, MAX_NEW_BLOCK_AGE, MAX_NEW_HASHES,
|
||||||
PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2,
|
PAR_PROTOCOL_VERSION_1, PAR_PROTOCOL_VERSION_2,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -659,16 +659,72 @@ impl SyncHandler {
|
|||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
r: &Rlp,
|
r: &Rlp,
|
||||||
) -> Result<(), DownloaderImportError> {
|
) -> Result<(), DownloaderImportError> {
|
||||||
|
let mut r_iter = r.iter();
|
||||||
sync.handshaking_peers.remove(&peer_id);
|
sync.handshaking_peers.remove(&peer_id);
|
||||||
let protocol_version: u8 = r.val_at(0)?;
|
let protocol_version: u8 = r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?;
|
||||||
|
let eth_protocol_version = io.protocol_version(Ð_PROTOCOL, peer_id);
|
||||||
let warp_protocol_version = io.protocol_version(&PAR_PROTOCOL, peer_id);
|
let warp_protocol_version = io.protocol_version(&PAR_PROTOCOL, peer_id);
|
||||||
let warp_protocol = warp_protocol_version != 0;
|
let warp_protocol = warp_protocol_version != 0;
|
||||||
|
|
||||||
|
let network_id = r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?;
|
||||||
|
let difficulty = Some(
|
||||||
|
r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?,
|
||||||
|
);
|
||||||
|
let latest_hash = r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?;
|
||||||
|
let genesis = r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?;
|
||||||
|
let forkid_validation_error = {
|
||||||
|
if eth_protocol_version >= ETH_PROTOCOL_VERSION_64.0 {
|
||||||
|
let fork_id = rlp04::Rlp::new(r.as_raw()).val_at(5)?;
|
||||||
|
r_iter.next().ok_or(rlp::DecoderError::RlpIsTooShort)?;
|
||||||
|
sync.fork_filter
|
||||||
|
.is_compatible(io.chain(), fork_id)
|
||||||
|
.err()
|
||||||
|
.map(|e| (fork_id, e))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let snapshot_hash = if warp_protocol {
|
||||||
|
Some(
|
||||||
|
r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let snapshot_number = if warp_protocol {
|
||||||
|
Some(
|
||||||
|
r_iter
|
||||||
|
.next()
|
||||||
|
.ok_or(rlp::DecoderError::RlpIsTooShort)?
|
||||||
|
.as_val()?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
let peer = PeerInfo {
|
let peer = PeerInfo {
|
||||||
protocol_version: protocol_version,
|
protocol_version,
|
||||||
network_id: r.val_at(1)?,
|
network_id,
|
||||||
difficulty: Some(r.val_at(2)?),
|
difficulty,
|
||||||
latest_hash: r.val_at(3)?,
|
latest_hash,
|
||||||
genesis: r.val_at(4)?,
|
genesis,
|
||||||
asking: PeerAsking::Nothing,
|
asking: PeerAsking::Nothing,
|
||||||
asking_blocks: Vec::new(),
|
asking_blocks: Vec::new(),
|
||||||
asking_hash: None,
|
asking_hash: None,
|
||||||
@ -681,16 +737,8 @@ impl SyncHandler {
|
|||||||
ForkConfirmation::Unconfirmed
|
ForkConfirmation::Unconfirmed
|
||||||
},
|
},
|
||||||
asking_snapshot_data: None,
|
asking_snapshot_data: None,
|
||||||
snapshot_hash: if warp_protocol {
|
snapshot_hash,
|
||||||
Some(r.val_at(5)?)
|
snapshot_number,
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
snapshot_number: if warp_protocol {
|
|
||||||
Some(r.val_at(6)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
block_set: None,
|
block_set: None,
|
||||||
client_version: ClientVersion::from(io.peer_version(peer_id)),
|
client_version: ClientVersion::from(io.peer_version(peer_id)),
|
||||||
};
|
};
|
||||||
@ -729,13 +777,18 @@ impl SyncHandler {
|
|||||||
return Err(DownloaderImportError::Invalid);
|
return Err(DownloaderImportError::Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some((fork_id, reason)) = forkid_validation_error {
|
||||||
|
trace!(target: "sync", "Peer {} incompatible fork id (fork id: {:#x}/{}, error: {:?})", peer_id, fork_id.hash.0, fork_id.next, reason);
|
||||||
|
return Err(DownloaderImportError::Invalid);
|
||||||
|
}
|
||||||
|
|
||||||
if false
|
if false
|
||||||
|| (warp_protocol
|
|| (warp_protocol
|
||||||
&& (peer.protocol_version < PAR_PROTOCOL_VERSION_1.0
|
&& (peer.protocol_version < PAR_PROTOCOL_VERSION_1.0
|
||||||
|| peer.protocol_version > PAR_PROTOCOL_VERSION_2.0))
|
|| peer.protocol_version > PAR_PROTOCOL_VERSION_2.0))
|
||||||
|| (!warp_protocol
|
|| (!warp_protocol
|
||||||
&& (peer.protocol_version < ETH_PROTOCOL_VERSION_62.0
|
&& (peer.protocol_version < ETH_PROTOCOL_VERSION_63.0
|
||||||
|| peer.protocol_version > ETH_PROTOCOL_VERSION_63.0))
|
|| peer.protocol_version > ETH_PROTOCOL_VERSION_64.0))
|
||||||
{
|
{
|
||||||
trace!(target: "sync", "Peer {} unsupported eth protocol ({})", peer_id, peer.protocol_version);
|
trace!(target: "sync", "Peer {} unsupported eth protocol ({})", peer_id, peer.protocol_version);
|
||||||
return Err(DownloaderImportError::Invalid);
|
return Err(DownloaderImportError::Invalid);
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! `BlockChain` synchronization strategy.
|
//! `BlockChain` synchronization strategy.
|
||||||
//! Syncs to peers and keeps up to date.
|
//! Syncs to peers and keeps up to date.
|
||||||
//! This implementation uses ethereum protocol v63
|
//! This implementation uses ethereum protocol v63/v64
|
||||||
//!
|
//!
|
||||||
//! Syncing strategy summary.
|
//! Syncing strategy summary.
|
||||||
//! Split the chain into ranges of N blocks each. Download ranges sequentially. Split each range into subchains of M blocks. Download subchains in parallel.
|
//! Split the chain into ranges of N blocks each. Download ranges sequentially. Split each range into subchains of M blocks. Download subchains in parallel.
|
||||||
@ -87,14 +87,16 @@
|
|||||||
//!
|
//!
|
||||||
//! All other messages are ignored.
|
//! All other messages are ignored.
|
||||||
|
|
||||||
|
pub mod fork_filter;
|
||||||
mod handler;
|
mod handler;
|
||||||
mod propagator;
|
mod propagator;
|
||||||
mod requester;
|
mod requester;
|
||||||
mod supplier;
|
mod supplier;
|
||||||
pub mod sync_packet;
|
pub mod sync_packet;
|
||||||
|
|
||||||
|
pub use self::fork_filter::ForkFilterApi;
|
||||||
use super::{SyncConfig, WarpSync};
|
use super::{SyncConfig, WarpSync};
|
||||||
use api::{EthProtocolInfo as PeerInfoDigest, PriorityTask, PAR_PROTOCOL};
|
use api::{EthProtocolInfo as PeerInfoDigest, PriorityTask, ETH_PROTOCOL, PAR_PROTOCOL};
|
||||||
use block_sync::{BlockDownloader, DownloadAction};
|
use block_sync::{BlockDownloader, DownloadAction};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use derive_more::Display;
|
use derive_more::Display;
|
||||||
@ -151,10 +153,10 @@ impl From<DecoderError> for PacketProcessError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 64 version of Ethereum protocol.
|
||||||
|
pub const ETH_PROTOCOL_VERSION_64: (u8, u8) = (64, 0x11);
|
||||||
/// 63 version of Ethereum protocol.
|
/// 63 version of Ethereum protocol.
|
||||||
pub const ETH_PROTOCOL_VERSION_63: (u8, u8) = (63, 0x11);
|
pub const ETH_PROTOCOL_VERSION_63: (u8, u8) = (63, 0x11);
|
||||||
/// 62 version of Ethereum protocol.
|
|
||||||
pub const ETH_PROTOCOL_VERSION_62: (u8, u8) = (62, 0x11);
|
|
||||||
/// 1 version of Parity protocol and the packet count.
|
/// 1 version of Parity protocol and the packet count.
|
||||||
pub const PAR_PROTOCOL_VERSION_1: (u8, u8) = (1, 0x15);
|
pub const PAR_PROTOCOL_VERSION_1: (u8, u8) = (1, 0x15);
|
||||||
/// 2 version of Parity protocol (consensus messages added).
|
/// 2 version of Parity protocol (consensus messages added).
|
||||||
@ -407,10 +409,11 @@ impl ChainSyncApi {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
config: SyncConfig,
|
config: SyncConfig,
|
||||||
chain: &dyn BlockChainClient,
|
chain: &dyn BlockChainClient,
|
||||||
|
fork_filter: ForkFilterApi,
|
||||||
priority_tasks: mpsc::Receiver<PriorityTask>,
|
priority_tasks: mpsc::Receiver<PriorityTask>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
ChainSyncApi {
|
ChainSyncApi {
|
||||||
sync: RwLock::new(ChainSync::new(config, chain)),
|
sync: RwLock::new(ChainSync::new(config, chain, fork_filter)),
|
||||||
priority_tasks: Mutex::new(priority_tasks),
|
priority_tasks: Mutex::new(priority_tasks),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,6 +663,8 @@ pub struct ChainSync {
|
|||||||
network_id: u64,
|
network_id: u64,
|
||||||
/// Optional fork block to check
|
/// Optional fork block to check
|
||||||
fork_block: Option<(BlockNumber, H256)>,
|
fork_block: Option<(BlockNumber, H256)>,
|
||||||
|
/// Fork filter
|
||||||
|
fork_filter: ForkFilterApi,
|
||||||
/// Snapshot downloader.
|
/// Snapshot downloader.
|
||||||
snapshot: Snapshot,
|
snapshot: Snapshot,
|
||||||
/// Connected peers pending Status message.
|
/// Connected peers pending Status message.
|
||||||
@ -680,8 +685,11 @@ pub struct ChainSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ChainSync {
|
impl ChainSync {
|
||||||
/// Create a new instance of syncing strategy.
|
pub fn new(
|
||||||
pub fn new(config: SyncConfig, chain: &dyn BlockChainClient) -> Self {
|
config: SyncConfig,
|
||||||
|
chain: &dyn BlockChainClient,
|
||||||
|
fork_filter: ForkFilterApi,
|
||||||
|
) -> Self {
|
||||||
let chain_info = chain.chain_info();
|
let chain_info = chain.chain_info();
|
||||||
let best_block = chain.chain_info().best_block_number;
|
let best_block = chain.chain_info().best_block_number;
|
||||||
let state = Self::get_init_state(config.warp_sync, chain);
|
let state = Self::get_init_state(config.warp_sync, chain);
|
||||||
@ -704,6 +712,7 @@ impl ChainSync {
|
|||||||
last_sent_block_number: 0,
|
last_sent_block_number: 0,
|
||||||
network_id: config.network_id,
|
network_id: config.network_id,
|
||||||
fork_block: config.fork_block,
|
fork_block: config.fork_block,
|
||||||
|
fork_filter,
|
||||||
download_old_blocks: config.download_old_blocks,
|
download_old_blocks: config.download_old_blocks,
|
||||||
snapshot: Snapshot::new(),
|
snapshot: Snapshot::new(),
|
||||||
sync_start_time: None,
|
sync_start_time: None,
|
||||||
@ -725,7 +734,7 @@ impl ChainSync {
|
|||||||
|
|
||||||
SyncStatus {
|
SyncStatus {
|
||||||
state: self.state.clone(),
|
state: self.state.clone(),
|
||||||
protocol_version: ETH_PROTOCOL_VERSION_63.0,
|
protocol_version: ETH_PROTOCOL_VERSION_64.0,
|
||||||
network_id: self.network_id,
|
network_id: self.network_id,
|
||||||
start_block_number: self.starting_block,
|
start_block_number: self.starting_block,
|
||||||
last_imported_block_number: Some(last_imported_number),
|
last_imported_block_number: Some(last_imported_number),
|
||||||
@ -1255,30 +1264,35 @@ impl ChainSync {
|
|||||||
|
|
||||||
/// Send Status message
|
/// Send Status message
|
||||||
fn send_status(&mut self, io: &mut dyn SyncIo, peer: PeerId) -> Result<(), network::Error> {
|
fn send_status(&mut self, io: &mut dyn SyncIo, peer: PeerId) -> Result<(), network::Error> {
|
||||||
|
let eth_protocol_version = io.protocol_version(Ð_PROTOCOL, peer);
|
||||||
let warp_protocol_version = io.protocol_version(&PAR_PROTOCOL, peer);
|
let warp_protocol_version = io.protocol_version(&PAR_PROTOCOL, peer);
|
||||||
let warp_protocol = warp_protocol_version != 0;
|
let warp_protocol = warp_protocol_version != 0;
|
||||||
let protocol = if warp_protocol {
|
let protocol = if warp_protocol {
|
||||||
warp_protocol_version
|
warp_protocol_version
|
||||||
} else {
|
} else {
|
||||||
ETH_PROTOCOL_VERSION_63.0
|
eth_protocol_version
|
||||||
};
|
};
|
||||||
trace!(target: "sync", "Sending status to {}, protocol version {}", peer, protocol);
|
trace!(target: "sync", "Sending status to {}, protocol version {}", peer, protocol);
|
||||||
let mut packet = RlpStream::new();
|
|
||||||
|
let mut packet = rlp04::RlpStream::new();
|
||||||
packet.begin_unbounded_list();
|
packet.begin_unbounded_list();
|
||||||
let chain = io.chain().chain_info();
|
let chain = io.chain().chain_info();
|
||||||
packet.append(&(protocol as u32));
|
packet.append(&(protocol as u32));
|
||||||
packet.append(&self.network_id);
|
packet.append(&self.network_id);
|
||||||
packet.append(&chain.total_difficulty);
|
packet.append(&primitive_types07::U256(chain.total_difficulty.0));
|
||||||
packet.append(&chain.best_block_hash);
|
packet.append(&primitive_types07::H256(chain.best_block_hash.0));
|
||||||
packet.append(&chain.genesis_hash);
|
packet.append(&primitive_types07::H256(chain.genesis_hash.0));
|
||||||
|
if eth_protocol_version >= ETH_PROTOCOL_VERSION_64.0 {
|
||||||
|
packet.append(&self.fork_filter.current(io.chain()));
|
||||||
|
}
|
||||||
if warp_protocol {
|
if warp_protocol {
|
||||||
let manifest = io.snapshot_service().manifest();
|
let manifest = io.snapshot_service().manifest();
|
||||||
let block_number = manifest.as_ref().map_or(0, |m| m.block_number);
|
let block_number = manifest.as_ref().map_or(0, |m| m.block_number);
|
||||||
let manifest_hash = manifest.map_or(H256::new(), |m| keccak(m.into_rlp()));
|
let manifest_hash = manifest.map_or(H256::new(), |m| keccak(m.into_rlp()));
|
||||||
packet.append(&manifest_hash);
|
packet.append(&primitive_types07::H256(manifest_hash.0));
|
||||||
packet.append(&block_number);
|
packet.append(&block_number);
|
||||||
}
|
}
|
||||||
packet.complete_unbounded_list();
|
packet.finalize_unbounded_list();
|
||||||
io.respond(StatusPacket.id(), packet.out())
|
io.respond(StatusPacket.id(), packet.out())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1577,7 +1591,11 @@ pub mod tests {
|
|||||||
peer_latest_hash: H256,
|
peer_latest_hash: H256,
|
||||||
client: &dyn BlockChainClient,
|
client: &dyn BlockChainClient,
|
||||||
) -> ChainSync {
|
) -> ChainSync {
|
||||||
let mut sync = ChainSync::new(SyncConfig::default(), client);
|
let mut sync = ChainSync::new(
|
||||||
|
SyncConfig::default(),
|
||||||
|
client,
|
||||||
|
ForkFilterApi::new_dummy(client),
|
||||||
|
);
|
||||||
insert_dummy_peer(&mut sync, 0, peer_latest_hash);
|
insert_dummy_peer(&mut sync, 0, peer_latest_hash);
|
||||||
sync
|
sync
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,11 @@ mod tests {
|
|||||||
client.add_blocks(2, EachBlockWith::Uncle);
|
client.add_blocks(2, EachBlockWith::Uncle);
|
||||||
let queue = RwLock::new(VecDeque::new());
|
let queue = RwLock::new(VecDeque::new());
|
||||||
let block = client.block(BlockId::Latest).unwrap().into_inner();
|
let block = client.block(BlockId::Latest).unwrap().into_inner();
|
||||||
let mut sync = ChainSync::new(SyncConfig::default(), &client);
|
let mut sync = ChainSync::new(
|
||||||
|
SyncConfig::default(),
|
||||||
|
&client,
|
||||||
|
ForkFilterApi::new_dummy(&client),
|
||||||
|
);
|
||||||
sync.peers.insert(
|
sync.peers.insert(
|
||||||
0,
|
0,
|
||||||
PeerInfo {
|
PeerInfo {
|
||||||
@ -540,7 +544,11 @@ mod tests {
|
|||||||
client.add_blocks(100, EachBlockWith::Uncle);
|
client.add_blocks(100, EachBlockWith::Uncle);
|
||||||
client.insert_transaction_to_queue();
|
client.insert_transaction_to_queue();
|
||||||
// Sync with no peers
|
// Sync with no peers
|
||||||
let mut sync = ChainSync::new(SyncConfig::default(), &client);
|
let mut sync = ChainSync::new(
|
||||||
|
SyncConfig::default(),
|
||||||
|
&client,
|
||||||
|
ForkFilterApi::new_dummy(&client),
|
||||||
|
);
|
||||||
let queue = RwLock::new(VecDeque::new());
|
let queue = RwLock::new(VecDeque::new());
|
||||||
let ss = TestSnapshotService::new();
|
let ss = TestSnapshotService::new();
|
||||||
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
||||||
@ -617,7 +625,11 @@ mod tests {
|
|||||||
let mut client = TestBlockChainClient::new();
|
let mut client = TestBlockChainClient::new();
|
||||||
client.insert_transaction_with_gas_price_to_queue(U256::zero());
|
client.insert_transaction_with_gas_price_to_queue(U256::zero());
|
||||||
let block_hash = client.block_hash_delta_minus(1);
|
let block_hash = client.block_hash_delta_minus(1);
|
||||||
let mut sync = ChainSync::new(SyncConfig::default(), &client);
|
let mut sync = ChainSync::new(
|
||||||
|
SyncConfig::default(),
|
||||||
|
&client,
|
||||||
|
ForkFilterApi::new_dummy(&client),
|
||||||
|
);
|
||||||
let queue = RwLock::new(VecDeque::new());
|
let queue = RwLock::new(VecDeque::new());
|
||||||
let ss = TestSnapshotService::new();
|
let ss = TestSnapshotService::new();
|
||||||
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
||||||
@ -655,7 +667,11 @@ mod tests {
|
|||||||
let tx1_hash = client.insert_transaction_to_queue();
|
let tx1_hash = client.insert_transaction_to_queue();
|
||||||
let tx2_hash = client.insert_transaction_with_gas_price_to_queue(U256::zero());
|
let tx2_hash = client.insert_transaction_with_gas_price_to_queue(U256::zero());
|
||||||
let block_hash = client.block_hash_delta_minus(1);
|
let block_hash = client.block_hash_delta_minus(1);
|
||||||
let mut sync = ChainSync::new(SyncConfig::default(), &client);
|
let mut sync = ChainSync::new(
|
||||||
|
SyncConfig::default(),
|
||||||
|
&client,
|
||||||
|
ForkFilterApi::new_dummy(&client),
|
||||||
|
);
|
||||||
let queue = RwLock::new(VecDeque::new());
|
let queue = RwLock::new(VecDeque::new());
|
||||||
let ss = TestSnapshotService::new();
|
let ss = TestSnapshotService::new();
|
||||||
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
let mut io = TestIo::new(&mut client, &ss, &queue, None);
|
||||||
|
@ -27,6 +27,7 @@ extern crate ethcore;
|
|||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate ethcore_network as network;
|
extern crate ethcore_network as network;
|
||||||
extern crate ethcore_network_devp2p as devp2p;
|
extern crate ethcore_network_devp2p as devp2p;
|
||||||
|
extern crate ethereum_forkid;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate ethkey;
|
extern crate ethkey;
|
||||||
extern crate ethstore;
|
extern crate ethstore;
|
||||||
@ -34,8 +35,10 @@ extern crate fastmap;
|
|||||||
extern crate keccak_hash as hash;
|
extern crate keccak_hash as hash;
|
||||||
extern crate parity_bytes as bytes;
|
extern crate parity_bytes as bytes;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
|
extern crate primitive_types07;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
|
extern crate rlp04;
|
||||||
extern crate stats;
|
extern crate stats;
|
||||||
extern crate triehash_ethereum;
|
extern crate triehash_ethereum;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use api::PAR_PROTOCOL;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use chain::{
|
use chain::{
|
||||||
sync_packet::{PacketInfo, SyncPacket},
|
sync_packet::{PacketInfo, SyncPacket},
|
||||||
ChainSync, SyncSupplier, ETH_PROTOCOL_VERSION_63, PAR_PROTOCOL_VERSION_2,
|
ChainSync, ForkFilterApi, SyncSupplier, ETH_PROTOCOL_VERSION_64, PAR_PROTOCOL_VERSION_2,
|
||||||
};
|
};
|
||||||
use ethcore::{
|
use ethcore::{
|
||||||
client::{
|
client::{
|
||||||
@ -30,6 +30,7 @@ use ethcore::{
|
|||||||
spec::Spec,
|
spec::Spec,
|
||||||
test_helpers,
|
test_helpers,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ethereum_types::H256;
|
use ethereum_types::H256;
|
||||||
use io::{IoChannel, IoContext, IoHandler};
|
use io::{IoChannel, IoContext, IoHandler};
|
||||||
use network::{self, client_version::ClientVersion, PacketId, PeerId, ProtocolId, SessionInfo};
|
use network::{self, client_version::ClientVersion, PacketId, PeerId, ProtocolId, SessionInfo};
|
||||||
@ -168,7 +169,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eth_protocol_version(&self, _peer: PeerId) -> u8 {
|
fn eth_protocol_version(&self, _peer: PeerId) -> u8 {
|
||||||
ETH_PROTOCOL_VERSION_63.0
|
ETH_PROTOCOL_VERSION_64.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 {
|
fn protocol_version(&self, protocol: &ProtocolId, peer_id: PeerId) -> u8 {
|
||||||
@ -405,7 +406,7 @@ impl TestNet<EthPeer<TestBlockChainClient>> {
|
|||||||
for _ in 0..n {
|
for _ in 0..n {
|
||||||
let chain = TestBlockChainClient::new();
|
let chain = TestBlockChainClient::new();
|
||||||
let ss = Arc::new(TestSnapshotService::new());
|
let ss = Arc::new(TestSnapshotService::new());
|
||||||
let sync = ChainSync::new(config.clone(), &chain);
|
let sync = ChainSync::new(config.clone(), &chain, ForkFilterApi::new_dummy(&chain));
|
||||||
net.peers.push(Arc::new(EthPeer {
|
net.peers.push(Arc::new(EthPeer {
|
||||||
sync: RwLock::new(sync),
|
sync: RwLock::new(sync),
|
||||||
snapshot_service: ss,
|
snapshot_service: ss,
|
||||||
@ -454,7 +455,7 @@ impl TestNet<EthPeer<EthcoreClient>> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let ss = Arc::new(TestSnapshotService::new());
|
let ss = Arc::new(TestSnapshotService::new());
|
||||||
let sync = ChainSync::new(config, &*client);
|
let sync = ChainSync::new(config, &*client, ForkFilterApi::new_dummy(&*client));
|
||||||
let peer = Arc::new(EthPeer {
|
let peer = Arc::new(EthPeer {
|
||||||
sync: RwLock::new(sync),
|
sync: RwLock::new(sync),
|
||||||
snapshot_service: ss,
|
snapshot_service: ss,
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
use std::sync::{mpsc, Arc};
|
use std::sync::{mpsc, Arc};
|
||||||
|
|
||||||
use ethcore::{client::BlockChainClient, snapshot::SnapshotService};
|
use ethcore::{client::BlockChainClient, snapshot::SnapshotService};
|
||||||
|
use std::collections::BTreeSet;
|
||||||
use sync::{self, ConnectionFilter, NetworkConfiguration, Params, SyncConfig};
|
use sync::{self, ConnectionFilter, NetworkConfiguration, Params, SyncConfig};
|
||||||
|
use types::BlockNumber;
|
||||||
|
|
||||||
pub use ethcore::client::ChainNotify;
|
pub use ethcore::client::ChainNotify;
|
||||||
use ethcore_logger::Config as LogConfig;
|
use ethcore_logger::Config as LogConfig;
|
||||||
@ -34,6 +36,7 @@ pub fn sync(
|
|||||||
config: SyncConfig,
|
config: SyncConfig,
|
||||||
network_config: NetworkConfiguration,
|
network_config: NetworkConfiguration,
|
||||||
chain: Arc<dyn BlockChainClient>,
|
chain: Arc<dyn BlockChainClient>,
|
||||||
|
forks: BTreeSet<BlockNumber>,
|
||||||
snapshot_service: Arc<dyn SnapshotService>,
|
snapshot_service: Arc<dyn SnapshotService>,
|
||||||
_log_settings: &LogConfig,
|
_log_settings: &LogConfig,
|
||||||
connection_filter: Option<Arc<dyn ConnectionFilter>>,
|
connection_filter: Option<Arc<dyn ConnectionFilter>>,
|
||||||
@ -42,6 +45,7 @@ pub fn sync(
|
|||||||
Params {
|
Params {
|
||||||
config,
|
config,
|
||||||
chain,
|
chain,
|
||||||
|
forks,
|
||||||
snapshot_service,
|
snapshot_service,
|
||||||
network_config,
|
network_config,
|
||||||
},
|
},
|
||||||
|
@ -360,6 +360,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<RunningClient
|
|||||||
|
|
||||||
let connection_filter_address = spec.params().node_permission_contract;
|
let connection_filter_address = spec.params().node_permission_contract;
|
||||||
// drop the spec to free up genesis state.
|
// drop the spec to free up genesis state.
|
||||||
|
let forks = spec.hard_forks.clone();
|
||||||
drop(spec);
|
drop(spec);
|
||||||
|
|
||||||
// take handle to client
|
// take handle to client
|
||||||
@ -433,6 +434,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<RunningClient
|
|||||||
sync_config,
|
sync_config,
|
||||||
net_conf.clone().into(),
|
net_conf.clone().into(),
|
||||||
client.clone(),
|
client.clone(),
|
||||||
|
forks,
|
||||||
snapshot_service.clone(),
|
snapshot_service.clone(),
|
||||||
&cmd.logger_config,
|
&cmd.logger_config,
|
||||||
connection_filter
|
connection_filter
|
||||||
|
@ -44,7 +44,7 @@ impl TestSyncProvider {
|
|||||||
status: RwLock::new(SyncStatus {
|
status: RwLock::new(SyncStatus {
|
||||||
state: SyncState::Idle,
|
state: SyncState::Idle,
|
||||||
network_id: config.network_id,
|
network_id: config.network_id,
|
||||||
protocol_version: 63,
|
protocol_version: 64,
|
||||||
start_block_number: 0,
|
start_block_number: 0,
|
||||||
last_imported_block_number: None,
|
last_imported_block_number: None,
|
||||||
highest_block_number: None,
|
highest_block_number: None,
|
||||||
@ -82,11 +82,11 @@ impl SyncProvider for TestSyncProvider {
|
|||||||
PeerInfo {
|
PeerInfo {
|
||||||
id: Some("node1".to_owned()),
|
id: Some("node1".to_owned()),
|
||||||
client_version: ClientVersion::from("Parity-Ethereum/1/v2.4.0/linux/rustc"),
|
client_version: ClientVersion::from("Parity-Ethereum/1/v2.4.0/linux/rustc"),
|
||||||
capabilities: vec!["eth/62".to_owned(), "eth/63".to_owned()],
|
capabilities: vec!["eth/63".to_owned(), "eth/64".to_owned()],
|
||||||
remote_address: "127.0.0.1:7777".to_owned(),
|
remote_address: "127.0.0.1:7777".to_owned(),
|
||||||
local_address: "127.0.0.1:8888".to_owned(),
|
local_address: "127.0.0.1:8888".to_owned(),
|
||||||
eth_info: Some(EthProtocolInfo {
|
eth_info: Some(EthProtocolInfo {
|
||||||
version: 62,
|
version: 63,
|
||||||
difficulty: Some(40.into()),
|
difficulty: Some(40.into()),
|
||||||
head: 50.into(),
|
head: 50.into(),
|
||||||
}),
|
}),
|
||||||
@ -94,11 +94,11 @@ impl SyncProvider for TestSyncProvider {
|
|||||||
PeerInfo {
|
PeerInfo {
|
||||||
id: None,
|
id: None,
|
||||||
client_version: ClientVersion::from("Parity-Ethereum/2/v2.4.0/linux/rustc"),
|
client_version: ClientVersion::from("Parity-Ethereum/2/v2.4.0/linux/rustc"),
|
||||||
capabilities: vec!["eth/63".to_owned(), "eth/64".to_owned()],
|
capabilities: vec!["eth/64".to_owned(), "eth/65".to_owned()],
|
||||||
remote_address: "Handshake".to_owned(),
|
remote_address: "Handshake".to_owned(),
|
||||||
local_address: "127.0.0.1:3333".to_owned(),
|
local_address: "127.0.0.1:3333".to_owned(),
|
||||||
eth_info: Some(EthProtocolInfo {
|
eth_info: Some(EthProtocolInfo {
|
||||||
version: 64,
|
version: 65,
|
||||||
difficulty: None,
|
difficulty: None,
|
||||||
head: 60.into(),
|
head: 60.into(),
|
||||||
}),
|
}),
|
||||||
|
@ -137,7 +137,7 @@ impl EthTester {
|
|||||||
#[test]
|
#[test]
|
||||||
fn rpc_eth_protocol_version() {
|
fn rpc_eth_protocol_version() {
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "eth_protocolVersion", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "eth_protocolVersion", "params": [], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":"63","id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":"64","id":1}"#;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
EthTester::default().io.handle_request_sync(request),
|
EthTester::default().io.handle_request_sync(request),
|
||||||
|
@ -212,7 +212,7 @@ fn rpc_parity_net_peers() {
|
|||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_netPeers", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/62","eth/63"],"id":"node1","name":{"ParityClient":{"can_handle_large_requests":true,"compiler":"rustc","identity":"1","name":"Parity-Ethereum","os":"linux","semver":"2.4.0"}},"network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":62}}},{"caps":["eth/63","eth/64"],"id":null,"name":{"ParityClient":{"can_handle_large_requests":true,"compiler":"rustc","identity":"2","name":"Parity-Ethereum","os":"linux","semver":"2.4.0"}},"network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":64}}}]},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","result":{"active":0,"connected":120,"max":50,"peers":[{"caps":["eth/63","eth/64"],"id":"node1","name":{"ParityClient":{"can_handle_large_requests":true,"compiler":"rustc","identity":"1","name":"Parity-Ethereum","os":"linux","semver":"2.4.0"}},"network":{"localAddress":"127.0.0.1:8888","remoteAddress":"127.0.0.1:7777"},"protocols":{"eth":{"difficulty":"0x28","head":"0000000000000000000000000000000000000000000000000000000000000032","version":63}}},{"caps":["eth/64","eth/65"],"id":null,"name":{"ParityClient":{"can_handle_large_requests":true,"compiler":"rustc","identity":"2","name":"Parity-Ethereum","os":"linux","semver":"2.4.0"}},"network":{"localAddress":"127.0.0.1:3333","remoteAddress":"Handshake"},"protocols":{"eth":{"difficulty":null,"head":"000000000000000000000000000000000000000000000000000000000000003c","version":65}}}]},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user