Whitelist not working in blocksonly mode? #19943

issue t-bast opened this issue on September 11, 2020
  1. t-bast commented at 5:04 PM on September 11, 2020: member

    I'm trying the following setup with bitcoind 0.20.1 (in regtest currently, let me know if that behaves differently from testnet/mainnet):

                        +------------+
             connect    |   Node2    |     addnode
    Node1 ------------->| blocksonly |<---------------- Node3
                        | forcerelay |---------------->
                        +------------+     addnode
    
    • Node1 uses connect to Node2
    • Node2 is a blocksonly node, but it whitelists nodes 1 and 3 for forcerelay (whitelist=noban,relay,forcerelay,mempool@<IPs>)
    • Node3 is connected to the public network, and uses addnode to Node2

    My expectation from the test added in #18530 was that when Node3 receives a transaction from the network, it would relay it to Node2, which would in turn relay it to Node1 (thanks to the whitelist). When testing that E2E on regtest though it doesn't work: the transaction appears in Node3's mempool, but not in Node1 and Node2's mempools.

    bitcoin-cli getpeerinfo on Node3 has relaytxes: false for the connections to Node2, which is the likely culprit. The permissions field sets forcerelay and relay, but I'm likely missing a different configuration to force tx-relay. Can someone please point me in the right direction? @MarcoFalke

  2. t-bast added the label Bug on Sep 11, 2020
  3. naumenkogs commented at 7:58 AM on September 16, 2020: member

    What I think is happening here:

    1. Node2 sets g_relay_txes=false because of blocksonly at the startup
    2. Node2 sends a VERSION message with fRelay=false because it's evaluated as ::g_relay_txes && pnode.m_tx_relay != nullptr (see above).
    3. When got VERSION message, Node3 sets pfrom.m_tx_relay->fRelayTxes=false for Node2 according to fRelay

    Based on this condition, Node3 would not announce transactions to Node2: if (!pto->m_tx_relay->fRelayTxes) pto->m_tx_relay->setInventoryTxToSend.clear();

  4. t-bast commented at 8:21 AM on September 16, 2020: member

    Thanks for the analysis! Shouldn't the forcerelay whitelist override pto->m_tx_relay->fRelayTxes and set it to true? Note that I opened connections in both directions (Node2 -> Node3 and Node3 -> Node2) since whitelists seem to apply only to inbound connections.

  5. naumenkogs commented at 9:55 AM on September 16, 2020: member

    Shouldn't the forcerelay whitelist override pto->m_tx_relay->fRelayTxes and set it to true?

    The documentation of forcerelay says: "relay transactions even if the transactions were already in the mempool", which probably means it has nothing to do with blocks-only. Overriding can't happen, because this flag is set on the other side of the connection (not a blocks-only node), and that node simply isn't aware of whether it's whitelisted or not. It could have overriden fRelay=false in the VERSION message, but it doesn't.

    I looked at the test #18530. The difference is that nodes connecting to blocks-only peer are mininodes. When they receive blocks-only node's version message, they don't apply much handling logic (like what I described in the previous message), so they keep sending transactions to a blocks-only node. Real nodes do apply it.

    So, this test shows that, for example, if a modified bitcoin node (or another implementation) would send transactions to a blocks-only Bitcoin Core node, they would be relayed if conditions are met (relay permission is set).

    Current Bitcoin Core nodes don't do that. Whether Bitcoin Core nodes should I'm not so sure. At least we should add a comment to the functional test #18530 I guess.

    For now, you can e.g. remove this condition if (!pto->m_tx_relay->fRelayTxes) pto->m_tx_relay->setInventoryTxToSend.clear(); (in Node3), recompile, and perhaps it would work for you :) You can also try sending a FILTERCLEAR message from Node2 to Node3 as another workaround, as it sets pfrom.m_tx_relay->fRelayTxes=true I don't 100% guarantee this works :)

  6. naumenkogs commented at 9:56 AM on September 16, 2020: member

    "addnode" on both sides doesn't make any difference. Connections are bidirectional, and they would have the same behavior (sending same VERSION messages etc.) I tried to explain above.

  7. t-bast commented at 10:05 AM on September 16, 2020: member

    Awesome, thanks for your detailed answer, that makes a lot of sense. I agree that maybe adding a comment to the test would be helpful for newcomers :) I'll try your suggestions, that's definitely acceptable solutions for my use-case, I'll let you know if that works.

  8. t-bast commented at 12:14 PM on September 16, 2020: member

    I've tested both solutions and they work fine. Thanks for the help!

  9. t-bast closed this on Sep 16, 2020

  10. michaelfolkson commented at 12:22 PM on September 16, 2020: contributor

    I agree that maybe adding a comment to the test would be helpful for newcomers :)

    Maybe you could open a PR to add a comment to the test if you can spare the time @t-bast ;)

  11. t-bast commented at 12:24 PM on September 16, 2020: member

    Good idea! I can definitely spare the time, thanks for reminding me!

  12. t-bast referenced this in commit e483b06187 on Sep 16, 2020
  13. t-bast referenced this in commit 0c3f669a49 on Sep 21, 2020
  14. t-bast referenced this in commit f59681ecc4 on Sep 21, 2020
  15. t-bast referenced this in commit e15344889a on Sep 21, 2020
  16. MarcoFalke referenced this in commit b1291b2e8f on Sep 22, 2020
  17. sidhujag referenced this in commit 748f7209a8 on Sep 23, 2020
  18. janus referenced this in commit f5b29be827 on Dec 7, 2020
  19. deadalnix referenced this in commit 4f440ba689 on Oct 11, 2021
  20. DrahtBot locked this on Feb 15, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-29 03:14 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me