Upgrade ethereum types (#10670)

* cargo upgrade "ethereum-types" --all --allow-prerelease

* [ethash] fix compilation errors

* [ethkey] fix compilation errors

* [journaldb] fix compilation errors

* [dir] fix compilation errors

* [ethabi] update to 0.7

* wip

* [eip-712] fix compilation errors

* [ethjson] fix compilation errors

* [Cargo.toml] add TODO to remove patches

* [ethstore] fix compilation errors

* use patched keccak-hash with new primitive-types

* wip

* [ethcore-network-devp2p] fix compilation errors

* [vm] fix compilation errors

* [common-types, evm, wasm] fix compilation errors

* [ethcore-db] Require AsRef instead of Deref for keys

* [ethcore-blockchain] fix some compilation errors

* [blooms-db] fix compilation errors

Thanks a lot @dvdplm :)

* we don't need no rlp ethereum feature

* [ethcore] fix some compilation errors

* [parity-ipfs-api] fix compilation error

* [ethcore-light] fix compilation errors

* [Cargo.lock] update parity-common

* [ethcore-private-tx] fix some compilation errors

* wip

* [ethcore-private-tx] fix compilation errors

* [parity-updater] fix compilation errors

* [parity-rpc] fix compilation errors

* [parity-bin] fix other compilation errors

* update to new ethereum-types

* update keccak-hash

* [fastmap] fix compilation in tests

* [blooms-db] fix compilation in tests

* [common-types] fix compilation in tests

* [triehash-ethereum] fix compilation in tests

* [ethkey] fix compilation in tests

* [pwasm-run-test] fix compilation errors

* [wasm] fix compilation errors

* [ethjson] fix compilation in tests

* [eip-712] fix compilation in tests

* [ethcore-blockchain] fix compilation in tests

* [ethstore] fix compilation in tests

* [ethstore-accounts] fix compilation in tests

* [parity-hash-fetch] fix compilation in tests

* [parity-whisper] fix compilation in tests

* [ethcore-miner] fix compilation in tests

* [ethcore-network-devp2p] fix compilation in tests

* [*] upgrade rand to 0.6

* [evm] get rid of num-bigint conversions

* [ethcore] downgrade trie-standardmap and criterion

* [ethcore] fix some warnings

* [ethcore] fix compilation in tests

* [evmbin] fix compilation in tests

* [updater] fix compilation in tests

* [ethash] fix compilation in tests

* [ethcore-secretstore] fix compilation in tests

* [ethcore-sync] fix compilation in tests

* [parity-rpc] fix compilation in tests

* [ethcore] finally fix compilation in tests

FUCK YEAH!!!

* [ethstore] lazy_static is unused

* [ethcore] fix test

* fix up bad merge

* [Cargo.toml] remove unused patches

* [*] replace some git dependencies with crates.io

* [Cargo.toml] remove unused lazy_static

* [*] clean up

* [ethcore] fix transaction_filter_deprecated test

* [private-tx] fix serialization tests

* fix more serialization tests

* [ethkey] fix smoky test

* [rpc] fix tests, please?

* [ethcore] remove commented out code

* Apply suggestions from code review

Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* [ethstore] remove unused dev-dependency

* [ethcore] remove resolved TODO

* [*] resolve keccak-hash TODO

* [*] s/Address::default()/Address::zero()

* [rpc] remove Subscribers::new_test

* [rpc] remove EthPubSubClient::new_test

* [ethcore] use trie-standardmap from crates.io

* [dir] fix db_root_path

* [ethcore] simplify snapshot::tests::helpers::fill_storage

* Apply suggestions from code review

Co-Authored-By: David <dvdplm@gmail.com>

* [ethcore-secretstore] resolve TODO in serialization

* [ethcore-network-devp2p] resolve TODO in save_key

* [Cargo.lock] update triehash

* [*] use ethabi from crates.io

* [ethkey] use secp256k1 from master branch

* [Cargo.lock] update eth-secp256k1
This commit is contained in:
Andronik Ordian
2019-06-03 15:36:21 +02:00
committed by David
parent 33d3bfae8b
commit dae5d75dd6
274 changed files with 2718 additions and 2275 deletions

View File

@@ -298,37 +298,40 @@ impl EncryptedConnection {
/// Create an encrypted connection out of the handshake.
pub fn new(handshake: &mut Handshake) -> Result<EncryptedConnection, Error> {
let shared = crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_ephemeral)?;
let mut nonce_material = H512::new();
let mut nonce_material = H512::default();
if handshake.originated {
handshake.remote_nonce.copy_to(&mut nonce_material[0..32]);
handshake.nonce.copy_to(&mut nonce_material[32..64]);
(&mut nonce_material[0..32]).copy_from_slice(handshake.remote_nonce.as_bytes());
(&mut nonce_material[32..64]).copy_from_slice(handshake.nonce.as_bytes());
}
else {
handshake.nonce.copy_to(&mut nonce_material[0..32]);
handshake.remote_nonce.copy_to(&mut nonce_material[32..64]);
(&mut nonce_material[0..32]).copy_from_slice(handshake.nonce.as_bytes());
(&mut nonce_material[32..64]).copy_from_slice(handshake.remote_nonce.as_bytes());
}
let mut key_material = H512::new();
shared.copy_to(&mut key_material[0..32]);
let mut key_material = H512::default();
(&mut key_material[0..32]).copy_from_slice(shared.as_bytes());
write_keccak(&nonce_material, &mut key_material[32..64]);
keccak(&key_material).copy_to(&mut key_material[32..64]);
keccak(&key_material).copy_to(&mut key_material[32..64]);
let key_material_keccak = keccak(&key_material);
(&mut key_material[32..64]).copy_from_slice(key_material_keccak.as_bytes());
let key_material_keccak = keccak(&key_material);
(&mut key_material[32..64]).copy_from_slice(key_material_keccak.as_bytes());
let iv = vec![0u8; 16];
let encoder = CtrMode::new(AesSafe256Encryptor::new(&key_material[32..64]), iv);
let iv = vec![0u8; 16];
let decoder = CtrMode::new(AesSafe256Encryptor::new(&key_material[32..64]), iv);
keccak(&key_material).copy_to(&mut key_material[32..64]);
let key_material_keccak = keccak(&key_material);
(&mut key_material[32..64]).copy_from_slice(key_material_keccak.as_bytes());
let mac_encoder = EcbEncryptor::new(AesSafe256Encryptor::new(&key_material[32..64]), NoPadding);
let mut egress_mac = Keccak::new_keccak256();
let mut mac_material = H256::from_slice(&key_material[32..64]) ^ handshake.remote_nonce;
egress_mac.update(&mac_material);
egress_mac.update(mac_material.as_bytes());
egress_mac.update(if handshake.originated { &handshake.auth_cipher } else { &handshake.ack_cipher });
let mut ingress_mac = Keccak::new_keccak256();
mac_material = H256::from_slice(&key_material[32..64]) ^ handshake.nonce;
ingress_mac.update(&mac_material);
ingress_mac.update(mac_material.as_bytes());
ingress_mac.update(if handshake.originated { &handshake.ack_cipher } else { &handshake.auth_cipher });
let old_connection = handshake.connection.try_clone()?;
@@ -385,14 +388,18 @@ impl EncryptedConnection {
}
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]);
let mac = &header[16..];
let mut expected = H256::new();
self.ingress_mac.clone().finalize(&mut expected);
let mut expected = H256::zero();
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
if mac != &expected[0..16] {
return Err(ErrorKind::Auth.into());
}
let mut hdec = H128::new();
self.decoder.decrypt(&mut RefReadBuffer::new(&header[0..16]), &mut RefWriteBuffer::new(&mut hdec), false).expect("Invalid length or padding");
let mut hdec = H128::default();
self.decoder.decrypt(
&mut RefReadBuffer::new(&header[0..16]),
&mut RefWriteBuffer::new(hdec.as_bytes_mut()),
false,
).expect("Invalid length or padding");
let length = ((((hdec[0] as u32) << 8) + (hdec[1] as u32)) << 8) + (hdec[2] as u32);
let header_rlp = Rlp::new(&hdec[3..6]);
@@ -418,8 +425,8 @@ impl EncryptedConnection {
self.ingress_mac.update(&payload[0..payload.len() - 16]);
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]);
let mac = &payload[(payload.len() - 16)..];
let mut expected = H128::new();
self.ingress_mac.clone().finalize(&mut expected);
let mut expected = H128::default();
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
if mac != &expected[..] {
return Err(ErrorKind::Auth.into());
}
@@ -436,14 +443,18 @@ impl EncryptedConnection {
/// Update MAC after reading or writing any data.
fn update_mac(mac: &mut Keccak, mac_encoder: &mut EcbEncryptor<AesSafe256Encryptor, EncPadding<NoPadding>>, seed: &[u8]) {
let mut prev = H128::new();
mac.clone().finalize(&mut prev);
let mut enc = H128::new();
mac_encoder.encrypt(&mut RefReadBuffer::new(&prev), &mut RefWriteBuffer::new(&mut enc), true).expect("Error updating MAC");
let mut prev = H128::default();
mac.clone().finalize(prev.as_bytes_mut());
let mut enc = H128::default();
mac_encoder.encrypt(
&mut RefReadBuffer::new(prev.as_bytes()),
&mut RefWriteBuffer::new(enc.as_bytes_mut()),
true
).expect("Error updating MAC");
mac_encoder.reset();
enc = enc ^ if seed.is_empty() { prev } else { H128::from_slice(seed) };
mac.update(&enc);
mac.update(enc.as_bytes());
}
/// Readable IO handler. Tracker receive status and returns decoded packet if available.
@@ -486,14 +497,14 @@ pub fn test_encryption() {
let after = H128::from_str("89464c6b04e7c99e555c81d3f7266a05").unwrap();
let after2 = H128::from_str("85c070030589ef9c7a2879b3a8489316").unwrap();
let mut got = H128::new();
let mut got = H128::zero();
let mut encoder = EcbEncryptor::new(AesSafe256Encryptor::new(&key), NoPadding);
encoder.encrypt(&mut RefReadBuffer::new(&before), &mut RefWriteBuffer::new(&mut got), true).unwrap();
let mut encoder = EcbEncryptor::new(AesSafe256Encryptor::new(key.as_bytes()), NoPadding);
encoder.encrypt(&mut RefReadBuffer::new(before.as_bytes()), &mut RefWriteBuffer::new(got.as_bytes_mut()), true).unwrap();
encoder.reset();
assert_eq!(got, after);
got = H128::new();
encoder.encrypt(&mut RefReadBuffer::new(&before2), &mut RefWriteBuffer::new(&mut got), true).unwrap();
got = H128::zero();
encoder.encrypt(&mut RefReadBuffer::new(before2.as_bytes()), &mut RefWriteBuffer::new(got.as_bytes_mut()), true).unwrap();
encoder.reset();
assert_eq!(got, after2);
}

View File

@@ -197,7 +197,7 @@ impl<'a> Discovery<'a> {
public_endpoint: public,
discovery_initiated: false,
discovery_round: None,
discovery_id: NodeId::new(),
discovery_id: NodeId::default(),
discovery_nodes: HashSet::new(),
node_buckets: (0..ADDRESS_BITS).map(|_| NodeBucket::new()).collect(),
other_observed_nodes: LruCache::new(OBSERVED_NODES_MAX_SIZE),
@@ -414,7 +414,7 @@ impl<'a> Discovery<'a> {
fn send_packet(&mut self, packet_id: u8, address: &SocketAddr, payload: &[u8]) -> Result<H256, Error> {
let packet = assemble_packet(packet_id, payload, &self.secret)?;
let hash = H256::from(&packet[0..32]);
let hash = H256::from_slice(&packet[0..32]);
self.send_to(packet, address.clone());
Ok(hash)
}
@@ -491,7 +491,7 @@ impl<'a> Discovery<'a> {
let packet_id = signed[0];
let rlp = Rlp::new(&signed[1..]);
match packet_id {
PACKET_PING => self.on_ping(&rlp, &node_id, &from, &hash_signed),
PACKET_PING => self.on_ping(&rlp, &node_id, &from, hash_signed.as_bytes()),
PACKET_PONG => self.on_pong(&rlp, &node_id, &from),
PACKET_FIND_NODE => self.on_find_node(&rlp, &node_id, &from),
PACKET_NEIGHBOURS => self.on_neighbours(&rlp, &node_id, &from),
@@ -860,7 +860,7 @@ fn assemble_packet(packet_id: u8, bytes: &[u8], secret: &Secret) -> Result<Bytes
};
packet[32..(32 + 65)].copy_from_slice(&signature[..]);
let signed_hash = keccak(&packet[32..]);
packet[0..32].copy_from_slice(&signed_hash);
packet[0..32].copy_from_slice(signed_hash.as_bytes());
Ok(packet)
}
@@ -970,7 +970,7 @@ mod tests {
}
}
let results = discovery_handlers[0].nearest_node_entries(&NodeId::new());
let results = discovery_handlers[0].nearest_node_entries(&NodeId::zero());
assert_eq!(results.len(), 4);
}
@@ -1073,10 +1073,10 @@ mod tests {
let mut discovery = Discovery::new(&key, ep.clone(), IpFilter::default());
for _ in 0..(16 + 10) {
let entry = BucketEntry::new(NodeEntry { id: NodeId::new(), endpoint: ep.clone() });
let entry = BucketEntry::new(NodeEntry { id: NodeId::zero(), endpoint: ep.clone() });
discovery.node_buckets[0].nodes.push_back(entry);
}
let nearest = discovery.nearest_node_entries(&NodeId::new());
let nearest = discovery.nearest_node_entries(&NodeId::zero());
assert_eq!(nearest.len(), 16)
}
@@ -1267,7 +1267,7 @@ mod tests {
// Create a pong packet with incorrect echo hash and assert that it is rejected.
let mut incorrect_pong_rlp = RlpStream::new_list(3);
ep1.to_rlp_list(&mut incorrect_pong_rlp);
incorrect_pong_rlp.append(&H256::default());
incorrect_pong_rlp.append(&H256::zero());
append_expiration(&mut incorrect_pong_rlp);
let incorrect_pong_data = assemble_packet(
PACKET_PONG, &incorrect_pong_rlp.drain(), &discovery2.secret
@@ -1296,7 +1296,7 @@ mod tests {
// Deliver an unexpected PONG message to discover1.
let mut unexpected_pong_rlp = RlpStream::new_list(3);
ep3.to_rlp_list(&mut unexpected_pong_rlp);
unexpected_pong_rlp.append(&H256::default());
unexpected_pong_rlp.append(&H256::zero());
append_expiration(&mut unexpected_pong_rlp);
let unexpected_pong = assemble_packet(
PACKET_PONG, &unexpected_pong_rlp.drain(), key3.secret()

View File

@@ -82,14 +82,14 @@ impl Handshake {
/// Create a new handshake object
pub fn new(token: StreamToken, id: Option<&NodeId>, socket: TcpStream, nonce: &H256) -> Result<Handshake, Error> {
Ok(Handshake {
id: if let Some(id) = id { *id } else { NodeId::new() },
id: if let Some(id) = id { *id } else { NodeId::default() },
connection: Connection::new(token, socket),
originated: false,
state: HandshakeState::New,
ecdhe: Random.generate()?,
nonce: *nonce,
remote_ephemeral: Public::new(),
remote_nonce: H256::new(),
remote_ephemeral: Public::default(),
remote_nonce: H256::zero(),
remote_version: PROTOCOL_VERSION,
auth_cipher: Bytes::new(),
ack_cipher: Bytes::new(),
@@ -149,8 +149,9 @@ impl Handshake {
}
fn set_auth(&mut self, host_secret: &Secret, sig: &[u8], remote_public: &[u8], remote_nonce: &[u8], remote_version: u64) -> Result<(), Error> {
self.id.clone_from_slice(remote_public);
self.remote_nonce.clone_from_slice(remote_nonce);
// TODO: assign_from_slice will panic if sizes differ
self.id.assign_from_slice(remote_public);
self.remote_nonce.assign_from_slice(remote_nonce);
self.remote_version = remote_version;
let shared = *ecdh::agree(host_secret, &self.id)?;
let signature = H520::from_slice(sig);
@@ -199,7 +200,7 @@ impl Handshake {
let remote_public: Public = rlp.val_at(1)?;
let remote_nonce: H256 = rlp.val_at(2)?;
let remote_version: u64 = rlp.val_at(3)?;
self.set_auth(secret, &signature, &remote_public, &remote_nonce, remote_version)?;
self.set_auth(secret, signature.as_bytes(), remote_public.as_bytes(), remote_nonce.as_bytes(), remote_version)?;
self.write_ack_eip8(io)?;
Ok(())
}
@@ -214,8 +215,8 @@ impl Handshake {
self.ack_cipher = data.to_vec();
match ecies::decrypt(secret, &[], data) {
Ok(ack) => {
self.remote_ephemeral.clone_from_slice(&ack[0..64]);
self.remote_nonce.clone_from_slice(&ack[64..(64+32)]);
self.remote_ephemeral.assign_from_slice(&ack[0..64]);
self.remote_nonce.assign_from_slice(&ack[64..(64+32)]);
self.state = HandshakeState::StartSession;
}
Err(_) => {
@@ -261,8 +262,8 @@ impl Handshake {
let shared = *ecdh::agree(secret, &self.id)?;
sig.copy_from_slice(&*sign(self.ecdhe.secret(), &(shared ^ self.nonce))?);
write_keccak(self.ecdhe.public(), hepubk);
pubk.copy_from_slice(public);
nonce.copy_from_slice(&self.nonce);
pubk.copy_from_slice(public.as_bytes());
nonce.copy_from_slice(self.nonce.as_bytes());
}
let message = ecies::encrypt(&self.id, &[], &data)?;
self.auth_cipher = message.clone();
@@ -281,8 +282,8 @@ impl Handshake {
data[len - 1] = 0x0;
let (epubk, rest) = data.split_at_mut(64);
let (nonce, _) = rest.split_at_mut(32);
self.ecdhe.public().copy_to(epubk);
self.nonce.copy_to(nonce);
epubk.copy_from_slice(self.ecdhe.public().as_bytes());
nonce.copy_from_slice(self.nonce.as_bytes());
}
let message = ecies::encrypt(&self.id, &[], &data)?;
self.ack_cipher = message.clone();
@@ -319,28 +320,38 @@ impl Handshake {
mod test {
use rustc_hex::FromHex;
use super::*;
use ethereum_types::H256;
use ethereum_types::{H256, H512};
use io::*;
use mio::tcp::TcpStream;
use ethkey::Public;
use std::str::FromStr;
fn check_auth(h: &Handshake, version: u64) {
assert_eq!(h.id, "fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877".into());
assert_eq!(h.remote_nonce, "7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6".into());
assert_eq!(h.remote_ephemeral, "654d1044b69c577a44e5f01a1209523adb4026e70c62d1c13a067acabc09d2667a49821a0ad4b634554d330a15a58fe61f8a8e0544b310c6de7b0c8da7528a8d".into());
assert_eq!(
h.id,
H512::from_str("fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877").unwrap(),
);
assert_eq!(h.remote_nonce, H256::from_str("7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6").unwrap());
assert_eq!(
h.remote_ephemeral,
H512::from_str("654d1044b69c577a44e5f01a1209523adb4026e70c62d1c13a067acabc09d2667a49821a0ad4b634554d330a15a58fe61f8a8e0544b310c6de7b0c8da7528a8d").unwrap(),
);
assert_eq!(h.remote_version, version);
}
fn check_ack(h: &Handshake, version: u64) {
assert_eq!(h.remote_nonce, "559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd".into());
assert_eq!(h.remote_ephemeral, "b6d82fa3409da933dbf9cb0140c5dde89f4e64aec88d476af648880f4a10e1e49fe35ef3e69e93dd300b4797765a747c6384a6ecf5db9c2690398607a86181e4".into());
assert_eq!(h.remote_nonce, H256::from_str("559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd").unwrap());
assert_eq!(
h.remote_ephemeral,
H512::from_str("b6d82fa3409da933dbf9cb0140c5dde89f4e64aec88d476af648880f4a10e1e49fe35ef3e69e93dd300b4797765a747c6384a6ecf5db9c2690398607a86181e4").unwrap(),
);
assert_eq!(h.remote_version, version);
}
fn create_handshake(to: Option<&Public>) -> Handshake {
let addr = "127.0.0.1:50556".parse().unwrap();
let socket = TcpStream::connect(&addr).unwrap();
let nonce = H256::new();
let nonce = H256::zero();
Handshake::new(0, to, socket, &nonce).unwrap()
}
@@ -427,7 +438,7 @@ mod test {
#[test]
fn test_handshake_ack_plain() {
let remote = "fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877".into();
let remote = H512::from_str("fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877").unwrap();
let mut h = create_handshake(Some(&remote));
let secret = "49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee".parse().unwrap();
let ack =
@@ -447,7 +458,7 @@ mod test {
#[test]
fn test_handshake_ack_eip8() {
let remote = "fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877".into();
let remote = H512::from_str("fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877").unwrap();
let mut h = create_handshake(Some(&remote));
let secret = "49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee".parse().unwrap();
let ack =
@@ -476,7 +487,7 @@ mod test {
#[test]
fn test_handshake_ack_eip8_2() {
let remote = "fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877".into();
let remote = H512::from_str("fda1cff674c90c9a197539fe3dfb53086ace64f83ed7c6eabec741f7f381cc803e52ab2cd55d5569bce4347107a310dfd5f88a010cd2ffd1005ca406f1842877").unwrap();
let mut h = create_handshake(Some(&remote));
let secret = "49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee".parse().unwrap();
let ack =

View File

@@ -33,6 +33,7 @@ use mio::tcp::*;
use mio::udp::*;
use ethereum_types::H256;
use rlp::{RlpStream, Encodable};
use rustc_hex::ToHex;
use session::{Session, SessionData};
use io::*;
@@ -1223,7 +1224,7 @@ fn save_key(path: &Path, key: &Secret) {
if let Err(e) = restrict_permissions_owner(path, true, false) {
warn!(target: "network", "Failed to modify permissions of the file ({})", e);
}
if let Err(e) = file.write(&key.hex().into_bytes()[2..]) {
if let Err(e) = file.write(&key.to_hex().into_bytes()) {
warn!("Error writing key file: {:?}", e);
}
}

View File

@@ -211,7 +211,7 @@ impl FromStr for Node {
(s[8..136].parse().map_err(|_| ErrorKind::InvalidNodeId)?, NodeEndpoint::from_str(&s[137..])?)
}
else {
(NodeId::new(), NodeEndpoint::from_str(s)?)
(NodeId::default(), NodeEndpoint::from_str(s)?)
};
Ok(Node {