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
crate::ix!();
impl FinalizeNode for PeerManager {
fn finalize_node(&mut self, node: &mut AmoWriteGuard<Box<dyn NodeInterface>>) {
let nodeid: NodeId = node.get_id();
let mut misbehavior: i32 = 0;
{
let mut guard = CS_MAIN.lock();
{
let peer: Amo<Peer> = self.remove_peer(nodeid);
assert!(peer.is_some());
misbehavior =
peer.get().misbehavior.lock().score;
}
let state: Amo<NodeState> = create_state(nodeid);
assert!(state.is_some());
if state.get().sync_started.load(atomic::Ordering::Relaxed) {
{
let old = self.inner.lock().n_sync_started;
self.inner.lock().n_sync_started -= 1;
old
};
}
let mut inner = self.inner.lock();
let mut mbif = inner.map_blocks_in_flight.lock();
for entry in state.get().blocks_in_flight.iter() {
mbif.remove(&entry.pindex.as_ref().unwrap().get_block_hash());
}
{
let mut guard = G_CS_ORPHANS.lock();
self.orphanage.clone().erase_for_peer(nodeid);
}
inner.txrequest.lock().disconnected_peer(nodeid);
N_PREFERRED_DOWNLOAD.fetch_sub(
match state.get().preferred_download.load(atomic::Ordering::Relaxed) { true => 1, false => 0 },
atomic::Ordering::Relaxed
);
inner.peers_downloading_from.fetch_sub(
match state.get().n_blocks_in_flight.load(atomic::Ordering::Relaxed) != 0 { true => 1, false => 0 },
atomic::Ordering::Relaxed
);
assert!(inner.peers_downloading_from.load(atomic::Ordering::Relaxed) >= 0);
inner.outbound_peers_with_protect_from_disconnect.fetch_sub(
match state.get().chain_sync.protect { true => 1, false => 0 },
atomic::Ordering::Relaxed
);
assert!(inner.outbound_peers_with_protect_from_disconnect.load(atomic::Ordering::Relaxed) >= 0);
inner.wtxid_relay_peers.fetch_sub(
match state.get().wtxid_relay.load(atomic::Ordering::Relaxed) { true => 1, false => 0 },
atomic::Ordering::Relaxed
);
assert!(inner.wtxid_relay_peers.load(atomic::Ordering::Relaxed) >= 0);
MAP_NODE_STATE.lock().remove(&nodeid);
if MAP_NODE_STATE.lock().is_empty() {
assert!(mbif.is_empty());
assert!(N_PREFERRED_DOWNLOAD.load(atomic::Ordering::Relaxed) == 0);
assert!(inner.peers_downloading_from.load(atomic::Ordering::Relaxed) == 0);
assert!(inner.outbound_peers_with_protect_from_disconnect.load(atomic::Ordering::Relaxed) == 0);
assert!(inner.wtxid_relay_peers.load(atomic::Ordering::Relaxed) == 0);
assert!(inner.txrequest.lock().size() == 0);
assert!(self.orphanage.size() == 0);
}
}
if node.is_successfully_connected()
&& misbehavior == 0
&& !node.is_block_only_conn()
&& !node.is_inbound_conn() {
self.addrman.get_mut()
.connected(node.service(), None);
}
log_print!(LogFlags::NET, "Cleared nodestate for peer=%d\n", nodeid);
}
}