feat(wire): implement BanMan and make it single source of truth for bans#926
feat(wire): implement BanMan and make it single source of truth for bans#926Micah-Shallom wants to merge 2 commits intogetfloresta:masterfrom
Conversation
da6ad69 to
4a44223
Compare
|
Even if the PRs are being consolidated, it should have a clearer description of what’s being done. If possible, follow the PR template we have. |
|
okay @moisesPompilio ...editing the description right away |
4a44223 to
a317a87
Compare
| }; | ||
|
|
||
| let net_address = peer_address.get_net_address(); | ||
| if self.ban_man.is_banned(net_address) { |
There was a problem hiding this comment.
add a unit test that seeds a banned IP and verifies something like create_connection returns PeerBanned and no connection attempt is started yet
|
|
||
| // Purge banned IPs from the address database | ||
| self.addresses | ||
| .retain(|_, address| !banned_ips.contains(&address.get_net_address())); |
There was a problem hiding this comment.
banned IP cleanup in rearrange_buckets remove the entries only of addresses but doesnt synchronize good_addresses /good_peers_by_service or similars
this can leave stale ids and make enough_addresses overcounty which can alter peer-acquisition behaviors
while purging the ban address collecct the removed ids and then remove them from all indexes would fix this
| } | ||
|
|
||
| /// Removes all addresses matching the given IP from the address book. | ||
| pub fn remove_address_by_ip(&mut self, ip: IpAddr) { |
There was a problem hiding this comment.
remove_address_by_ip removed from addresses/good_addresses etc but not peers_by_service
this creates stale service index entries and can slowly degrade lookup quality/performance
retain-filter all vectors in peers_by_service for removed ids also would help
|
|
||
| assert!(second_ban > first_ban); | ||
| } | ||
| } |
There was a problem hiding this comment.
lint is unhappy due to missing empty line at the end of file ig
vedpatel@VEDs-MacBook-Air Floresta % cargo +nightly fmt --all -- --check
Diff in /Users/vedpatel/Downloads/Floresta/crates/floresta-wire/src/p2p_wire/ban_man.rs:165:
assert!(second_ban > first_ban);
}
}
+
| pub(crate) state: PeerStatus, | ||
|
|
||
| /// An id identifying this peer's address in our address manager | ||
| #[allow(dead_code)] |
There was a problem hiding this comment.
If it's not being used, just remove the field
There was a problem hiding this comment.
This is not really fixed. Adding a _ is the same as allowing dead code.
There was a problem hiding this comment.
the address_id field has been removed.... @Davidson-Souza
| PeerStatus::Banned => { | ||
| self.address_man | ||
| .update_set_state(idx, AddressState::Banned(RunningNode::BAN_TIME)); | ||
| // Already removed from address_man in disconnect_and_ban | ||
| } |
There was a problem hiding this comment.
If this status isn't needed anymore, you can remove it
There was a problem hiding this comment.
But do we even need a PeerStatus banned?
There was a problem hiding this comment.
@Davidson-Souza ....well looking around we actually do not need it anymore...it is majorly referenced in 2 places
- the assignment here happens to be redundant
- this can be replaced with
ban_man.is_banned(peer.address)but will need to pass in either &self or &banman
There was a problem hiding this comment.
so after alot of back and forths with the compiler.... i tried removing PeerStatus::Banned and replacing the check in is_peer_good with ban_man.is_banned(),,,but i kept getting borrow conflicts...since peers and ban_man live in NODECOMMON and go through DerefMut, the compiler didnt let me borrow them at the same time.....
the workaround was to extract the peer_address before get_mut and check ban status upfront...this ended up removing is_peer_good entirely and creating an inline check....
NOTE: this was an AI suggested change @Davidson-Souza
There was a problem hiding this comment.
Wait, the behavior we want now if for peers to be removed from the addressmanager right ?
| // Purge banned IPs from the address database | ||
| self.addresses | ||
| .retain(|_, address| !banned_ips.contains(&address.get_net_address())); |
There was a problem hiding this comment.
Why purging, tho? I think they can be removed from the good addresses buckets. However, if we prune them here, we will simply forget it forever.
There was a problem hiding this comment.
nice catch @Davidson-Souza ...
purging was a bad design choice here... like you suggested, i introduced a quarantine move instead
quarantine removes banned_ip from good_addresses and good_peers_by_service and marks the banned ip as Failed...this way we still posses info about bannedIPs and this will prevent us from forgetting them..
|
|
||
| impl BanMan { | ||
| /// Creates a new empty Banman | ||
| /// Creates a new empty `Banman`. |
There was a problem hiding this comment.
| /// Creates a new empty `Banman`. | |
| /// Creates a new empty [`Banman`]. |
87043dc to
bf0aabd
Compare
| if let Err(e) = self.ban_man.dump_bans(&self.datadir) { | ||
| tracing::warn!("Failed to dump bans: {e}"); | ||
| } | ||
|
|
There was a problem hiding this comment.
this has been propagated @Davidson-Souza
| @@ -0,0 +1,215 @@ | |||
| use std::collections::HashMap; | |||
There was a problem hiding this comment.
This file needs a SPDX license identifier
9423ba7 to
8f078a4
Compare
| &mut self, | ||
| kind: ConnectionKind, | ||
| peer_id: usize, | ||
| _peer_id: usize, |
There was a problem hiding this comment.
Please remove all unused values (variables, structs, enum variants). Don't add an _ or allow deadcode.
8f078a4 to
22ae270
Compare


Description and Notes
Introduces BanMan for centralized ban management and makes it the single source of truth for bans. Removes AddressState::Banned and replaces scattered ban logic across AddressMan and peer_man.
The following are some of the main changes to get a good grasp:
This PR is a consolidation of #892 and #912.
PR #899 tries to introduce support for CIDR/Subnet into BanMAN
To verify changes
cargo test -p floresta-wireCloses #820.