2022-04-19 09:14:24 -07:00
//! Definitions of Zebra network constants, including:
//! - network protocol versions,
//! - network protocol user agents,
//! - peer address limits,
//! - peer connection limits, and
//! - peer connection timeouts.
2019-09-12 03:23:51 -07:00
2021-10-08 10:57:04 -07:00
use std ::{ collections ::HashMap , time ::Duration } ;
2019-10-11 12:41:37 -07:00
2021-01-29 04:36:33 -08:00
use lazy_static ::lazy_static ;
use regex ::Regex ;
2023-03-27 21:13:04 -07:00
// TODO: should these constants be split into protocol also?
2019-11-26 22:42:42 -08:00
use crate ::protocol ::external ::types ::* ;
2019-09-12 03:23:51 -07:00
2021-10-08 10:57:04 -07:00
use zebra_chain ::{
2022-04-19 09:14:24 -07:00
parameters ::{
Network ::{ self , * } ,
NetworkUpgrade ::* ,
} ,
2021-10-08 10:57:04 -07:00
serialization ::Duration32 ,
} ;
2020-07-21 01:41:18 -07:00
2022-02-14 08:00:31 -08:00
/// A multiplier used to calculate the inbound connection limit for the peer set,
2021-10-27 14:28:51 -07:00
///
2022-02-14 08:00:31 -08:00
/// When it starts up, Zebra opens [`Config.peerset_initial_target_size`]
/// outbound connections.
2021-10-27 14:28:51 -07:00
///
2022-02-14 08:00:31 -08:00
/// Then it opens additional outbound connections as needed for network requests,
/// and accepts inbound connections initiated by other peers.
///
/// The inbound and outbound connection limits are calculated from:
///
/// The inbound limit is:
/// `Config.peerset_initial_target_size * INBOUND_PEER_LIMIT_MULTIPLIER`.
/// (This is similar to `zcashd`'s default inbound limit.)
///
/// The outbound limit is:
/// `Config.peerset_initial_target_size * OUTBOUND_PEER_LIMIT_MULTIPLIER`.
/// (This is a bit larger than `zcashd`'s default outbound limit.)
2021-10-27 14:28:51 -07:00
///
/// # Security
///
2022-02-14 08:00:31 -08:00
/// Each connection requires one inbound slot and one outbound slot, on two different peers.
/// But some peers only make outbound connections, because they are behind a firewall,
/// or their lister port address is misconfigured.
///
/// Zebra allows extra inbound connection slots,
/// to prevent accidental connection slot exhaustion.
/// (`zcashd` also allows a large number of extra inbound slots.)
///
/// ## Security Tradeoff
///
/// Since the inbound peer limit is higher than the outbound peer limit,
/// Zebra can be connected to a majority of peers
2022-06-13 18:22:16 -07:00
/// that it has *not* chosen from its [`crate::AddressBook`].
2021-10-27 14:28:51 -07:00
///
/// Inbound peer connections are initiated by the remote peer,
/// so inbound peer selection is not controlled by the local node.
2022-02-14 08:00:31 -08:00
/// This means that an attacker can easily become a majority of a node's peers.
///
/// However, connection exhaustion is a higher priority.
pub const INBOUND_PEER_LIMIT_MULTIPLIER : usize = 5 ;
/// A multiplier used to calculate the outbound connection limit for the peer set,
///
/// See [`INBOUND_PEER_LIMIT_MULTIPLIER`] for details.
pub const OUTBOUND_PEER_LIMIT_MULTIPLIER : usize = 3 ;
2021-10-27 14:28:51 -07:00
2020-08-06 11:29:00 -07:00
/// The buffer size for the peer set.
2020-09-01 18:20:32 -07:00
///
2020-09-08 03:04:01 -07:00
/// This should be greater than 1 to avoid sender contention, but also reasonably
/// small, to avoid queueing too many in-flight block downloads. (A large queue
/// of in-flight block downloads can choke a constrained local network
/// connection, or a small peer set on testnet.)
///
2020-09-01 18:20:32 -07:00
/// We assume that Zebra nodes have at least 10 Mbps bandwidth. Therefore, a
2020-09-08 03:04:01 -07:00
/// maximum-sized block can take up to 2 seconds to download. So the peer set
/// buffer adds up to 6 seconds worth of blocks to the queue.
pub const PEERSET_BUFFER_SIZE : usize = 3 ;
2020-08-06 11:29:00 -07:00
2022-01-31 10:22:00 -08:00
/// The timeout for sending a message to a remote peer,
/// and receiving a response from a remote peer.
2020-09-01 18:20:32 -07:00
pub const REQUEST_TIMEOUT : Duration = Duration ::from_secs ( 20 ) ;
2019-10-10 17:54:15 -07:00
2020-08-06 11:29:00 -07:00
/// The timeout for handshakes when connecting to new peers.
2020-09-08 03:04:01 -07:00
///
/// This timeout should remain small, because it helps stop slow peers getting
/// into the peer set. This is particularly important for network-constrained
/// nodes, and on testnet.
2022-04-28 10:32:16 -07:00
pub const HANDSHAKE_TIMEOUT : Duration = Duration ::from_secs ( 3 ) ;
2020-08-06 11:29:00 -07:00
2019-10-11 12:41:37 -07:00
/// We expect to receive a message from a live peer at least once in this time duration.
2019-10-21 12:16:28 -07:00
///
/// This is the sum of:
/// - the interval between connection heartbeats
/// - the timeout of a possible pending (already-sent) request
/// - the timeout for a possible queued request
/// - the timeout for the heartbeat request itself
///
/// This avoids explicit synchronization, but relies on the peer
/// connector actually setting up channels and these heartbeats in a
/// specific manner that matches up with this math.
2021-12-19 15:02:31 -08:00
pub const MIN_PEER_RECONNECTION_DELAY : Duration = Duration ::from_secs ( 59 + 20 + 20 + 20 ) ;
2022-02-14 17:44:33 -08:00
/// Zebra rotates its peer inventory registry every time this interval elapses.
///
/// After 2 of these intervals, Zebra's local available and missing inventory entries expire.
pub const INVENTORY_ROTATION_INTERVAL : Duration = Duration ::from_secs ( 53 ) ;
2021-12-19 15:02:31 -08:00
/// The default peer address crawler interval.
///
2022-06-02 08:07:35 -07:00
/// This should be at least [`HANDSHAKE_TIMEOUT`] lower than all other crawler
/// intervals.
2021-12-19 15:02:31 -08:00
///
/// This makes the following sequence of events more likely:
/// 1. a peer address crawl,
/// 2. new peer connections,
/// 3. peer requests from other crawlers.
///
/// Using a prime number makes sure that peer address crawls
/// don't synchronise with other crawls.
pub const DEFAULT_CRAWL_NEW_PEER_INTERVAL : Duration = Duration ::from_secs ( 61 ) ;
2021-06-28 22:12:27 -07:00
/// The maximum duration since a peer was last seen to consider it reachable.
///
/// This is used to prevent Zebra from gossiping addresses that are likely unreachable. Peers that
/// have last been seen more than this duration ago will not be gossiped.
///
/// This is determined as a tradeoff between network health and network view leakage. From the
/// [Bitcoin protocol documentation](https://en.bitcoin.it/wiki/Protocol_documentation#getaddr):
///
/// "The typical presumption is that a node is likely to be active if it has been sending a message
/// within the last three hours."
pub const MAX_PEER_ACTIVE_FOR_GOSSIP : Duration32 = Duration32 ::from_hours ( 3 ) ;
2019-10-21 11:59:47 -07:00
2021-11-10 15:51:22 -08:00
/// The maximum duration since a peer was last seen to consider reconnecting to it.
///
/// Peers that haven't been seen for more than three days and that had its last connection attempt
/// fail are considered to be offline and Zebra will stop trying to connect to them.
///
/// This is to ensure that Zebra can't have a denial-of-service as a consequence of having too many
/// offline peers that it constantly and uselessly retries to connect to.
pub const MAX_RECENT_PEER_AGE : Duration32 = Duration32 ::from_days ( 3 ) ;
2019-10-21 11:59:47 -07:00
/// Regular interval for sending keepalive `Ping` messages to each
/// connected peer.
2021-12-19 15:02:31 -08:00
///
/// Using a prime number makes sure that heartbeats don't synchronise with crawls.
pub const HEARTBEAT_INTERVAL : Duration = Duration ::from_secs ( 59 ) ;
2019-10-11 12:41:37 -07:00
2023-04-18 01:13:19 -07:00
/// The minimum time between outbound peer connections, implemented by
2022-06-13 18:22:16 -07:00
/// [`CandidateSet::next`][crate::peer_set::CandidateSet::next].
2021-06-08 16:42:45 -07:00
///
/// ## Security
///
2023-04-18 01:13:19 -07:00
/// Zebra resists distributed denial of service attacks by making sure that new outbound peer
/// connections are only initiated after this minimum time has elapsed.
///
/// It also enforces a minimum per-peer reconnection interval, and filters failed outbound peers.
pub const MIN_OUTBOUND_PEER_CONNECTION_INTERVAL : Duration = Duration ::from_millis ( 50 ) ;
/// The minimum time between _successful_ inbound peer connections, implemented by
/// `peer_set::initialize::accept_inbound_connections`.
///
/// To support multiple peers connecting simultaneously, this is less than the
/// [`HANDSHAKE_TIMEOUT`].
///
/// ## Security
///
/// Zebra resists distributed denial of service attacks by limiting the inbound connection rate.
/// After a _successful_ inbound connection, new inbound peer connections are only accepted,
/// and our side of the handshake initiated, after this minimum time has elapsed.
///
/// The inbound interval is much longer than the outbound interval, because Zebra does not
/// control the selection or reconnections of inbound peers.
pub const MIN_INBOUND_PEER_CONNECTION_INTERVAL : Duration = Duration ::from_secs ( 1 ) ;
/// The minimum time between _failed_ inbound peer connections, implemented by
/// `peer_set::initialize::accept_inbound_connections`.
///
/// This is a tradeoff between:
/// - the memory, CPU, and network usage of each new connection attempt, and
/// - denying service to honest peers due to an attack which makes many inbound connections.
///
/// Attacks that reach this limit should be managed using a firewall or intrusion prevention system.
///
/// ## Security
///
/// Zebra resists distributed denial of service attacks by limiting the inbound connection rate.
/// After a _failed_ inbound connection, new inbound peer connections are only accepted,
/// and our side of the handshake initiated, after this minimum time has elapsed.
pub const MIN_INBOUND_PEER_FAILED_CONNECTION_INTERVAL : Duration = Duration ::from_millis ( 10 ) ;
2021-06-08 16:42:45 -07:00
2022-06-13 18:22:16 -07:00
/// The minimum time between successive calls to
/// [`CandidateSet::update`][crate::peer_set::CandidateSet::update].
2021-06-08 16:42:45 -07:00
///
2021-12-19 15:02:31 -08:00
/// Using a prime number makes sure that peer address crawls don't synchronise with other crawls.
///
2021-06-08 16:42:45 -07:00
/// ## Security
///
/// Zebra resists distributed denial of service attacks by making sure that requests for more
2022-06-13 18:22:16 -07:00
/// peer addresses are sent at least [`MIN_PEER_GET_ADDR_INTERVAL`] apart.
2021-12-19 15:02:31 -08:00
pub const MIN_PEER_GET_ADDR_INTERVAL : Duration = Duration ::from_secs ( 31 ) ;
2021-11-30 13:04:32 -08:00
2022-06-13 18:22:16 -07:00
/// The combined timeout for all the requests in
/// [`CandidateSet::update`][crate::peer_set::CandidateSet::update].
2021-11-30 13:04:32 -08:00
///
/// `zcashd` doesn't respond to most `getaddr` requests,
/// so this timeout needs to be short.
pub const PEER_GET_ADDR_TIMEOUT : Duration = Duration ::from_secs ( 8 ) ;
2021-06-08 16:42:45 -07:00
Fix a deadlock between the crawler and dialer, and other hangs (#1950)
* Stop ignoring inbound message errors and handshake timeouts
To avoid hangs, Zebra needs to maintain the following invariants in the
handshake and heartbeat code:
- each handshake should run in a separate spawned task
(not yet implemented)
- every message, error, timeout, and shutdown must update the peer address state
- every await that depends on the network must have a timeout
Once the Connection is created, it should handle timeouts.
But we need to handle timeouts during handshake setup.
* Avoid hangs by adding a timeout to the candidate set update
Also increase the fanout from 1 to 2, to increase address diversity.
But only return permanent errors from `CandidateSet::update`, because
the crawler task exits if `update` returns an error.
Also log Peers response errors in the CandidateSet.
* Use the select macro in the crawler to reduce hangs
The `select` function is biased towards its first argument, risking
starvation.
As a side-benefit, this change also makes the code a lot easier to read
and maintain.
* Split CrawlerAction::Demand into separate actions
This refactor makes the code a bit easier to read, at the cost of
sometimes blocking the crawler on `candidates.next()`.
That's ok, because `next` only has a short (< 100 ms) delay. And we're
just about to spawn a separate task for each handshake.
* Spawn a separate task for each handshake
This change avoids deadlocks by letting each handshake make progress
independently.
* Move the dial task into a separate function
This refactor improves readability.
* Fix buggy future::select function usage
And document the correctness of the new code.
2021-04-07 06:25:10 -07:00
/// The number of GetAddr requests sent when crawling for new peers.
///
2022-01-04 15:43:30 -08:00
/// # Security
Fix a deadlock between the crawler and dialer, and other hangs (#1950)
* Stop ignoring inbound message errors and handshake timeouts
To avoid hangs, Zebra needs to maintain the following invariants in the
handshake and heartbeat code:
- each handshake should run in a separate spawned task
(not yet implemented)
- every message, error, timeout, and shutdown must update the peer address state
- every await that depends on the network must have a timeout
Once the Connection is created, it should handle timeouts.
But we need to handle timeouts during handshake setup.
* Avoid hangs by adding a timeout to the candidate set update
Also increase the fanout from 1 to 2, to increase address diversity.
But only return permanent errors from `CandidateSet::update`, because
the crawler task exits if `update` returns an error.
Also log Peers response errors in the CandidateSet.
* Use the select macro in the crawler to reduce hangs
The `select` function is biased towards its first argument, risking
starvation.
As a side-benefit, this change also makes the code a lot easier to read
and maintain.
* Split CrawlerAction::Demand into separate actions
This refactor makes the code a bit easier to read, at the cost of
sometimes blocking the crawler on `candidates.next()`.
That's ok, because `next` only has a short (< 100 ms) delay. And we're
just about to spawn a separate task for each handshake.
* Spawn a separate task for each handshake
This change avoids deadlocks by letting each handshake make progress
independently.
* Move the dial task into a separate function
This refactor improves readability.
* Fix buggy future::select function usage
And document the correctness of the new code.
2021-04-07 06:25:10 -07:00
///
2021-04-12 18:12:10 -07:00
/// The fanout should be greater than 2, so that Zebra avoids getting a majority
/// of its initial address book entries from a single peer.
///
/// Zebra regularly crawls for new peers, initiating a new crawl every
/// [`crawl_new_peer_interval`](crate::config::Config.crawl_new_peer_interval).
2022-01-04 15:43:30 -08:00
///
/// TODO: Restore the fanout to 3, once fanouts are limited to the number of ready peers (#2214)
///
/// In #3110, we changed the fanout to 1, to make sure we actually use cached address responses.
/// With a fanout of 3, we were dropping a lot of responses, because the overall crawl timed out.
pub const GET_ADDR_FANOUT : usize = 1 ;
Fix a deadlock between the crawler and dialer, and other hangs (#1950)
* Stop ignoring inbound message errors and handshake timeouts
To avoid hangs, Zebra needs to maintain the following invariants in the
handshake and heartbeat code:
- each handshake should run in a separate spawned task
(not yet implemented)
- every message, error, timeout, and shutdown must update the peer address state
- every await that depends on the network must have a timeout
Once the Connection is created, it should handle timeouts.
But we need to handle timeouts during handshake setup.
* Avoid hangs by adding a timeout to the candidate set update
Also increase the fanout from 1 to 2, to increase address diversity.
But only return permanent errors from `CandidateSet::update`, because
the crawler task exits if `update` returns an error.
Also log Peers response errors in the CandidateSet.
* Use the select macro in the crawler to reduce hangs
The `select` function is biased towards its first argument, risking
starvation.
As a side-benefit, this change also makes the code a lot easier to read
and maintain.
* Split CrawlerAction::Demand into separate actions
This refactor makes the code a bit easier to read, at the cost of
sometimes blocking the crawler on `candidates.next()`.
That's ok, because `next` only has a short (< 100 ms) delay. And we're
just about to spawn a separate task for each handshake.
* Spawn a separate task for each handshake
This change avoids deadlocks by letting each handshake make progress
independently.
* Move the dial task into a separate function
This refactor improves readability.
* Fix buggy future::select function usage
And document the correctness of the new code.
2021-04-07 06:25:10 -07:00
2021-11-11 16:25:23 -08:00
/// The maximum number of addresses allowed in an `addr` or `addrv2` message.
///
/// `addr`:
/// > The number of IP address entries up to a maximum of 1,000.
///
2022-05-30 13:12:11 -07:00
/// <https://developer.bitcoin.org/reference/p2p_networking.html#addr>
2021-11-11 16:25:23 -08:00
///
/// `addrv2`:
/// > One message can contain up to 1,000 addresses.
/// > Clients MUST reject messages with more addresses.
///
2022-05-30 13:12:11 -07:00
/// <https://zips.z.cash/zip-0155#specification>
2021-11-11 16:25:23 -08:00
pub const MAX_ADDRS_IN_MESSAGE : usize = 1000 ;
2021-12-06 11:09:10 -08:00
/// The fraction of addresses Zebra sends in response to a `Peers` request.
///
/// Each response contains approximately:
/// `address_book.len() / ADDR_RESPONSE_LIMIT_DENOMINATOR`
/// addresses, selected at random from the address book.
///
/// # Security
///
/// This limit makes sure that Zebra does not reveal its entire address book
/// in a single `Peers` response.
pub const ADDR_RESPONSE_LIMIT_DENOMINATOR : usize = 3 ;
/// The maximum number of addresses Zebra will keep in its address book.
///
/// This is a tradeoff between:
/// - revealing the whole address book in a few requests,
/// - sending the maximum number of peer addresses, and
/// - making sure the limit code actually gets run.
pub const MAX_ADDRS_IN_ADDRESS_BOOK : usize =
MAX_ADDRS_IN_MESSAGE * ( ADDR_RESPONSE_LIMIT_DENOMINATOR + 1 ) ;
2019-11-13 14:03:12 -08:00
/// Truncate timestamps in outbound address messages to this time interval.
///
2021-04-12 18:12:10 -07:00
/// ## SECURITY
///
/// Timestamp truncation prevents a peer from learning exactly when we received
2019-11-13 14:03:12 -08:00
/// messages from each of our peers.
2021-05-30 19:52:34 -07:00
pub const TIMESTAMP_TRUNCATION_SECONDS : u32 = 30 * 60 ;
2019-11-13 14:03:12 -08:00
2019-09-19 16:16:06 -07:00
/// The User-Agent string provided by the node.
2020-07-29 08:53:57 -07:00
///
/// This must be a valid [BIP 14] user agent.
///
/// [BIP 14]: https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki
2021-06-23 00:45:25 -07:00
//
// TODO: generate this from crate metadata (#2375)
2023-04-18 20:25:51 -07:00
pub const USER_AGENT : & str = " /Zebra:1.0.0-rc.7/ " ;
2019-09-19 16:16:06 -07:00
2020-08-03 19:53:09 -07:00
/// The Zcash network protocol version implemented by this crate, and advertised
/// during connection setup.
2020-07-21 01:41:18 -07:00
///
2020-08-03 19:53:09 -07:00
/// The current protocol version is checked by our peers. If it is too old,
2021-06-28 17:49:03 -07:00
/// newer peers will disconnect from us.
2020-08-03 19:53:09 -07:00
///
/// The current protocol version typically changes before Mainnet and Testnet
/// network upgrades.
2022-05-18 18:04:11 -07:00
pub const CURRENT_NETWORK_PROTOCOL_VERSION : Version = Version ( 170_100 ) ;
2019-09-13 05:28:38 -07:00
2020-08-06 11:29:00 -07:00
/// The default RTT estimate for peer responses.
2020-09-01 18:20:32 -07:00
///
/// We choose a high value for the default RTT, so that new peers must prove they
/// are fast, before we prefer them to other peers. This is particularly
/// important on testnet, which has a small number of peers, which are often
/// slow.
///
2021-04-12 18:12:10 -07:00
/// Make the default RTT slightly higher than the request timeout.
pub const EWMA_DEFAULT_RTT : Duration = Duration ::from_secs ( REQUEST_TIMEOUT . as_secs ( ) + 1 ) ;
2020-08-06 11:29:00 -07:00
/// The decay time for the EWMA response time metric used for load balancing.
2020-09-01 18:20:32 -07:00
///
/// This should be much larger than the `SYNC_RESTART_TIMEOUT`, so we choose
/// better peers when we restart the sync.
2021-12-08 18:54:29 -08:00
pub const EWMA_DECAY_TIME_NANOS : f64 = 200.0 * NANOS_PER_SECOND ;
/// The number of nanoseconds in one second.
const NANOS_PER_SECOND : f64 = 1_000_000_000.0 ;
2020-08-06 11:29:00 -07:00
2021-01-29 04:36:33 -08:00
lazy_static! {
2021-10-08 10:57:04 -07:00
/// The minimum network protocol version accepted by this crate for each network,
/// represented as a network upgrade.
///
/// The minimum protocol version is used to check the protocol versions of our
2021-11-12 11:30:22 -08:00
/// peers during the initial block download. After the initial block download,
2021-10-08 10:57:04 -07:00
/// we use the current block height to select the minimum network protocol
/// version.
///
/// If peer versions are too old, we will disconnect from them.
///
2022-06-02 06:45:29 -07:00
/// The minimum network protocol version typically changes after Mainnet and
2021-10-08 10:57:04 -07:00
/// Testnet network upgrades.
2022-04-19 09:14:24 -07:00
pub static ref INITIAL_MIN_NETWORK_PROTOCOL_VERSION : HashMap < Network , Version > = {
2021-10-08 10:57:04 -07:00
let mut hash_map = HashMap ::new ( ) ;
2022-04-19 09:14:24 -07:00
2022-06-02 06:45:29 -07:00
hash_map . insert ( Mainnet , Version ::min_specified_for_upgrade ( Mainnet , Nu5 ) ) ;
hash_map . insert ( Testnet , Version ::min_specified_for_upgrade ( Testnet , Nu5 ) ) ;
2022-04-19 09:14:24 -07:00
2021-10-08 10:57:04 -07:00
hash_map
} ;
2021-01-29 04:36:33 -08:00
/// OS-specific error when the port attempting to be opened is already in use.
pub static ref PORT_IN_USE_ERROR : Regex = if cfg! ( unix ) {
#[ allow(clippy::trivial_regex) ]
2021-06-03 19:28:43 -07:00
Regex ::new ( & regex ::escape ( " already in use " ) )
2021-01-29 04:36:33 -08:00
} else {
Regex ::new ( " (access a socket in a way forbidden by its access permissions)|(Only one usage of each socket address) " )
} . expect ( " regex is valid " ) ;
}
2021-02-02 18:20:26 -08:00
/// The timeout for DNS lookups.
///
/// [6.1.3.3 Efficient Resource Usage] from [RFC 1123: Requirements for Internet Hosts]
/// suggest no less than 5 seconds for resolving timeout.
///
2022-05-30 13:12:11 -07:00
/// [RFC 1123: Requirements for Internet Hosts] <https://tools.ietf.org/rfcmarkup?doc=1123>
/// [6.1.3.3 Efficient Resource Usage] <https://tools.ietf.org/rfcmarkup?doc=1123#page-77>
2021-02-02 18:20:26 -08:00
pub const DNS_LOOKUP_TIMEOUT : Duration = Duration ::from_secs ( 5 ) ;
2020-03-12 16:34:34 -07:00
/// Magic numbers used to identify different Zcash networks.
pub mod magics {
use super ::* ;
/// The production mainnet.
pub const MAINNET : Magic = Magic ( [ 0x24 , 0xe9 , 0x27 , 0x64 ] ) ;
/// The testnet.
pub const TESTNET : Magic = Magic ( [ 0xfa , 0x1a , 0xf9 , 0xbf ] ) ;
}
2019-10-21 11:59:47 -07:00
#[ cfg(test) ]
mod tests {
2022-02-14 17:44:33 -08:00
use zebra_chain ::parameters ::POST_BLOSSOM_POW_TARGET_SPACING ;
2019-10-21 11:59:47 -07:00
use super ::* ;
2019-10-21 12:16:28 -07:00
/// This assures that the `Duration` value we are computing for
2022-06-13 18:22:16 -07:00
/// [`MIN_PEER_RECONNECTION_DELAY`] actually matches the other const values
/// it relies on.
2019-10-21 11:59:47 -07:00
#[ test ]
fn ensure_live_peer_duration_value_matches_others ( ) {
2022-08-04 08:44:44 -07:00
let _init_guard = zebra_test ::init ( ) ;
2020-11-09 16:29:25 -08:00
2019-10-21 11:59:47 -07:00
let constructed_live_peer_duration =
HEARTBEAT_INTERVAL + REQUEST_TIMEOUT + REQUEST_TIMEOUT + REQUEST_TIMEOUT ;
2021-06-28 22:12:27 -07:00
assert_eq! ( MIN_PEER_RECONNECTION_DELAY , constructed_live_peer_duration ) ;
2019-10-21 11:59:47 -07:00
}
2020-09-01 18:20:32 -07:00
/// Make sure that the timeout values are consistent with each other.
#[ test ]
fn ensure_timeouts_consistent ( ) {
2022-08-04 08:44:44 -07:00
let _init_guard = zebra_test ::init ( ) ;
2020-11-09 16:29:25 -08:00
2020-09-01 18:20:32 -07:00
assert! ( HANDSHAKE_TIMEOUT < = REQUEST_TIMEOUT ,
" Handshakes are requests, so the handshake timeout can't be longer than the timeout for all requests. " ) ;
// This check is particularly important on testnet, which has a small
// number of peers, which are often slow.
assert! ( EWMA_DEFAULT_RTT > REQUEST_TIMEOUT ,
" The default EWMA RTT should be higher than the request timeout, so new peers are required to prove they are fast, before we prefer them to other peers. " ) ;
2021-12-08 18:54:29 -08:00
let request_timeout_nanos = REQUEST_TIMEOUT . as_secs_f64 ( )
+ f64 ::from ( REQUEST_TIMEOUT . subsec_nanos ( ) ) * NANOS_PER_SECOND ;
assert! ( EWMA_DECAY_TIME_NANOS > request_timeout_nanos ,
2020-09-01 18:20:32 -07:00
" The EWMA decay time should be higher than the request timeout, so timed out peers are penalised by the EWMA. " ) ;
2021-12-19 15:02:31 -08:00
assert! (
2023-04-18 01:13:19 -07:00
MIN_PEER_RECONNECTION_DELAY . as_secs ( ) as f32
/ ( u32 ::try_from ( MAX_ADDRS_IN_ADDRESS_BOOK ) . expect ( " fits in u32 " )
* MIN_OUTBOUND_PEER_CONNECTION_INTERVAL )
. as_secs ( ) as f32
> = 0.5 ,
" most peers should get a connection attempt in each connection interval " ,
2021-12-19 15:02:31 -08:00
) ;
assert! (
2023-04-18 01:13:19 -07:00
MIN_PEER_RECONNECTION_DELAY . as_secs ( ) as f32
2021-12-19 15:02:31 -08:00
/ ( u32 ::try_from ( MAX_ADDRS_IN_ADDRESS_BOOK ) . expect ( " fits in u32 " )
2023-04-18 01:13:19 -07:00
* MIN_OUTBOUND_PEER_CONNECTION_INTERVAL )
. as_secs ( ) as f32
< = 2.0 ,
2021-12-19 15:02:31 -08:00
" each peer should only have a few connection attempts in each connection interval " ,
) ;
2020-09-01 18:20:32 -07:00
}
2021-12-06 11:09:10 -08:00
/// Make sure that peer age limits are consistent with each other.
#[ test ]
fn ensure_peer_age_limits_consistent ( ) {
2022-08-04 08:44:44 -07:00
let _init_guard = zebra_test ::init ( ) ;
2021-12-06 11:09:10 -08:00
assert! (
MAX_PEER_ACTIVE_FOR_GOSSIP < = MAX_RECENT_PEER_AGE ,
" we should only gossip peers we are actually willing to try ourselves "
) ;
}
/// Make sure the address limits are consistent with each other.
#[ test ]
#[ allow(clippy::assertions_on_constants) ]
fn ensure_address_limits_consistent ( ) {
// Zebra 1.0.0-beta.2 address book metrics in December 2021.
const TYPICAL_MAINNET_ADDRESS_BOOK_SIZE : usize = 4_500 ;
2022-08-04 08:44:44 -07:00
let _init_guard = zebra_test ::init ( ) ;
2021-12-06 11:09:10 -08:00
assert! (
MAX_ADDRS_IN_ADDRESS_BOOK > = GET_ADDR_FANOUT * MAX_ADDRS_IN_MESSAGE ,
" the address book should hold at least a fanout's worth of addresses "
) ;
assert! (
MAX_ADDRS_IN_ADDRESS_BOOK / ADDR_RESPONSE_LIMIT_DENOMINATOR > MAX_ADDRS_IN_MESSAGE ,
" the address book should hold enough addresses for a full response "
) ;
assert! (
MAX_ADDRS_IN_ADDRESS_BOOK < TYPICAL_MAINNET_ADDRESS_BOOK_SIZE ,
" the address book limit should actually be used "
) ;
}
2022-02-14 17:44:33 -08:00
/// Make sure inventory registry rotation is consistent with the target block interval.
#[ test ]
fn ensure_inventory_rotation_consistent ( ) {
2022-08-04 08:44:44 -07:00
let _init_guard = zebra_test ::init ( ) ;
2022-02-14 17:44:33 -08:00
assert! (
INVENTORY_ROTATION_INTERVAL
< Duration ::from_secs (
POST_BLOSSOM_POW_TARGET_SPACING
. try_into ( )
. expect ( " non-negative " ) ,
) ,
" we should expire inventory every time 1-2 new blocks get generated "
) ;
}
2019-10-21 11:59:47 -07:00
}