Skip to content

Conversation

vasild
Copy link
Contributor

@vasild vasild commented Feb 9, 2024

To improve privacy, broadcast locally submitted transactions (from the sendrawtransaction RPC) to the P2P network only via Tor or I2P short-lived connections, or to IPv4/IPv6 peers but through the Tor network.

  • Introduce a new connection type for private broadcast of transactions with the following properties:

    • started whenever there are local transactions to be sent
    • opened to Tor or I2P peers or IPv4/IPv6 via the Tor proxy
    • opened regardless of max connections limits
    • after handshake is completed one local transaction is pushed to the peer, PING is sent and after receiving PONG the connection is closed
    • ignore all incoming messages after handshake is completed (except PONG)
  • Broadcast transactions submitted via sendrawtransaction using this new mechanism, to a few peers. Keep doing this until we receive back this transaction from one of our ordinary peers (this takes about 1 second on mainnet).

  • The transaction is stored in peerman and does not enter the mempool.

  • Once we get an INV from one of our ordinary peers, then the normal flow executes: we request the transaction with GETDATA, receive it with a TX message, put it in our mempool and broadcast it to all our existent connections (as if we see it for the first time).

  • After we receive the full transaction as a TX message, in reply to our GETDATA request, only then consider the transaction has propagated through the network and remove it from the storage in peerman, ending the private broadcast attempts.

The messages exchange should look like this:

tx-sender >--- connect -------> tx-recipient
tx-sender >--- VERSION -------> tx-recipient (dummy VERSION with no revealing data)
tx-sender <--- VERSION -------< tx-recipient
tx-sender <--- WTXIDRELAY ----< tx-recipient (maybe)
tx-sender <--- SENDADDRV2 ----< tx-recipient (maybe)
tx-sender <--- SENDTXRCNCL ---< tx-recipient (maybe)
tx-sender <--- VERACK --------< tx-recipient
tx-sender >--- VERACK --------> tx-recipient
tx-sender >--- INV/TX --------> tx-recipient (if we take the last commit: fixup!)
tx-sender <--- GETDATA/TX ----< tx-recipient (if we take the last commit: fixup!)
tx-sender >--- TX ------------> tx-recipient
tx-sender >--- PING ----------> tx-recipient
tx-sender <--- PONG ----------< tx-recipient
tx-sender disconnects

Whenever a new transaction is received from sendrawtransaction RPC, the node will send it to a few (NUM_PRIVATE_BROADCAST_PER_TX) recipients right away. If after 10-15 mins we still have not heard anything about the transaction from the network, then it will be sent to 1 more peer (see PeerManagerImpl::ReattemptPrivateBroadcast()).

A few considerations:

  • The short-lived private broadcast connections are very cheap and fast wrt network traffic. It is expected that some of those peers could blackhole the transaction. Just one honest/proper peer is enough for successful propagation.
  • The peers that receive the transaction could deduce that this is initial transaction broadcast from the transaction originator. This is ok, they can't identify the sender.

How to test this?

Thank you, @stratospher and @andrewtoth!

Start bitcoind with -privatebroadcast=1 -debug=privatebroadcast.

Create a wallet and get a new address, go to the Signet faucet and request some coins to that address:

build/bin/bitcoin-cli -chain="signet" createwallet test
build/bin/bitcoin-cli -chain="signet" getnewaddress

Get a new address for the test transaction recipient:

build/bin/bitcoin-cli -chain="signet" loadwallet test
new_address=$(build/bin/bitcoin-cli -chain="signet" getnewaddress)

Create the transaction:

# Option 1: `createrawtransaction` and `signrawtransactionwithwallet`:

txid=$(build/bin/bitcoin-cli -chain="signet" listunspent | jq -r '.[0] | .txid')
vout=$(build/bin/bitcoin-cli -chain="signet" listunspent | jq -r '.[0] | .vout')
echo "txid: $txid"
echo "vout: $vout"

tx=$(build/bin/bitcoin-cli -chain="signet" createrawtransaction "[{\"txid\": \"$txid\", \"vout\": $vout}]" "[{\"$new_address\": 0.00001000}]" 0 false)
echo "tx: $tx"

signed_tx=$(build/bin/bitcoin-cli -chain="signet" signrawtransactionwithwallet "$tx" | jq -r '.hex')
echo "signed_tx: $signed_tx"

# OR Option 2: `walletcreatefundedpsbt` and `walletprocesspsbt`:
# This makes it not have to worry about inputs and also automatically sends back change to the wallet.
# Start `bitcoind` with `-fallbackfee=0.00003000` for instance for 3 sat/vbyte fee.

psbt=$(build/bin/bitcoin-cli -chain="signet" walletcreatefundedpsbt "[]" "[{\"$new_address\": 0.00001000}]" | jq -r '.psbt')
echo "psbt: $psbt"

signed_tx=$(build/bin/bitcoin-cli -chain="signet" walletprocesspsbt "$psbt" | jq -r '.hex')
echo "signed_tx: $signed_tx"

Finally, send the transaction:

raw_tx=$(build/bin/bitcoin-cli -chain="signet" sendrawtransaction "$signed_tx")
echo "raw_tx: $raw_tx"

High-level explanation of the commits
  • New logging category and config option to enable private broadcast

    • log: introduce a new category for private broadcast
    • init: introduce a new option to enable/disable private broadcast
  • Implement the private broadcast connection handling on the CConnman side:

    • net: introduce a new connection type for private broadcast
    • net: support overriding the proxy selection in ConnectNode()
    • net: implement opening PRIVATE_BROADCAST connections
  • Prepare BroadcastTransaction() for private broadcast requests:

    • net_processing: rename RelayTransaction to better describe what it does
    • node: change a tx-relay on/off flag to a tri-state
    • net_processing: store transactions for private broadcast in PeerManager
  • Implement the private broadcast connection handling on the PeerManager side:

    • net_processing: reorder the code that handles the VERSION message
    • net_processing: handle ConnectionType::PRIVATE_BROADCAST connections
    • net_processing: stop private broadcast of a transaction after round-trip
    • net_processing: retry private broadcast
  • Engage the new functionality from sendrawtransaction:

    • rpc: use private broadcast from sendrawtransaction RPC if -privatebroadcast is ON
  • Independent test framework improvement:

    • test: move create_malleated_version() to messages.py for reuse
  • New functional test that exercies some of the new code:

    • test: add functional test for local tx relay
  • Add an intermediate step that sends INV message and waits for a request for the transaction. If reviewers like this, then I will squash it into the relevant commit, or otherwise drop it:

    • fixup! net_processing: handle ConnectionType::PRIVATE_BROADCAST connections

This PR would close the following issues:
#3828 Clients leak IPs if they are recipients of a transaction
#14692 Can't configure bitocoind to only send tx via Tor but receive clearnet transactions
#19042 Tor-only transaction broadcast onlynet=onion alternative
#24557 Option for receive events with all networks, but send transactions and/or blocks only with anonymous network[s]?
#25450 Ability to broadcast wallet transactions only via dedicated oneshot Tor connections
#32235 Tor: TX circuit isolation

Issues that are related, but (maybe?) not to be closed by this PR:
#21876 Broadcast a transaction to specific nodes
#28636 new RPC: sendrawtransactiontopeer


Further extensions:

  • Have the wallet do the private broadcast as well, Could the wallet count unconfirmed non-mempool change? #11887 would have to be resolved.
  • Have the submitpackage RPC do the private broadcast as well, draft diff in the comment below, thanks @ismaelsadeeq!
  • Add some stats via RPC, so that the user can better monitor what is going on during and after the broadcast. Currently this can be done via the debug log, but that is not convenient.
  • Make the private broadcast storage, currently in peerman, persistent over node restarts.
  • Add (optional) random delay before starting to broadcast the transaction in order to avoid correlating unrelated transactions based on the time when they were broadcast. Suggested independently of this PR here.
  • Consider periodically sending transactions that did not originate from the node as decoy, discussed here.

A previous incarnation of this can be found at #27509. It puts the transaction in the mempool and (tries to) hide it from the outside observers. This turned out to be too error prone or maybe even impossible.

@DrahtBot
Copy link
Contributor

DrahtBot commented Feb 9, 2024

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

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/29415.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK andrewtoth
Concept ACK zzzi2p, nothingmuch, jonatack, kdmukai, kevkevinpal, RandyMcMillan
Stale ACK pinheadmz, mzumsande

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #32941 (p2p: TxOrphanage revamp cleanups by glozow)
  • #32747 (Introduce SockMan ("lite"): low-level socket handling for HTTP by pinheadmz)
  • #32699 (docs: adds correct updated documentation links by Zeegaths)
  • #32547 (Mining: Avoid copying template CBlocks by luke-jr)
  • #32394 (net: make m_nodes_mutex non-recursive by vasild)
  • #32326 (net: improve the interface around FindNode() and avoid a recursive mutex lock by vasild)
  • #32065 (i2p: make a time gap between creating transient sessions and using them by vasild)
  • #32015 (net: replace manual reference counting of CNode with shared_ptr by vasild)
  • #31829 (p2p: improve TxOrphanage denial of service bounds by glozow)
  • #30988 (Split CConnman by vasild)
  • #30595 (kernel: Introduce initial C header API by TheCharlatan)
  • #30277 ([DO NOT MERGE] Erlay: bandwidth-efficient transaction relay protocol (Full implementation) by sr-gi)
  • #30116 (p2p: Fill reconciliation sets (Erlay) attempt 2 by sr-gi)
  • #29278 (Wallet: Add maxfeerate wallet startup option by ismaelsadeeq)
  • #28690 (build: Introduce internal kernel library by TheCharlatan)
  • #28584 (Fuzz: extend CConnman tests by vasild)
  • #28463 (p2p: Increase inbound capacity for block-relay only connections by mzumsande)
  • #27865 (wallet: Track no-longer-spendable TXOs separately by achow101)

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.

@1440000bytes

This comment was marked as abuse.

@vasild
Copy link
Contributor Author

vasild commented Feb 10, 2024

@1440000bytes, thanks for asking! There is some discussion at #27509 (the previous attempt on this).

Is it necessary to open new short lived tor/i2p connections for broadcasting the transaction?

Yes, it is. See below.

What are the trade-offs in this implementation vs a simple implementation to relay tx to one or more peers that our node is already connected to?

Sending the transaction over clearnet reveals the IP address/geolocation of the sender. A spy with many connections to the network could try to guess who was the originator. So, why not send it to our Tor peers only? Because it is relatively easy for a spy to fingerprint and link clearnet and Tor connections to the same peer. That is, a long running connection over Tor could be linked to a long running clearnet connection. This is why the proposed changes open a short-lived connection that does not reveal any of the identity of the sender.

Would this benefit nodes that don't have clearnet connections, e.g. Tor/I2P-only nodes? Yes! In the case where the sender sends two otherwise unrelated transactions over the same long-running Tor connection, the recipient will know that they have the same origin, even though they are not related on-chain. Using single shot connections fixes that too.

Related issues:

Linked in the OP, thanks!

@epiccurious
Copy link
Contributor

v2 Transport will be enabled by default in the next release (#29347).

If there were eventually a change to force clearnet transactions over v2 transport (so the details of the communications were encrypted), would that solve the same problem that this PR is aiming to solve?

@vasild
Copy link
Contributor Author

vasild commented Feb 11, 2024

@epiccurious, p2p encryption "solves" the spying from intermediate routers on clearnet (aka man-in-the-middle). Tor, I2P and CJDNS solve that too. While this PR uses only Tor and I2P it would solve that problem. But there is more - it will as well solve issues with spying bitcoin nodes.

vasild added a commit to vasild/bitcoin that referenced this pull request Feb 11, 2024
@User087
Copy link

User087 commented Jul 13, 2025

To be clear, in what ways does the proposed feature resemble/differ from the --tx-proxy option in monero:

Send out your local transactions through SOCKS5 proxy (Tor or I2P).
...
This was introduced to make publishing transactions over Tor easier (no need for torsocks) while allowing clearnet for blocks at the same time (while torsocks affected everything).
...
Note that forwarded transactions (those not originating from the connected wallet(s)) will still be relayed over clearnet.

and from the guide:

If any anonymity network is enabled, transactions being broadcast that lack a valid "context" (i.e. the transaction did not come from a P2P connection), will only be sent to peers on anonymity networks. If an anonymity network is enabled but no peers over an anonymity network are available, an error is logged and the transaction is kept for future broadcasting over an anonymity network. The transaction will not be broadcast unless an anonymity connection is made or until monerod is shutdown and restarted with only public connections enabled.

Would monero's implementation be useful at all?

@andrewtoth
Copy link
Contributor

@User087 There are a few differences from the feature you linked. From the same guide, the very last section:

I2P/Tor Stream Used Twice
monerod currently selects two outgoing connections every 5 minutes for transmitting transactions over I2P/Tor.

The proposed feature here does not use any existing connections for transmitting transactions. It creates a new connection to a random peer for every transaction that is submitted.

From my understanding, the --tx-proxy option also will not relay to clearnet nodes via Tor exit nodes. The proposed feature here will also connect to IPv4 and IPv6 nodes by tunneling through a Tor exit node.

vasild and others added 15 commits July 15, 2025 13:08
Co-authored-by: brunoerg <brunoely.gc@gmail.com>
We will open a short-lived connection to a random Tor or I2P peer,
send our transaction to that peer and close the connection.
Normally `ConnectNode()` could choose whether to use a proxy and which
one. Make it possible to override this from the callers and same for
`OpenNetworkConnection()` - pass down the proxy to `ConnectNode()`.

Document both functions.
Implement opening `ConnectionType::PRIVATE_BROADCAST` connections with
the following properties:
* Only to Tor or I2P (or IPv4/IPv6 through the Tor proxy, if provided)
* Open such connections only when requested and don't maintain N opened
  connections of this type.
* Since this is substantially different than what
  `OpenNetworkConnection()` does, open the private broadcast connections
  from a different thread instead of modifying `OpenNetworkConnection()`
  to also open those types of connections.
Rename `PeerManager::RelayTransaction()` to
`PeerManager::ScheduleTxForBroadcastToAll()`. The transaction is not relayed
when the method returns. It is only scheduled for broadcasting at a later
time. Also, there will be another method which only schedules for broadcast
to Tor or I2P peers.
Previously the `bool relay` argument to `BroadcastTransaction()`
designated:

```
relay=true: add to the mempool and broadcast to all peers
relay=false: add to the mempool
```

Extend this with a third option to not add the transaction to the
mempool and broadcast privately.

This is a non-functional change - the new third option is not handled
inside `BroadcastTransaction()` and is not used by any of the callers.

The idea for the new `node/types.h` and the comments in it by Ryan.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
Extend `PeerManager` with a transaction storage and a new method
`ScheduleTxForPrivateBroadcast()` which:
* adds a transaction to that storage and
* calls `CConnman::PrivateBroadcastAdd()` to open dedicated privacy
  connections that will pick an entry from the transaction storage and
  broadcast it.
Change the order in which code snippets are executed as a result of
receiving the `VERSION` message. Move the snippets that do
`MakeAndPushMessage()` near the end. This will help with handling of
private broadcast connections - they do not require any of that.

This is a non-functional change.
For connections of type `ConnectionType::PRIVATE_BROADCAST`:
* After receiving VERACK, relay a transaction from the list of
  transactions for private broadcast and disconnect
* Don't process any messages after VERACK
* Don't send any messages other than the minimum required for the
  transaction relay
Remove the transaction from the list of transactions to broadcast after
we receive it from the network.

Only remove the transaction if it is the same as the one we sent: both
txid and wtxid match. Don't remove transactions that have the same txid
and different wxtid. Such transactions show that some of the private
broadcast recipients malleated the witness and the transaction made it
back to us. The witness could be either:
* invalid, in which case the transaction will not be accepted in
  anybody's pool; or
* valid, in which case either the original or the malleated transaction
  will make it to nodes' mempools and eventually be mined. Our response
  is to keep broadcasting the original. If the malleated transaction
  wins then we will eventually stop broadcasting the original when it
  gets stale and gets removed from the "to broadcast" storage cause it
  is not acceptable in our mempool.
Periodically check for stale transactions in peerman and if found,
reschedule new connections to be opened by connman for broadcasting
them.
@vasild vasild force-pushed the private_broadcast branch from 6d697bb to dbd76e6 Compare July 15, 2025 12:28
@vasild
Copy link
Contributor Author

vasild commented Jul 15, 2025

6d697bba16...dbd76e68c3: rebase due to conflicts

runtime option for sendrawtransaction

@ismaelsadeeq, I thought about this, but decided to have a single global option to control the behavior given that the plan is to do private broadcast from other places as well. Otherwise it would be a messy situation where "my wallet is doing private broadcast but my RPC is not" or similar.

what will a tor/i2p peer be able to do after fingerprinting that bunch of transactions are from it's peer?

Link them together to the same originator, even if the UTXOs are unrelated.

@andrewtoth
Copy link
Contributor

andrewtoth commented Jul 18, 2025

re-ACK dbd76e6

Changes from my last ACK cedbc2c (git range-diff 7763e86afa...cedbc2cd99 5d17e64a02...dbd76e68c3)

4480ca4 - Added a comment
ead32f3 - const uint256& in some places were changed to const Txid/Wtxid& and this caused a conflict
7255b28 - fixed issue with passing 0 as second parameter to sendrawtransaction
9ec10ce - split up combined if statement into two separate statements. Expanded on a comment.
b817c3e - updated methods to field access in test due to conflict

I tested sendrawtransaction with 0 as second parameter as well for good measure. It worked correctly.

@DrahtBot DrahtBot requested a review from mzumsande July 18, 2025 02:38
@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

DashCoreAutoGuix pushed a commit to DashCoreAutoGuix/dash that referenced this pull request Jul 31, 2025
…ing.cpp

b0344c2 logging: remove unused BCLog::UTIL (Vasil Dimov)
d3b3af9 log: deduplicate category names and improve logging.cpp (Vasil Dimov)

Pull request description:

  The code in `logging.cpp` needs to:
  * Get the category name given the flag (e.g. `BCLog::PRUNE` -> `"prune"`)
  * Get the flag given the category name (e.g. `"prune"` -> `BCLog::PRUNE`)
  * Get the list of category names sorted in alphabetical order

  Achieve this by using the proper std containers. The result is
  * less code (the diff of the first commit is +62 / -129)
  * faster code (to linear search and no copy+sort)
  * more maintainable code (the categories are no longer duplicated in `LogCategories[]` and `LogCategoryToStr()`)

  This behavior is preserved:
  `BCLog::NONE` -> `""` (lookup by `LogCategoryToStr()`)
  `""` -> `BCLog::ALL` (lookup by `GetLogCategory("")`)

  ---

  Also remove unused `BCLog::UTIL`.

  ---

  These changes (modulo the `BCLog::UTIL` removal) are part of bitcoin#29415 but they make sense on their own and would be good to have them, regardless of the fate of bitcoin#29415. Also, if this is merged, that would reduce the size of bitcoin#29415, thus the current standalone PR.

ACKs for top commit:
  davidgumberg:
    crACK bitcoin@b0344c2
  pinheadmz:
    ACK b0344c2
  ryanofsky:
    Code review ACK b0344c2. Nice cleanup! Having to maintain multiple copies of the same mapping seemed messy and a like a possible footgun. I checked old and new mappings in both directions and confirmed no behavior should be changing.

Tree-SHA512: 57f87a090932f9b33dc8e075d1855dba9b71a3243a0758511745483dec2d9c46d3b532eadab297e78164c9b7caba370986ee380696a45f0778a841082f8e21a7
@kdmukai
Copy link
Contributor

kdmukai commented Aug 7, 2025

I successfully completed an end-to-end test:

I configured the Bitcoin Keeper android wallet (v2.5.1) to connect to my electrs instance (v0.10.10) which in turn connected to bitcoind at dbd76e6 on testnet4.

A basic transaction created in Keeper was sent through electrs and out to the network via private broadcast without any complaints. No modifications needed in Keeper or electrs.

As far as electrs was concerned, nothing was out of the ordinary:

[2025-08-07T11:56:21.829Z DEBUG electrs::server] 1: recv {"jsonrpc":"2.0","method":"blockchain.transaction.broadcast","params":["0200000000010180e479f995f35081b96d754640b3614795c7e7a2b3487e1364857ee60fe7d1940100000000feffffff0213b50000000000001600148d38a74a217d0b676481bf5201aa6be9f0f0cf3aac0d0000000000001600141faf25fdc3344325ff5433efdc193db70dc199a402483045022100abbdd964305f6aa5e1d460b30ccadf5084d0708d76da4cd508c95ab4a1cb641b0220400b6123c34fbe035b7dd9be44781b484ae7cc635e0e1dab5e2a402fb57ca91d012102c3239d07a327bfd938dceb288d371f70f508a8243fc0861affb2d4c83065b56d8f750100"],"id":44}
[2025-08-07T11:56:21.829Z DEBUG bitcoincore_rpc] JSON-RPC request: sendrawtransaction ["0200000000010180e479f995f35081b96d754640b3614795c7e7a2b3487e1364857ee60fe7d1940100000000feffffff0213b50000000000001600148d38a74a217d0b676481bf5201aa6be9f0f0cf3aac0d0000000000001600141faf25fdc3344325ff5433efdc193db70dc199a402483045022100abbdd964305f6aa5e1d460b30ccadf5084d0708d76da4cd508c95ab4a1cb641b0220400b6123c34fbe035b7dd9be44781b484ae7cc635e0e1dab5e2a402fb57ca91d012102c3239d07a327bfd938dceb288d371f70f508a8243fc0861affb2d4c83065b56d8f750100"]
[2025-08-07T11:56:21.831Z DEBUG electrs::server] 1: send {"id":44,"jsonrpc":"2.0","result":"af2c09c62e9a7e81c0974b8be393b9b3cd606c5246860fecbc10916bff10fbe5"}

bitcoind logs:

2025-08-07T11:56:21Z [privatebroadcast] Requesting 3 new connections due to txid=af2c09c62e9a7e81c0974b8be393b9b3cd606c5246860fecbc10916bff10fbe5, wtxid=fe1fc666af1425bf61ee3155ded9aa301490229f302db232eb99ba9e15c55a85
2025-08-07T11:56:24Z [privatebroadcast] Socket connected to 85.203.53.149:18333 through the proxy at 127.0.0.1:9050; remaining connections to open: 2
2025-08-07T11:56:24Z [privatebroadcast] Failed to connect to [2607:5300:205:200::115b]:48333 through the proxy at 127.0.0.1:9050, will retry to a different address; remaining connections to open: 2
2025-08-07T11:56:24Z [privatebroadcast] Reattempting broadcast of stale txid=af2c09c62e9a7e81c0974b8be393b9b3cd606c5246860fecbc10916bff10fbe5 wtxid=fe1fc666af1425bf61ee3155ded9aa301490229f302db232eb99ba9e15c55a85
2025-08-07T11:56:24Z New private-broadcast v2 peer connected: version: 70016, blocks=95632, peer=14
2025-08-07T11:56:24Z [privatebroadcast:info] P2P handshake completed, sending INV for txid=af2c09c62e9a7e81c0974b8be393b9b3cd606c5246860fecbc10916bff10fbe5, wtxid=fe1fc666af1425bf61ee3155ded9aa301490229f302db232eb99ba9e15c55a85, peer=14
2025-08-07T11:56:24Z [privatebroadcast] Ignoring incoming message 'ping', peer=14
2025-08-07T11:56:24Z [privatebroadcast] Ignoring incoming message 'feefilter', peer=14
2025-08-07T11:56:29Z [privatebroadcast:info] Got a PONG (the transaction will probably reach the network), marking for disconnect, peer=14
2025-08-07T11:56:32Z [privatebroadcast:info] Received our privately broadcast transaction (txid=af2c09c62e9a7e81c0974b8be393b9b3cd606c5246860fecbc10916bff10fbe5) from the network from peer=8; stopping private broadcast attempts

@RandyMcMillan
Copy link
Contributor

Concept ACK

@jonatack
Copy link
Member

Needs trivial rebase in commit "test: move create_malleated_version() to messages.py for reuse"

diff --cc test/functional/p2p_orphan_handling.py
index f2eed48603c,94b911f4b5a..00000000000
--- a/test/functional/p2p_orphan_handling.py
+++ b/test/functional/p2p_orphan_handling.py
  
  from test_framework.messages import (
      CInv,
++<<<<<<< HEAD
 +    CTxInWitness,
 +    DEFAULT_ANCESTOR_LIMIT,
++=======
++>>>>>>> b817c3e45bd (test: move create_malleated_version() to messages.py for reuse)
      MSG_TX,
      MSG_WITNESS_TX,

(Not a blocker for reviewing further.)

Copy link
Member

@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.

Reviewed up to and including b9cf8a1, looks good so far.

@@ -655,6 +655,15 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
OptionsCategory::NODE_RELAY);
argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-privatebroadcast",
strprintf(
"Broadcast transactions submitted via sendrawtransaction RPC using short lived "
Copy link
Member

Choose a reason for hiding this comment

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

ee75225 two minor grammar touch-ups

Suggested change
"Broadcast transactions submitted via sendrawtransaction RPC using short lived "
"Broadcast transactions submitted via sendrawtransaction RPC using short-lived "

and on the next line, s/networks without/networks, without/

@DrahtBot DrahtBot requested a review from jonatack August 13, 2025 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.