feat(wire)!: Add a new BitcoinSocketAddr struct to unify address parsing#984
feat(wire)!: Add a new BitcoinSocketAddr struct to unify address parsing#984Davidson-Souza wants to merge 4 commits into
BitcoinSocketAddr struct to unify address parsing#984Conversation
|
cACK. I was actually thinking about this lately. To me, it would make sense to eventually upstream this to |
2d92b13 to
45785e1
Compare
BitcoinSocketAddr struct to unify address parsingBitcoinSocketAddr struct to unify address parsing
1646cab to
4017323
Compare
|
Ready for a first round of reviews |
| // Don't connect to the same peer twice | ||
| let is_connected = |(_, peer_addr): (_, &LocalPeerView)| peer_addr.address == peer_address; | ||
|
|
||
| if self.common.peers.iter().any(is_connected) { | ||
| return Err(WireError::PeerAlreadyExists(peer_address)); |
There was a problem hiding this comment.
NIT
You can use .values() to avoid the clunky |(_, peer_addr): (_, &LocalPeerView)| peer_addr.address == peer_address; syntax
:P
// Don't connect to the same peer twice
if self
.common
.peers
.values()
.any(|p| p.address == peer_address)
{
return Err(WireError::PeerAlreadyExists(peer_address));
}
There was a problem hiding this comment.
| 0, | ||
| AddressState::NeverTried, | ||
| ServiceFlags::NONE, | ||
| 0, |
There was a problem hiding this comment.
maybe dumb question, but why is id hardcoded to zero?
There was a problem hiding this comment.
These come from the AddrMan and we use it to ban/update that address. But since this is coming from somewhere else, we don't know if AddrMan have it or what's the internal id for it.
| debug!("Trying to remove peer {addr}"); | ||
|
|
||
| let address = self.to_addr_v2(addr); | ||
| let index = self |
There was a problem hiding this comment.
NIT
let index = self
.added_peers
.iter()
.position(|info| addr == info.address)
.ok_or(WireError::PeerNotFoundAtAddress(addr))?;
self.added_peers.remove(index);
if your in for a more idiomatic rust approach
| /// Handles the node request for immediate disconnection from a peer. | ||
| pub fn handle_disconnect_peer(&mut self, addr: IpAddr, port: u16) -> Result<(), WireError> { | ||
| pub fn handle_disconnect_peer(&mut self, addr: BitcoinSocketAddr) -> Result<(), WireError> { | ||
| // Get the peer's index in the [`AddressMan`]'s list, if it exists. |
There was a problem hiding this comment.
also nit :p
// Get the peer's index in the [`AddressMan`]'s list, if it exists.
let peer_id = self
.peers
.iter()
.find_map(|(&id, peer)| (*peer.address.as_bitcoin_socket_addr() == addr).then_some(id))
.ok_or(WireError::PeerNotFoundAtAddress(addr))?;
self.send_to_peer(peer_id, NodeRequest::Shutdown)
| .write_all(&[SOCKS_VERSION, 1, SOCKS_AUTH_METHOD_NONE]) | ||
| .await | ||
| .unwrap(); | ||
| .await?; |
| Network::Signet => 38333, | ||
| Network::Bitcoin => 8333, | ||
| Network::Testnet => 18333, | ||
| Network::Regtest => 48444, |
There was a problem hiding this comment.
@Davidson-Souza use the get_p2p_port function I added I while back
There was a problem hiding this comment.
@Davidson-Souza use the get_p2p_port function I added I while back
Where is this function? Maybe it was removed
There was a problem hiding this comment.
Where is this function? Maybe it was removed
Floresta/crates/floresta-wire/src/p2p_wire/node/conn.rs#L475
It's named get_port. Maybe you could rename it to get_p2p_port.
4017323 to
7635a87
Compare
|
Pushed 7635a87 applying @lorenzolfm's code styling suggestions. |
| false, | ||
| "Valid address with out-of-range port", | ||
| ) | ||
| } |
There was a problem hiding this comment.
Missing test coverage for CJDNS addresses.
There was a problem hiding this comment.
Nice catch! Will add!
|
Those PRs changing several files are hard to reason about, but it seems consistent 👍 Maybe we should tackle validation with more tests and corner cases. |
Yeah, it's annoying. But I can't break it further because it wouldn't compile. Most of the changes however, are just changing types, so this is easy to use. As for testing; most of the API parts changes are covered by our functional tests (addnode and connect mainly), I've added several parsing tests and fuzzing to make sure it won't break. Do you have any further suggestion for how to test it? |
7635a87 to
3381963
Compare
|
Added tests for CJDNS |
|
Needs rebase thanks to |
It's actually @moisesPompilio's fault. @JoseSK999 didn't touch RPC. |
|
Fixed lol |
Our code represents addresses in a scattered and messy way. Some places we use SocketAddr, some AddrV2 and some Strings. SocketAddr and Strings already wraps ports, while AddrV2 and IpAddr don't. Therefore some functions will ask for a `u16` and other won't. We also have parsing logic for addresses all over the code, repeating logic and creating inconsistecies. Finally, in some APIs we support names, and others don't, which is frustrating. This type will encapsulate both addresses and ports, as AddrV2 it will work with non-ip addresses such as Tor and I2P. It also supports name resolution. It exposes a few conversion primitives to make it into other types if this is required in specific scopes, but overall we should use this type to represent Bitcoin node addresses.
Use BitcoinSocketAddr where we need to represent a node addressess, simplify some code and improve debug message for addresses.
…nSocketAddr This function was just calling BitcoinSocketAddr, and didn't have any reason to exist. The tests also tested BitcoinSocketAddr, instead of something inside `conn.rs`, so I've moved them.
3381963 to
8470e4d
Compare
|
Rebased and fixed tests. |
Description and Notes
Our code represents addresses in a scattered and messy way. Some places we use SocketAddr, some AddrV2 and some Strings. SocketAddr and Strings already wraps ports, while AddrV2 and IpAddr don't. Therefore some functions will ask for a
u16and other won't. We also have parsing logic for addresses all over the code, repeating logic and creating inconsistecies. Finally, in some APIs we support names, and others don't, which is frustrating.This type will encapsulate both addresses and ports, as AddrV2 it will work with non-ip addresses such as Tor and I2P. It also supports name resolution.
It exposes a few conversion primitives to make it into other types if this is required in specific scopes, but overall we should use this type to represent Bitcoin node addresses.
Note: This used to be part of another PR to implement Onion addresses (we currently can't connect to
.onionaddresses), but got too big and I decided to split it up. Without these changes, it would be impossible to have those as well.