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 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
crate::ix!();
impl AddrManInner {
pub unsafe fn resolve_collisions(&mut self,
n_key: &u256,
asmap: &Vec<bool>,
tried_collisions: *mut HashSet<i32>,
) {
(*tried_collisions).retain(|id_new| {
let mut erase_collision: bool = false;
// If id_new not found in mapInfo
// remove it from m_tried_collisions
if !self.map_info.contains_key(id_new) {
erase_collision = true;
} else {
let info_new: *mut AddrInfo = self.map_info.get_mut(&id_new).unwrap() as *mut AddrInfo;
unsafe {
// Which tried bucket to move the
// entry to.
let tried_bucket: usize = (*info_new).get_tried_bucket(n_key, asmap).try_into().unwrap();
let tried_bucket_pos: usize = (*info_new).get_bucket_position(n_key, false, tried_bucket).try_into().unwrap();
if !(*info_new).source.is_valid() {
// id_new may no longer map to
// a valid address
erase_collision = true;
} else if self.vv_tried[tried_bucket][tried_bucket_pos] != -1 {
// The position in the tried
// bucket is not empty
//
// Get the to-be-evicted
// address that is being
// tested
let id_old: i32 = self.vv_tried[tried_bucket][tried_bucket_pos];;
let info_old: *mut AddrInfo = self.map_info.get_mut(&id_old).unwrap() as *mut AddrInfo;
// Has successfully connected in last X hours
if get_adjusted_time() - (*info_old).n_last_success < (ADDRMAN_REPLACEMENT_HOURS * (60 * 60)).try_into().unwrap() {
erase_collision = true;
} else if get_adjusted_time() - (*info_old).n_last_try < (ADDRMAN_REPLACEMENT_HOURS * (60 * 60)).try_into().unwrap() {
// attempted to connect
// and failed in last
// X hours
//
// Give address at least
// 60 seconds to
// successfully connect
if get_adjusted_time() - (*info_old).n_last_try > 60 {
log_print!(
bc_log::addrman,
"Replacing %s with %s in tried table\n",
(*info_old).to_string(),
(*info_new).to_string()
);
// Replaces an
// existing address
// already in the
// tried table with
// the new address
self.good(
&(*info_new).address.service,
false,
get_adjusted_time(),
n_key,
asmap,
tried_collisions
);
erase_collision = true;
}
} else if get_adjusted_time() - (*info_new).n_last_success > ADDRMAN_TEST_WINDOW.try_into().unwrap() {
// If the collision hasn't
// resolved in some
// reasonable amount of
// time, just evict the
// old entry -- we must
// not be able to connect
// to it for some reason.
log_print!(
bc_log::addrman,
"Unable to test; replacing %s with %s in tried table anyway\n",
(*info_old).to_string(),
(*info_new).to_string()
);
self.good(
&(*info_new).address.service,
false,
get_adjusted_time(),
n_key,
asmap,
tried_collisions
);
erase_collision = true;
}
} else {
// Collision is not actually
// a collision anymore
self.good(
&(*info_new).address.service,
false,
get_adjusted_time(),
n_key,
asmap,
tried_collisions
);
erase_collision = true;
}
}
}
!erase_collision
})
}
}