Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't send 'sendaddrv2' to pre-70016 software, and send before 'verack' #20564

Merged
merged 2 commits into from
Dec 9, 2020

Conversation

sipa
Copy link
Member

@sipa sipa commented Dec 3, 2020

BIP155 defines addrv2 and sendaddrv2 for all protocol versions, but some implementations reject messages they don't know. As a courtesy, don't send it to nodes with a version before 70016, as no software is known to support BIP155 that doesn't announce at least that protocol version number.

Also move the sending of sendaddrv2 earlier (before sending verack), as proposed in bitcoin/bips#1043. This has the side effect that local address broadcast of torv3 will work (as it'll only trigger after we know whether or not the peer supports addrv2).

@fanquake fanquake added the P2P label Dec 3, 2020
@sipa
Copy link
Member Author

sipa commented Dec 3, 2020

I'm deliberately not introducing a name for the 70016 constant, or reuse any of the existing constants. The number isn't tied to any of those; it's just... we're observing that no clients below this number exist that support it.

Copy link
Contributor

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 152b0be

@laanwj
Copy link
Member

laanwj commented Dec 3, 2020

Reluctant ACK. I think this is very messed up for reasons mentioned by Matt here. I think a P2P protocol that is not permissionlessly extensible is unworthy of bitcoin.

@naumenkogs
Copy link
Member

I'm not even sure what's best here, considering an issue with another implementation.
I think considering that this code is non-consensus, very simple, and won't degrade much further — it's fine we pay this cost.
Reluctant ACK as well.

@vasild
Copy link
Contributor

vasild commented Dec 4, 2020

While this patch is technically sound and it will most likely make it in 0.21, the problem with protocol version bumps exists in the long term.

A central body deciding what version numbers are and what goes in them is not suitable for a protocol that is developed in a decentralized manner. Eventually some disagreement may tear apart the sequentiality of the protocol version resulting in something like:

  • implementation1 uses 70019 for feature X and Y
  • implementation2 uses 70019 for feature A and B
  • implementation3 uses 80123 for baking potatoes

Maybe it would be more flexible to introduce new functionality via service bits. Hopefully nobody will disconnect if they see an unknown service bit set. Also, they are gossiped, so one can have an idea what to expect from a peer before connecting and choose peers based on their advertised capabilities.

@sipa
Copy link
Member Author

sipa commented Dec 4, 2020

@vasild I completely agree with the flaws of using protocol versions for feature negotiation. That's not what this is about.

This is a one-time courtesy for existing clients on the network to not cause disruption. It isn't tying features to versions, and perhaps this patch can even be temporary.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review ACK 152b0be seems fine as a temporary workaround to give other implementations a few months to write and deploy a fix

src/net_processing.cpp Show resolved Hide resolved
@maflcko maflcko added this to the 0.21.0 milestone Dec 4, 2020
@maflcko
Copy link
Member

maflcko commented Dec 4, 2020

(Added 0.21 milestone for now)

@jonasschnelli
Copy link
Contributor

utACK 152b0be - agree with @laanwj about @TheBlueMatt point. - Though this "we-fix-your-software" seems acceptable. I already stated my concerns and long term risks with doing such "fixes" (it leads to lesser attention on p2p changes and probably fewer interoperability tests with alternative implementations [because things magically work, a.k.a. Core fixes it]).

@laanwj
Copy link
Member

laanwj commented Dec 4, 2020

Maybe it would be more flexible to introduce new functionality via service bits.

The problem with service bits is that there are (by definition) too few of them, and allocation of them is also a centralized project (lacking centralized allocation, or in presence of disagreement, the meaning of those bits starts to be ambiguous very soon—we've seen this with block versions). I do not think it would have been a better choice.

@maflcko
Copy link
Member

maflcko commented Dec 4, 2020

Also, avoiding to connect to "unknown" service bits is worse than disconnection on an unknown message, because it makes sybil attacks easier. An attacker might pollute the service bits in your p2p-address manager.

@jnewbery
Copy link
Contributor

jnewbery commented Dec 4, 2020

I wish we would use this as an opportunity to do sendaddrv2 negotiation in the right place (between version and verack). We're having to change the code and BIP already, and the logic of "no software is known to support BIP155 that doesn't announce at least that protocol version number" means that such a change would be safe.

Negotiating the addr relay version up front and treating it as const for the peer's lifetime is a much simpler mental model. It means we can be sure that a peer's addr relay version won't change between receiving an addr and trying to relay it to that peer.

Currently, if we receive a tor3 address, we'll choose which peers to relay it to in RelayAddress() without consideration of whether those peers support addrv2. When it's time to send our addrs to those peers in SendMessages(), we won't be able to serialize them. I think that effectively means any non-addrv2 peers become black holes for addrv2 addresses.

We solve that by only considering addrv2 peers as the relays on RelayAddress(), and that's much easier to reason about if we know that the peer's address relay version is constant and won't change out under us.

@laanwj
Copy link
Member

laanwj commented Dec 4, 2020

@jnewbery I vaguely remember that there were some problems with sending messages between version and verack, but not sure.

@Sjors
Copy link
Member

Sjors commented Dec 4, 2020

Tested 152b0be against Breez and a standalone Lnd 0.11.1-beta in neutrino mode (which uses btcd as a library). They no longer hang up on my bitcoind.

@lontivero
Copy link
Contributor

Concept NACK. I am currently implementing BIP 155 in NBitcoin which announces version 70012. This means that even when some clients implement addrv2 they will not receive the signal and share addrv2 addresses. @NicolasDorier what do you thing?

Fwiw I agree with @vasild that signaling new functionality via service bits would be more flexible. Signaling a feature with a new message was surprising to me.

@sipa
Copy link
Member Author

sipa commented Dec 4, 2020

This is not the time and place to discuss how version negotiation should be done in general. But to avoid reiterating things elsewhere: service flags are for feature discovery, not for feature negotiation. There are only a limited number of them, and for the purpose of negotiation they have no advantage over just send* messages like sendcmpct, sendheaders, ...

@laanwj Sending between version and verack works, we do it for wtxid relay. I don' think there is a particularly strong reason to change that for BIP155 at this point though.

@jnewbery I agree that would be slightly cleaner, but I don't think we should make such a change at this point in an rc anymore.

@lontivero That's a good point against this, philosophically. In practice there is no problem for you though - you can announce 70016 as soon as you support BIP155. As all protocol changes since 70012 were just enabling new messages, there would be no other action required from you (70013 adds feefilter, 70014 adds compact blocks, 70016 adds wtxid relay; but if you don't care about any of these, just ignore the messages they send to negotiate support - they only actually change behavior if you respond to those negotiation messages).

@lontivero
Copy link
Contributor

Concept ACK then.

@practicalswift
Copy link
Contributor

A swift Concept ACK for purely practical reasons!

@laanwj
Copy link
Member

laanwj commented Dec 7, 2020

@laanwj Sending between version and verack works, we do it for wtxid relay. I don' think there is a particularly strong reason to change that for BIP155 at this point though.

Maybe, I don't know, it makes some sense to handle different extensions in a consistent way.

@benthecarman
Copy link
Contributor

benthecarman commented Dec 7, 2020

tACK 152b0be

Bitcoin-S needed to update to allow parsing of unknown messages to be able to sync with 0.21.0rc2. I think this change makes sense so clients don't receive messages they aren't expecting.

@sipa sipa changed the title Don't send 'sendaddrv2' to pre-70016 software Don't send 'sendaddrv2' to pre-70016 software, and send before 'verack' Dec 7, 2020
@sipa
Copy link
Member Author

sipa commented Dec 7, 2020

Added a commit to move the sending of sendaddrv2 to before sending verack, matching bitcoin/bips#1043.

@laanwj
Copy link
Member

laanwj commented Dec 7, 2020

re-ACK b2eae52

@benthecarman
Copy link
Contributor

ACK b2eae52

@maflcko
Copy link
Member

maflcko commented Dec 7, 2020

re-ACK deef934

@jonatack
Copy link
Contributor

jonatack commented Dec 7, 2020

ACK deef934

@sipa
Copy link
Member Author

sipa commented Dec 7, 2020

Sorry for the extra pushes. I didn't at first change the message handling to accept incoming sendaddrv2 before verack (thanks @jnewbery), and that the tests needed adapting as well. Making the test changes without the corresponding net_processing changes fails the tests now.

@benthecarman
Copy link
Contributor

ACK deef934

@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 8, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK deef934

Another reason to send sendaddrv2 before sending verack:

When we connect to a peer and try to advertise our Tor v3 address to them we try to do that:

  1. immediately after receiving their version message. At this time PushAddress() does nothing because we still have not received sendaddrv2 from the peer and we assume they don't support addrv2. This is doomed.

  2. From SendMessages(). Notice: SendMessages() does nothing if the peer's verack has not arrived yet. So, what happens with master during my tests is that the first execution of SendMessages() happens before we have received the peer's sendaddrv2. Then AdvertiseLocal() does nothing (because we assume addrv2 is not supported) and our next self-advertise is scheduled for after ~24 hours. It will likely succeed then, but that is a huge delay.

I confirm that with this patch, in 2., the first execution of SendMessages() proceeds with the knowledge that the peer supports addrv2 and thus we actually advertise our address to them "immediately" after establishing the connection.

@sipa
Copy link
Member Author

sipa commented Dec 8, 2020

Updated to require SENDADDRV2 to arrive before VERACK.

@maflcko
Copy link
Member

maflcko commented Dec 8, 2020

ACK 1583498

1 similar comment
@jnewbery
Copy link
Contributor

jnewbery commented Dec 8, 2020

ACK 1583498

Copy link
Contributor

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 1583498

if (msg_type == NetMsgType::SENDADDRV2) {
if (pfrom.fSuccessfullyConnected) {
// Disconnect peers that send SENDADDRV2 message after VERACK; this
// must be negotiated between VERSION and VERACK.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe refer to BIP155 here if you retouch; if you do I'll update #20592 similarly to refer to BIP339

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do so if the BIP change is merged before this PR is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proposed in #20646

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 1583498

@maflcko maflcko merged commit 90ef622 into bitcoin:master Dec 9, 2020
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Dec 9, 2020
…nd send before 'verack'

1583498 Send and require SENDADDRV2 before VERACK (Pieter Wuille)
c5a8919 Don't send 'sendaddrv2' to pre-70016 software (Pieter Wuille)

Pull request description:

  BIP155 defines addrv2 and sendaddrv2 for all protocol versions, but some implementations reject messages they don't know. As a courtesy, don't send it to nodes with a version before 70016, as no software is known to support BIP155 that doesn't announce at least that protocol version number.

  Also move the sending of sendaddrv2 earlier (before sending verack), as proposed in bitcoin/bips#1043. This has the side effect that local address broadcast of torv3 will work (as it'll only trigger after we know whether or not the peer supports addrv2).

ACKs for top commit:
  MarcoFalke:
    ACK 1583498
  jnewbery:
    ACK 1583498
  jonatack:
    ACK 1583498
  vasild:
    ACK 1583498

Tree-SHA512: 3bd5833fa8c8567b6dedd99e4a9b6bb71c127aa66d5284b217503c86d597dc59aa7382c41f3a4bf561bb658b89db81d1a7703a700eef4ffc17cb916660e23a82
maflcko pushed a commit to maflcko/bitcoin-core that referenced this pull request Dec 10, 2020
maflcko pushed a commit to maflcko/bitcoin-core that referenced this pull request Dec 10, 2020
See the corresponding BIP change: bitcoin/bips#1043

Github-Pull: bitcoin#20564
Rebased-From: 1583498
@maflcko
Copy link
Member

maflcko commented Dec 10, 2020

Backported in #20612

random-zebra added a commit to PIVX-Project/PIVX that referenced this pull request Aug 11, 2021
ecde04a [Consensus] Bump Active Protocol version to 70923 for v5.3 (random-zebra)
b63e4f5 Consensus: Add v5.3 enforcement height for testnet. (furszy)
f44be94 Only relay IPv4, IPv6, Tor addresses (Pieter Wuille)
015298c fix: tor: Call event_base_loopbreak from the event's callback (furszy)
34ff7a8 Consensus: Add mnb ADDRv2 guard. (furszy)
b4515dc GUI: Present v3 onion addresses properly in MNs list. (furszy)
337d43d tests: don't export in6addr_loopback (Vasil Dimov)
2cde8e0 GUI: Do not show the tor v3 onion address in the topbar. (furszy)
0b5f406 Doc: update tor.md with latest upstream information. (furszy)
89df7f2 addrman: ensure old versions don't parse peers.dat (Vasil Dimov)
bb90c5c test: add getnetworkinfo network name regression tests (Jon Atack)
d8e01b5 rpc: update GetNetworksInfo() to not return unsupported networks (Jon Atack)
57fc7b0 net: update GetNetworkName() with all enum Network cases (Jon Atack)
647d60b tests: Modify rpc_bind to conform to bitcoin#14532 behaviour. (Carl Dong)
d4d6729 Allow running rpc_bind.py --nonloopback test without IPv6 (Kristaps Kaupe)
4a034d8 test: Add rpc_bind test to default-run tests (Wladimir J. van der Laan)
61a08af [tests] bind functional test nodes to 127.0.0.1  Prevents OSX firewall (Sjors Provoost)
6a4f1e0 test: Add basic addr relay test (furszy)
78aa61c net: Make addr relay mockable (furszy)
ba954ca Send and require SENDADDRV2 before VERACK (Pieter Wuille)
61c2ed4 Bump net protocol version + don't send 'sendaddrv2' to pre-70923 software (furszy)
ccd508a tor: make a TORv3 hidden service instead of TORv2 (Vasil Dimov)
6da9a14 net: advertise support for ADDRv2 via new message (furszy)
e58d5d0 Migrate to test_large_inv() to Misbehaving logging. (furszy)
d496b64 [QA] fix mininode CAddress ser/deser (Jonas Schnelli)
cec9567 net: CAddress & CAddrMan: (un)serialize as ADDRv2 Change the serialization of `CAddrMan` to serialize its addresses in ADDRv2/BIP155 format by default. Introduce a new `CAddrMan` format version (3). (furszy)
b8c1dda streams update: get rid of nType and nVersion. (furszy)
3eaa273 Support bypassing range check in ReadCompactSize (Pieter Wuille)
a237ba4 net: recognize TORv3/I2P/CJDNS networks (Vasil Dimov)
8e50853 util: make EncodeBase32 consume Spans (Sebastian Falbesoner)
1f67e30 net: CNetAddr: add support to (un)serialize as ADDRv2 (Vasil Dimov)
2455420 test: move HasReason so it can be reused (furszy)
d41adb4 util: move HasPrefix() so it can be reused (Vasil Dimov)
f6f86af Unroll Keccak-f implementation (Pieter Wuille)
45222e6 Implement keccak-f[1600] and SHA3-256 (Pieter Wuille)
08ad06d net: change CNetAddr::ip to have flexible size (furszy)
3337219 net: improve encapsulation of CNetAddr. (furszy)
910d5c4 test: Do not instantiate CAddrDB for static call (Hennadii Stepanov)
6b607ef Drop IsLimited in favor of IsReachable (Ben Woosley)
a40711b IsReachable is the inverse of IsLimited (DRY). Includes unit tests (marcaiaf)
8839828 net: don't accept non-left-contiguous netmasks (Vasil Dimov)
5d7f864 rpcbind: Warn about exposing RPC to untrusted networks (Luke Dashjr)
2a6abd8 CNetAddr: Add IsBindAny method to check for INADDR_ANY (Luke Dashjr)
4fdfa45 net: Always default rpcbind to localhost, never "all interfaces" (Luke Dashjr)
31064a8 net: Minor accumulated cleanups (furszy)
9f9c871 tests: Avoid using C-style NUL-terminated strings as arguments (practicalswift)
f6c52a3 tests: Add tests to make sure lookup methods fail on std::string parameters with embedded NUL characters (practicalswift)
a751b9b net: Avoid using C-style NUL-terminated strings as arguments in the netbase interface (furszy)
f30869d test: add IsRFC2544 tests (Mark Tyneway)
ed5abe1 Net: Proper CService deserialization + GetIn6Addr return false if addr isn't an IPv6 addr (furszy)
86d73fb net: save the network type explicitly in CNetAddr (Vasil Dimov)
ad57dfc net: document `enum Network` (Vasil Dimov)
cb160de netaddress: Update CNetAddr for ORCHIDv2 (Carl Dong)
c3c04e4 net: Better misbehaving logging (furszy)
3660487 net: Use C++11 member initialization in protocol (Marco)
082baa3 refactor: Drop unused CBufferedFile::Seek() (Hennadii Stepanov)
e2d776a util: CBufferedFile fixes (Larry Ruane)
6921f42 streams: backport OverrideStream class (furszy)

Pull request description:

  Conjunction of a large number of back ports, updates and refactorings that made with the final goal of implementing v3 Onion addresses support (BIP155 https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki) before the tor v2 addresses EOL, scheduled, by the Tor project, for (1) July 15th: v2 addr support removal from the code base, and (2) October 15th: v2 addr network disable, where **every peer in our network running under Tor will loose the connection and drop the network**.

  As BIP155 describes, this is introducing a new P2P message to gossip longer node addresses over the P2P network. This is required to support new-generation Onion addresses, I2P, and potentially other networks that have longer endpoint addresses than fit in the 128 bits of the current addr message.

  In order to achieve the end goal, had to:
  1.  Create Span class and push it up to latest Bitcoin implementation.
  2.  Update the whole serialization framework and every object using it up to latest Bitcoin implementation (3-4 years ahead of what we currently are in master).
  3.  Update the address manager implementing ASN-based bucketing of the network nodes.
  4.  Update and refactor the netAddress and address manager tests to latest Bitcoin implementation (4 years ahead of what we currently are in master).
  5.  Several util string, vector, encodings, parsing, hashing backports and more..

  Important note:
  This PR it is not meant to be merged as a standalone PR, will decouple smaller ones moving on. Adding on each sub-PR its own description isolated from this big monster.

  Second note:
  This is still a **work-in-progress**, not ready for testing yet. I'm probably missing to mention few PRs that have already adapted to our sources. Just making it public so can decouple the changes, we can start merging them and i can continue working a bit more confortable (rebase a +170 commits separate branch is not fun..).

  ### List of back ported and adapted PRs:

  Span and Serialization:
  ----------------
  *  bitcoin#12886.
  *  bitcoin#12916.
  *  bitcoin#13558.
  *  bitcoin#13697. (Only Span's commit 29943a9)
  *  bitcoin#17850.
  *  bitcoin#17896.
  *  bitcoin#12752.
  *  bitcoin#16577.
  *  bitcoin#16670. (without faebf62)
  *  bitcoin#17957.
  *  bitcoin#18021.
  *  bitcoin#18087.
  *  bitcoin#18112 (only from 353f376 that we don't support).
  *  bitcoin#18167.
  *  bitcoin#18317.
  *  bitcoin#18591 (only Span's commit 0fbde48)
  *  bitcoin#18468.
  *  bitcoin#19020.
  *  bitcoin#19032.
  *  bitcoin#19367.
  *  bitcoin#19387.

  Net, NetAddress and AddrMan:
  ----------------

  *  bitcoin#7932.
  *  bitcoin#10756.
  *  bitcoin#10765.
  *  bitcoin#12218.
  *  bitcoin#12855.
  *  bitcoin#13532.
  *  bitcoin#13575.
  *  bitcoin#13815.
  *  bitcoin#14532.
  *  bitcoin#15051.
  *  bitcoin#15138.
  *  bitcoin#15689.
  *  bitcoin#16702.
  *  bitcoin#17243.
  *  bitcoin#17345.
  *  bitcoin#17754.
  *  bitcoin#17758.
  *  bitcoin#17812.
  *  bitcoin#18023.
  *  bitcoin#18454.
  *  bitcoin#18512.
  *  bitcoin#19314.
  *  bitcoin#19687

  Keys and Addresses encoding:
  ----------------
  * bitcoin#11372.
  * bitcoin#17511.
  * bitcoin#17721.

  Util:
  ----------------
  * bitcoin#9140.
  * bitcoin#16577.
  * bitcoin#16889.
  * bitcoin#19593.

  Bench:
  ----------------
  * bitcoin#16299.

  BIP155:
  ----------------
  *  bitcoin#19351.
  *  bitcoin#19360.
  *  bitcoin#19534.
  *  bitcoin#19628.
  *  bitcoin#19841.
  *  bitcoin#19845.
  *  bitcoin#19954.
  *  bitcoin#19991 (pending).
  *  bitcoin#19845.
  *  bitcoin#20000 (pending).
  *  bitcoin#20120.
  *  bitcoin#20284.
  *  bitcoin#20564.
  *  bitcoin#21157 (pending).
  *  bitcoin#21564 (pending).
  *  Fully removed v2 onion addr support.
  *  Add hardcoded seeds.
  *  Add release-notes, changes to files.md and every needed documentation.

  I'm currently working on the PRs marked as "pending", this isn't over, but I'm pretty pretty close :). What a long road..

ACKs for top commit:
  random-zebra:
    utACK ecde04a
  Fuzzbawls:
    ACK ecde04a

Tree-SHA512: 82c95fbda76fce63f96d8a9af7fa9a89cb1e1b302b7891e27118a6103af0be23606bf202c7332fa61908205e6b6351764e2ec23d753f1e2484028f57c2e8b51a
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet