-
Notifications
You must be signed in to change notification settings - Fork 107
/
arbitrary.rs
122 lines (110 loc) · 4.27 KB
/
arbitrary.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! Randomised test data generation for MetaAddr.
use std::net::SocketAddr;
use proptest::{arbitrary::any, collection::vec, prelude::*};
use zebra_chain::{parameters::Network::*, serialization::DateTime32};
use crate::protocol::external::arbitrary::canonical_socket_addr_strategy;
use super::{MetaAddr, MetaAddrChange, PeerServices};
/// The largest number of random changes we want to apply to a [`MetaAddr`].
///
/// This should be at least twice the number of [`PeerAddrState`][1]s, so the
/// tests can cover multiple transitions through every state.
///
/// [1]: super::PeerAddrState
#[allow(dead_code)]
pub const MAX_ADDR_CHANGE: usize = 15;
/// The largest number of random addresses we want to add to an [`AddressBook`][2].
///
/// This should be at least the number of [`PeerAddrState`][1]s, so the tests
/// can cover interactions between addresses in different states.
///
/// [1]: super::PeerAddrState
/// [2]: crate::AddressBook
#[allow(dead_code)]
pub const MAX_META_ADDR: usize = 8;
impl MetaAddr {
/// Create a strategy that generates [`MetaAddr`]s in the
/// [`NeverAttemptedGossiped`][1] state.
///
/// [1]: super::PeerAddrState::NeverAttemptedGossiped
pub fn gossiped_strategy() -> BoxedStrategy<Self> {
(
canonical_socket_addr_strategy(),
any::<PeerServices>(),
any::<DateTime32>(),
)
.prop_map(|(addr, untrusted_services, untrusted_last_seen)| {
MetaAddr::new_gossiped_meta_addr(addr, untrusted_services, untrusted_last_seen)
})
.boxed()
}
/// Create a strategy that generates [`MetaAddr`]s in the
/// [`NeverAttemptedAlternate`][1] state.
///
/// [1]: super::PeerAddrState::NeverAttemptedAlternate
pub fn alternate_strategy() -> BoxedStrategy<Self> {
(canonical_socket_addr_strategy(), any::<PeerServices>())
.prop_map(|(socket_addr, untrusted_services)| {
MetaAddr::new_alternate(&socket_addr, &untrusted_services)
.into_new_meta_addr()
.expect("unexpected invalid alternate change")
})
.boxed()
}
}
impl MetaAddrChange {
/// Returns a strategy which generates changes for `socket_addr`.
///
/// `socket_addr` is typically generated by the `canonical_socket_addr`
/// strategy.
pub fn addr_strategy(addr: SocketAddr) -> BoxedStrategy<Self> {
any::<MetaAddrChange>()
.prop_map(move |mut change| {
change.set_addr(addr);
change
})
.boxed()
}
/// Returns a strategy which generates a `MetaAddr`, and a vector of up to
/// `max_addr_change` changes.
///
/// The address and the changes all have matching `SocketAddr`s.
pub fn addr_changes_strategy(
max_addr_change: usize,
) -> BoxedStrategy<(MetaAddr, Vec<MetaAddrChange>)> {
any::<MetaAddr>()
.prop_flat_map(move |addr| {
(
Just(addr),
vec(MetaAddrChange::addr_strategy(addr.addr), 1..max_addr_change),
)
})
.boxed()
}
/// Create a strategy that generates [`MetaAddrChange`]s which are ready for
/// outbound connections.
///
/// Currently, all generated changes are the [`NewAlternate`][1] variant.
/// TODO: Generate all [`MetaAddrChange`] variants, and give them ready
/// fields. (After PR #2276 merges.)
///
/// [1]: super::NewAlternate
pub fn ready_outbound_strategy() -> BoxedStrategy<Self> {
canonical_socket_addr_strategy()
.prop_filter_map("failed MetaAddr::is_valid_for_outbound", |addr| {
// Alternate nodes use the current time, so they're always ready
//
// TODO: create a "Zebra supported services" constant
let change = MetaAddr::new_alternate(&addr, &PeerServices::NODE_NETWORK);
if change
.into_new_meta_addr()
.expect("unexpected invalid alternate change")
.last_known_info_is_valid_for_outbound(Mainnet)
{
Some(change)
} else {
None
}
})
.boxed()
}
}