Replace PeerServices(u64) with a bitflags struct.
This gives considerably better ergonomics.
This commit is contained in:
parent
9603a29399
commit
f5dca597dd
|
@ -7,6 +7,7 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.2"
|
||||
bytes = "0.4"
|
||||
rand = "0.7"
|
||||
byteorder = "1.3"
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
extern crate failure;
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
||||
mod network;
|
||||
pub use network::Network;
|
||||
|
|
|
@ -31,7 +31,7 @@ pub struct MetaAddr {
|
|||
impl ZcashSerialize for MetaAddr {
|
||||
fn zcash_serialize<W: Write>(&self, mut writer: W) -> Result<(), SerializationError> {
|
||||
writer.write_u32::<LittleEndian>(self.last_seen.timestamp() as u32)?;
|
||||
writer.write_u64::<LittleEndian>(self.services.0)?;
|
||||
writer.write_u64::<LittleEndian>(self.services.bits())?;
|
||||
writer.write_socket_addr(self.addr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ impl ZcashDeserialize for MetaAddr {
|
|||
fn zcash_deserialize<R: Read>(mut reader: R) -> Result<Self, SerializationError> {
|
||||
Ok(MetaAddr {
|
||||
last_seen: Utc.timestamp(reader.read_u32::<LittleEndian>()? as i64, 0),
|
||||
services: PeerServices(reader.read_u64::<LittleEndian>()?),
|
||||
// Discard unknown service bits.
|
||||
services: PeerServices::from_bits_truncate(reader.read_u64::<LittleEndian>()?),
|
||||
addr: reader.read_socket_addr()?,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -174,15 +174,15 @@ impl Codec {
|
|||
ref relay,
|
||||
} => {
|
||||
writer.write_u32::<LittleEndian>(version.0)?;
|
||||
writer.write_u64::<LittleEndian>(services.0)?;
|
||||
writer.write_u64::<LittleEndian>(services.bits())?;
|
||||
writer.write_i64::<LittleEndian>(timestamp.timestamp())?;
|
||||
|
||||
let (recv_services, recv_addr) = address_recv;
|
||||
writer.write_u64::<LittleEndian>(recv_services.0)?;
|
||||
writer.write_u64::<LittleEndian>(recv_services.bits())?;
|
||||
writer.write_socket_addr(*recv_addr)?;
|
||||
|
||||
let (from_services, from_addr) = address_from;
|
||||
writer.write_u64::<LittleEndian>(from_services.0)?;
|
||||
writer.write_u64::<LittleEndian>(from_services.bits())?;
|
||||
writer.write_socket_addr(*from_addr)?;
|
||||
|
||||
writer.write_u64::<LittleEndian>(nonce.0)?;
|
||||
|
@ -341,14 +341,15 @@ impl Codec {
|
|||
fn read_version<R: Read>(&self, mut reader: R) -> Result<Message, Error> {
|
||||
Ok(Message::Version {
|
||||
version: Version(reader.read_u32::<LittleEndian>()?),
|
||||
services: PeerServices(reader.read_u64::<LittleEndian>()?),
|
||||
// Use from_bits_truncate to discard unknown service bits.
|
||||
services: PeerServices::from_bits_truncate(reader.read_u64::<LittleEndian>()?),
|
||||
timestamp: Utc.timestamp(reader.read_i64::<LittleEndian>()?, 0),
|
||||
address_recv: (
|
||||
PeerServices(reader.read_u64::<LittleEndian>()?),
|
||||
PeerServices::from_bits_truncate(reader.read_u64::<LittleEndian>()?),
|
||||
reader.read_socket_addr()?,
|
||||
),
|
||||
address_from: (
|
||||
PeerServices(reader.read_u64::<LittleEndian>()?),
|
||||
PeerServices::from_bits_truncate(reader.read_u64::<LittleEndian>()?),
|
||||
reader.read_socket_addr()?,
|
||||
),
|
||||
nonce: Nonce(reader.read_u64::<LittleEndian>()?),
|
||||
|
@ -505,7 +506,7 @@ mod tests {
|
|||
#[test]
|
||||
fn version_message_round_trip() {
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
let services = PeerServices(0x1);
|
||||
let services = PeerServices::NODE_NETWORK;
|
||||
let timestamp = Utc.timestamp(1568000000, 0);
|
||||
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
|
|
@ -8,11 +8,21 @@ pub struct Magic(pub [u8; 4]);
|
|||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Version(pub u32);
|
||||
|
||||
/// Bitfield of features to be enabled for this connection.
|
||||
// Tower provides utilities for service discovery, so this might go
|
||||
// away in the future in favor of that.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct PeerServices(pub u64);
|
||||
bitflags! {
|
||||
/// A bitflag describing services advertised by a node in the network.
|
||||
///
|
||||
/// Note that bits 24-31 are reserved for temporary experiments; other
|
||||
/// service bits should be allocated via the ZIP process.
|
||||
#[derive(Default)]
|
||||
pub struct PeerServices: u64 {
|
||||
/// NODE_NETWORK means that the node is a full node capable of serving
|
||||
/// blocks, as opposed to a light client that makes network requests but
|
||||
/// does not provide network services.
|
||||
const NODE_NETWORK = (1 << 0);
|
||||
/// NODE_BLOOM means that the node supports bloom-filtered connections.
|
||||
const NODE_BLOOM = (1 << 2);
|
||||
}
|
||||
}
|
||||
|
||||
/// A nonce used in the networking layer to identify messages.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
|
|
|
@ -70,13 +70,16 @@ impl ConnectCmd {
|
|||
|
||||
let version = Message::Version {
|
||||
version: constants::CURRENT_VERSION,
|
||||
services: PeerServices(1),
|
||||
services: PeerServices::NODE_NETWORK,
|
||||
timestamp: Utc::now(),
|
||||
address_recv: (PeerServices(1), self.addr),
|
||||
address_recv: (PeerServices::NODE_NETWORK, self.addr),
|
||||
// We just make something up because at this stage the `connect` command
|
||||
// doesn't run a server or anything -- will the zcashd respond on the
|
||||
// same tcp connection or try to open one to the bogus address below?
|
||||
address_from: (PeerServices(1), "127.0.0.1:9000".parse().unwrap()),
|
||||
address_from: (
|
||||
PeerServices::NODE_NETWORK,
|
||||
"127.0.0.1:9000".parse().unwrap(),
|
||||
),
|
||||
nonce: Nonce(1),
|
||||
user_agent: "Zebra Connect".to_owned(),
|
||||
start_height: BlockHeight(0),
|
||||
|
|
Loading…
Reference in New Issue