backports for stable 2.2.7 (#10163)

* version: bump stable to 2.2.7

* version: mark 2.2 track stable

* version: mark update critical on all networks

* version: commit cargo lock

* Ping nodes from discovery (#10167)

* snap: fix path in script (#10157)

* snap: fix path in script

* debug, revert me

* fix

* necromancer awk magic

* awk necromancy and path fixing

* working track selection

* Fix _cannot recursively call into `Core`_ issue (#10144)

* Change igd to github:maufl/rust-igd

* Run `igd::search_gateway_from_timeout` from own thread

* Handle the case for contract creation on an empty but exist account with storage items (#10065)

* Add is_base_storage_root_unchanged

* Fix compile, use a shortcut for check, and remove ignored tests

* Add a warn!

* Update ethereum/tests to v6.0.0-beta.2

* grumble: use {:#x} instead of 0x{:x}

Co-Authored-By: sorpaas <accounts@that.world>

* version: bump fork blocks for kovan and foundation (#10186)

* pull constantinople on ethereum network (#10189)

* ethcore: pull constantinople on ethereum network

* version: mark update as critical

* ethcore: remove constantinople alltogether from chain spec

* version: revert fork block for ethereum
This commit is contained in:
Afri Schoedon 2019-01-15 22:25:31 +01:00 committed by GitHub
parent e9396e158b
commit b00a21f39a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 152 additions and 114 deletions

12
Cargo.lock generated
View File

@ -2210,7 +2210,7 @@ version = "1.12.0"
dependencies = [ dependencies = [
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0", "panic_hook 0.1.0",
"parity-ethereum 2.2.6", "parity-ethereum 2.2.7",
] ]
[[package]] [[package]]
@ -2226,7 +2226,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-ethereum" name = "parity-ethereum"
version = "2.2.6" version = "2.2.7"
dependencies = [ dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2275,7 +2275,7 @@ dependencies = [
"parity-rpc-client 1.4.0", "parity-rpc-client 1.4.0",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.2.6", "parity-version 2.2.7",
"parity-whisper 0.1.0", "parity-whisper 0.1.0",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2430,7 +2430,7 @@ dependencies = [
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-runtime 0.1.0", "parity-runtime 0.1.0",
"parity-updater 1.12.0", "parity-updater 1.12.0",
"parity-version 2.2.6", "parity-version 2.2.7",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2527,7 +2527,7 @@ dependencies = [
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-hash-fetch 1.12.0", "parity-hash-fetch 1.12.0",
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-version 2.2.6", "parity-version 2.2.7",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2537,7 +2537,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-version" name = "parity-version"
version = "2.2.6" version = "2.2.7"
dependencies = [ dependencies = [
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -2,7 +2,7 @@
description = "Parity Ethereum client" description = "Parity Ethereum client"
name = "parity-ethereum" name = "parity-ethereum"
# NOTE Make sure to update util/version/Cargo.toml as well # NOTE Make sure to update util/version/Cargo.toml as well
version = "2.2.6" version = "2.2.7"
license = "GPL-3.0" license = "GPL-3.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]

View File

@ -9,8 +9,7 @@
"durationLimit": "0xd", "durationLimit": "0xd",
"blockReward": { "blockReward": {
"0x0": "0x4563918244f40000", "0x0": "0x4563918244f40000",
"0x42ae50": "0x29a2241af62c0000", "0x42ae50": "0x29a2241af62c0000"
"0x6c0840": "0x1bc16d674ec80000"
}, },
"homesteadTransition": "0x118c30", "homesteadTransition": "0x118c30",
"daoHardforkTransition": "0x1d4c00", "daoHardforkTransition": "0x1d4c00",
@ -135,8 +134,7 @@
], ],
"eip100bTransition": "0x42ae50", "eip100bTransition": "0x42ae50",
"difficultyBombDelays": { "difficultyBombDelays": {
"0x42ae50": "0x2dc6c0", "0x42ae50": "0x2dc6c0"
"0x6c0840": "0x1e8480"
} }
} }
} }
@ -161,11 +159,7 @@
"eip140Transition": "0x42ae50", "eip140Transition": "0x42ae50",
"eip211Transition": "0x42ae50", "eip211Transition": "0x42ae50",
"eip214Transition": "0x42ae50", "eip214Transition": "0x42ae50",
"eip658Transition": "0x42ae50", "eip658Transition": "0x42ae50"
"eip145Transition": "0x6c0840",
"eip1014Transition": "0x6c0840",
"eip1052Transition": "0x6c0840",
"eip1283Transition": "0x6c0840"
}, },
"genesis": { "genesis": {
"seal": { "seal": {

@ -1 +1 @@
Subproject commit 2cd62aeec11da29766b30d500f2b9a96f1f28cf0 Subproject commit 420f443477caa8516f1f9ee8122fafc3415c0f34

View File

@ -1,42 +1,4 @@
{ "block":
[
{ {
"reference": "None", "block": [],
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.", "state": []
"failing": "GeneralStateTest_stCreate2",
"subtests": ["RevertInCreateInInitCreate2_d0g0v0_Constantinople"]
},
{
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "GeneralStateTest_stRevertTest",
"subtests": ["RevertInCreateInInit_d0g0v0_Constantinople"]
}
],
"state":
[
{
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "stCreate2Test",
"subtests": {
"RevertInCreateInInitCreate2": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
}
}
},
{
"reference": "None",
"comment": "This failing test is deemed skippable. Could not happen on a mainnet.",
"failing": "stRevertTest",
"subtests": {
"RevertInCreateInInit": {
"subnumbers": ["1"],
"chain": "Constantinople (test)"
}
}
}
]
} }

View File

@ -116,7 +116,12 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend where T: Tracer, V: VMTracer, B: StateBackend
{ {
fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> { fn initial_storage_at(&self, key: &H256) -> vm::Result<H256> {
if self.state.is_base_storage_root_unchanged(&self.origin_info.address)? {
self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into) self.state.checkpoint_storage_at(0, &self.origin_info.address, key).map(|v| v.unwrap_or(H256::zero())).map_err(Into::into)
} else {
warn!(target: "externalities", "Detected existing account {:#x} where a forced contract creation happened.", self.origin_info.address);
Ok(H256::zero())
}
} }
fn storage_at(&self, key: &H256) -> vm::Result<H256> { fn storage_at(&self, key: &H256) -> vm::Result<H256> {

View File

@ -447,6 +447,11 @@ impl Account {
} }
} }
/// Whether the base storage root of this account is unchanged.
pub fn is_base_storage_root_unchanged(&self) -> bool {
self.original_storage_cache.is_none()
}
/// Storage root where the account changes are based upon. /// Storage root where the account changes are based upon.
pub fn base_storage_root(&self) -> H256 { pub fn base_storage_root(&self) -> H256 {
self.storage_root self.storage_root

View File

@ -539,6 +539,13 @@ impl<B: Backend> State<B> {
|a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce())) |a| a.as_ref().map_or(self.account_start_nonce, |account| *account.nonce()))
} }
/// Whether the base storage root of an account remains unchanged.
pub fn is_base_storage_root_unchanged(&self, a: &Address) -> TrieResult<bool> {
Ok(self.ensure_cached(a, RequireCache::None, true,
|a| a.as_ref().map(|account| account.is_base_storage_root_unchanged()))?
.unwrap_or(true))
}
/// Get the storage root of account `a`. /// Get the storage root of account `a`.
pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> { pub fn storage_root(&self, a: &Address) -> TrieResult<Option<H256>> {
self.ensure_cached(a, RequireCache::None, true, self.ensure_cached(a, RequireCache::None, true,

View File

@ -3,13 +3,17 @@
set -e # fail on any error set -e # fail on any error
set -u # treat unset variables as error set -u # treat unset variables as error
TRACK=`awk -F '=' '/^track/ {print $2}' ./util/version/Cargo.toml` # some necromancy:
# gsub(/"/, "", $2) deletes "qoutes"
# gsub(/ /, "", $2) deletes whitespaces
TRACK=`awk -F '=' '/^track/ {gsub(/"/, "", $2); gsub(/ /, "", $2); print $2}' ./util/version/Cargo.toml`
echo Track is: $TRACK
case ${TRACK} in case ${TRACK} in
nightly) export GRADE="devel" CHANNEL="edge";; nightly) export GRADE="devel" CHANNEL="edge";;
beta) export GRADE="stable" CHANNEL="beta";; beta) export GRADE="stable" CHANNEL="beta";;
stable) export GRADE="stable" CHANNEL="stable";; stable) export GRADE="stable" CHANNEL="stable";;
*) echo "No release" exit 0;; *) echo "No release" && exit 0;;
esac esac
SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap" SNAP_PACKAGE="parity_"$VERSION"_"$BUILD_ARCH".snap"

View File

@ -53,12 +53,15 @@ const REQUEST_BACKOFF: [Duration; 4] = [
Duration::from_secs(64) Duration::from_secs(64)
]; ];
const NODE_LAST_SEEN_TIMEOUT: Duration = Duration::from_secs(24*60*60);
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct NodeEntry { pub struct NodeEntry {
pub id: NodeId, pub id: NodeId,
pub endpoint: NodeEndpoint, pub endpoint: NodeEndpoint,
} }
#[derive(Debug)]
pub struct BucketEntry { pub struct BucketEntry {
pub address: NodeEntry, pub address: NodeEntry,
pub id_hash: H256, pub id_hash: H256,
@ -89,6 +92,12 @@ struct FindNodeRequest {
answered: bool, answered: bool,
} }
#[derive(Clone, Copy)]
enum PingReason {
Default,
FromDiscoveryRequest(NodeId)
}
struct PingRequest { struct PingRequest {
// Time when the request was sent // Time when the request was sent
sent_at: Instant, sent_at: Instant,
@ -99,8 +108,10 @@ struct PingRequest {
// The hash Parity used to respond with (until rev 01f825b0e1f1c4c420197b51fc801cbe89284b29) // The hash Parity used to respond with (until rev 01f825b0e1f1c4c420197b51fc801cbe89284b29)
#[deprecated()] #[deprecated()]
deprecated_echo_hash: H256, deprecated_echo_hash: H256,
reason: PingReason
} }
#[derive(Debug)]
pub struct NodeBucket { pub struct NodeBucket {
nodes: VecDeque<BucketEntry>, //sorted by last active nodes: VecDeque<BucketEntry>, //sorted by last active
} }
@ -178,7 +189,7 @@ impl<'a> Discovery<'a> {
if self.node_buckets[dist].nodes.iter().any(|n| n.id_hash == id_hash) { if self.node_buckets[dist].nodes.iter().any(|n| n.id_hash == id_hash) {
return; return;
} }
self.try_ping(e); self.try_ping(e, PingReason::Default);
} }
} }
@ -221,7 +232,7 @@ impl<'a> Discovery<'a> {
} else { None } } else { None }
}; };
if let Some(node) = ping { if let Some(node) = ping {
self.try_ping(node); self.try_ping(node, PingReason::Default);
} }
Some(TableUpdates { added: added_map, removed: HashSet::new() }) Some(TableUpdates { added: added_map, removed: HashSet::new() })
} }
@ -244,7 +255,7 @@ impl<'a> Discovery<'a> {
fn update_new_nodes(&mut self) { fn update_new_nodes(&mut self) {
while self.in_flight_pings.len() < MAX_NODES_PING { while self.in_flight_pings.len() < MAX_NODES_PING {
match self.adding_nodes.pop() { match self.adding_nodes.pop() {
Some(next) => self.try_ping(next), Some(next) => self.try_ping(next, PingReason::Default),
None => break, None => break,
} }
} }
@ -298,7 +309,7 @@ impl<'a> Discovery<'a> {
None // a and b are equal, so log distance is -inf None // a and b are equal, so log distance is -inf
} }
fn try_ping(&mut self, node: NodeEntry) { fn try_ping(&mut self, node: NodeEntry, reason: PingReason) {
if !self.is_allowed(&node) { if !self.is_allowed(&node) {
trace!(target: "discovery", "Node {:?} not allowed", node); trace!(target: "discovery", "Node {:?} not allowed", node);
return; return;
@ -313,7 +324,7 @@ impl<'a> Discovery<'a> {
} }
if self.in_flight_pings.len() < MAX_NODES_PING { if self.in_flight_pings.len() < MAX_NODES_PING {
self.ping(&node) self.ping(&node, reason)
.unwrap_or_else(|e| { .unwrap_or_else(|e| {
warn!(target: "discovery", "Error sending Ping packet: {:?}", e); warn!(target: "discovery", "Error sending Ping packet: {:?}", e);
}); });
@ -322,7 +333,7 @@ impl<'a> Discovery<'a> {
} }
} }
fn ping(&mut self, node: &NodeEntry) -> Result<(), Error> { fn ping(&mut self, node: &NodeEntry, reason: PingReason) -> Result<(), Error> {
let mut rlp = RlpStream::new_list(4); let mut rlp = RlpStream::new_list(4);
rlp.append(&PROTOCOL_VERSION); rlp.append(&PROTOCOL_VERSION);
self.public_endpoint.to_rlp_list(&mut rlp); self.public_endpoint.to_rlp_list(&mut rlp);
@ -336,6 +347,7 @@ impl<'a> Discovery<'a> {
node: node.clone(), node: node.clone(),
echo_hash: hash, echo_hash: hash,
deprecated_echo_hash: old_parity_hash, deprecated_echo_hash: old_parity_hash,
reason: reason
}); });
trace!(target: "discovery", "Sent Ping to {:?} ; node_id={:#x}", &node.endpoint, node.id); trace!(target: "discovery", "Sent Ping to {:?} ; node_id={:#x}", &node.endpoint, node.id);
@ -515,7 +527,7 @@ impl<'a> Discovery<'a> {
if request.deprecated_echo_hash == echo_hash { if request.deprecated_echo_hash == echo_hash {
trace!(target: "discovery", "Got Pong from an old parity-ethereum version."); trace!(target: "discovery", "Got Pong from an old parity-ethereum version.");
} }
Some(request.node.clone()) Some((request.node.clone(), request.reason.clone()))
} }
}; };
@ -529,7 +541,10 @@ impl<'a> Discovery<'a> {
}, },
}; };
if let Some(node) = expected_node { if let Some((node, ping_reason)) = expected_node {
if let PingReason::FromDiscoveryRequest(target) = ping_reason {
self.respond_with_discovery(target, &node)?;
}
Ok(self.update_node(node)) Ok(self.update_node(node))
} else { } else {
debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from); debug!(target: "discovery", "Got unexpected Pong from {:?} ; request not found", &from);
@ -537,21 +552,59 @@ impl<'a> Discovery<'a> {
} }
} }
fn on_find_node(&mut self, rlp: &Rlp, _node: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, Error> { fn on_find_node(&mut self, rlp: &Rlp, node_id: &NodeId, from: &SocketAddr) -> Result<Option<TableUpdates>, Error> {
trace!(target: "discovery", "Got FindNode from {:?}", &from); trace!(target: "discovery", "Got FindNode from {:?}", &from);
let target: NodeId = rlp.val_at(0)?; let target: NodeId = rlp.val_at(0)?;
let timestamp: u64 = rlp.val_at(1)?; let timestamp: u64 = rlp.val_at(1)?;
self.check_timestamp(timestamp)?; self.check_timestamp(timestamp)?;
let node = NodeEntry {
id: node_id.clone(),
endpoint: NodeEndpoint {
address: *from,
udp_port: from.port()
}
};
if self.is_a_valid_known_node(&node) {
self.respond_with_discovery(target, &node)?;
} else {
// Make sure the request source is actually there and responds to pings before actually responding
self.try_ping(node, PingReason::FromDiscoveryRequest(target));
}
Ok(None)
}
fn is_a_valid_known_node(&self, node: &NodeEntry) -> bool {
let id_hash = keccak(node.id);
let dist = match Discovery::distance(&self.id_hash, &id_hash) {
Some(dist) => dist,
None => {
debug!(target: "discovery", "Got an incoming discovery request from self: {:?}", node);
return false;
}
};
let bucket = &self.node_buckets[dist];
if let Some(known_node) = bucket.nodes.iter().find(|n| n.address.id == node.id) {
debug!(target: "discovery", "Found a known node in a bucket when processing discovery: {:?}/{:?}", known_node, node);
(known_node.address.endpoint == node.endpoint) && (known_node.last_seen.elapsed() < NODE_LAST_SEEN_TIMEOUT)
} else {
false
}
}
fn respond_with_discovery(&mut self, target: NodeId, node: &NodeEntry) -> Result<(), Error> {
let nearest = self.nearest_node_entries(&target); let nearest = self.nearest_node_entries(&target);
if nearest.is_empty() { if nearest.is_empty() {
return Ok(None); return Ok(());
} }
let mut packets = Discovery::prepare_neighbours_packets(&nearest); let mut packets = Discovery::prepare_neighbours_packets(&nearest);
for p in packets.drain(..) { for p in packets.drain(..) {
self.send_packet(PACKET_NEIGHBOURS, from, &p)?; self.send_packet(PACKET_NEIGHBOURS, &node.endpoint.address, &p)?;
} }
trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &from); trace!(target: "discovery", "Sent {} Neighbours to {:?}", nearest.len(), &node.endpoint);
Ok(None) Ok(())
} }
fn prepare_neighbours_packets(nearest: &[NodeEntry]) -> Vec<Bytes> { fn prepare_neighbours_packets(nearest: &[NodeEntry]) -> Vec<Bytes> {
@ -827,7 +880,7 @@ mod tests {
} }
// After 4 discovery rounds, the first one should have learned about the rest. // After 4 discovery rounds, the first one should have learned about the rest.
for _round in 0 .. 4 { for _round in 0 .. 5 {
discovery_handlers[0].round(); discovery_handlers[0].round();
let mut continue_loop = true; let mut continue_loop = true;
@ -835,9 +888,9 @@ mod tests {
continue_loop = false; continue_loop = false;
// Process all queued messages. // Process all queued messages.
for i in 0 .. 5 { for i in 0 .. 20 {
let src = discovery_handlers[i].public_endpoint.address.clone(); let src = discovery_handlers[i%5].public_endpoint.address.clone();
while let Some(datagram) = discovery_handlers[i].dequeue_send() { while let Some(datagram) = discovery_handlers[i%5].dequeue_send() {
let dest = discovery_handlers.iter_mut() let dest = discovery_handlers.iter_mut()
.find(|disc| datagram.address == disc.public_endpoint.address) .find(|disc| datagram.address == disc.public_endpoint.address)
.unwrap(); .unwrap();
@ -929,14 +982,14 @@ mod tests {
let mut discovery = Discovery { request_backoff: &request_backoff, ..discovery }; let mut discovery = Discovery { request_backoff: &request_backoff, ..discovery };
for _ in 0..2 { for _ in 0..2 {
discovery.ping(&node_entries[101]).unwrap(); discovery.ping(&node_entries[101], PingReason::Default).unwrap();
let num_nodes = total_bucket_nodes(&discovery.node_buckets); let num_nodes = total_bucket_nodes(&discovery.node_buckets);
discovery.check_expired(Instant::now() + PING_TIMEOUT); discovery.check_expired(Instant::now() + PING_TIMEOUT);
let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets); let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets);
assert_eq!(removed, 0); assert_eq!(removed, 0);
} }
discovery.ping(&node_entries[101]).unwrap(); discovery.ping(&node_entries[101], PingReason::Default).unwrap();
let num_nodes = total_bucket_nodes(&discovery.node_buckets); let num_nodes = total_bucket_nodes(&discovery.node_buckets);
discovery.check_expired(Instant::now() + PING_TIMEOUT); discovery.check_expired(Instant::now() + PING_TIMEOUT);
let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets); let removed = num_nodes - total_bucket_nodes(&discovery.node_buckets);
@ -1123,7 +1176,7 @@ mod tests {
let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default()); let mut discovery1 = Discovery::new(&key1, ep1.clone(), IpFilter::default());
let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default()); let mut discovery2 = Discovery::new(&key2, ep2.clone(), IpFilter::default());
discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }).unwrap(); discovery1.ping(&NodeEntry { id: discovery2.id, endpoint: ep2.clone() }, PingReason::Default).unwrap();
let ping_data = discovery1.dequeue_send().unwrap(); let ping_data = discovery1.dequeue_send().unwrap();
assert!(!discovery1.any_sends_queued()); assert!(!discovery1.any_sends_queued());
let data = &ping_data.payload[(32 + 65)..]; let data = &ping_data.payload[(32 + 65)..];

View File

@ -308,7 +308,15 @@ pub fn select_public_address(port: u16) -> SocketAddr {
pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> { pub fn map_external_address(local: &NodeEndpoint) -> Option<NodeEndpoint> {
if let SocketAddr::V4(ref local_addr) = local.address { if let SocketAddr::V4(ref local_addr) = local.address {
match search_gateway_from_timeout(*local_addr.ip(), Duration::new(5, 0)) { let local_ip = *local_addr.ip();
let search_gateway_child = ::std::thread::spawn(move || {
search_gateway_from_timeout(local_ip, Duration::new(5, 0))
});
let gateway_result = match search_gateway_child.join() {
Err(_) => return None,
Ok(gateway_result) => gateway_result,
};
match gateway_result {
Err(ref err) => debug!("Gateway search error: {}", err), Err(ref err) => debug!("Gateway search error: {}", err),
Ok(gateway) => { Ok(gateway) => {
match gateway.get_external_ip() { match gateway.get_external_ip() {

View File

@ -3,22 +3,22 @@
[package] [package]
name = "parity-version" name = "parity-version"
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION) # NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
version = "2.2.6" version = "2.2.7"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs" build = "build.rs"
[package.metadata] [package.metadata]
# This versions track. Should be changed to `stable` or `beta` when on respective branches. # This versions track. Should be changed to `stable` or `beta` when on respective branches.
# Used by auto-updater and for Parity version string. # Used by auto-updater and for Parity version string.
track = "beta" track = "stable"
# Network specific settings, used ONLY by auto-updater. # Network specific settings, used ONLY by auto-updater.
# Latest supported fork blocks. # Latest supported fork blocks.
# Indicates a critical release in this track (i.e. consensus issue). # Indicates a critical release in this track (i.e. consensus issue).
[package.metadata.networks] [package.metadata.networks]
foundation = { forkBlock = 4370000, critical = false } foundation = { forkBlock = 4370000, critical = true }
ropsten = { forkBlock = 4230000, critical = false } ropsten = { forkBlock = 4230000, critical = false }
kovan = { forkBlock = 6600000, critical = true } kovan = { forkBlock = 9200000, critical = true }
[dependencies] [dependencies]
parity-bytes = "0.1" parity-bytes = "0.1"