Introduction

As a follow on to my previous entry, I wanted to take a moment and update where I am with the testing regarding 'getdata for transaction' requests specifically. In the previous post, I had mentioned that transactions could also be a problematic spot, as it was for blocks.

Updating wedger.py

To test the transactions section of the 'getdata' code within main.cpp:ProcessMessage(...), I needed to alter asciilifeform's wedger.py tool to be able to take a list of Transactions (currently residing in a node's mempool) and construct them into a 'getdata' message.

I was going to post the changes that I made to the original wedger.py (at the time of this writing is not genesis'd, KECCAK: ba69d5cc9a4b683a241d01177ea9ccae5fc92a23676bc97b26ee6bfae58525f062f1fed8281c84625cf69c9c1cb9c4a9c9e14cfb462a5dacd1d464d751f3c3b6) here; however, it seems that the PHP blog thingy is stripping out a bunch of code because of right and left angle brackets. Uuugh. So, to hell with it. You can find it here.

Collecting Transactions for wedger.py

To gather up transactions in which to construct the 'getdata' message, I wrote a simple script that would grab these out TRB's debug.log. One needs to start the node, let it run for a while (to begin to populate the mempool), and then run a script, or by hand or something of your own design, of course.
We can only use up to 49,999 transactions in the 'getdata' message, so the script here will limit the number we place into the snap file. The bigger issue here is, I never found more than about 5000 transactions in my memory pool (after waiting about 90 minutes after starting the node, your mileage may vary, of course). The script greps through the debug.log (be sure to truncate the log before you start trb so you are getting fresh transactions) looking for lines with "AcceptToMemoryPool", then parses them and adds them to an array. After which, it simply iterates through the array, writing each transaction to STDOUT until just less than the maximum limit. The reason I don't like this is because we end up with a snap file where the transactions can be repeated a number of times: 49,999 / number of transactions found in mempool. I would like to have all unique transactions, but I haven't figured out a better way to do this yet. However, for the sake of my initial testing, I figured this was worth a try.
./loadtx.sh > snap_tx_49999.txt

Once the snap file is loaded up, now can attempt to run the modified wedger.py tool to see if we can TRB to choke.
./wedger.py tx 127.0.0.1 8333 snap_tx_49999.txt > wedger_tx_20200323.log &
You can find the full log here, but here's an excerpt:
<INCOMING MESSAGE: 'version', 115 bytes>
Alive: V=99999 (/therealbitcoin.org:0.9.99.99/) Jumpers=0x1 (TRB-Compat.) Return Addr=1.2.3.4:8333 Blocks=622691
<INCOMING MESSAGE: 'verack', 0 bytes>
Sending 1685403-byte message packet...
Now listening for replies (Ctl-C to quit...)
<INCOMING MESSAGE: 'getblocks', 1029 bytes>
<INCOMING MESSAGE: 'tx', 226 bytes>
<INCOMING MESSAGE: 'tx', 226 bytes>
<INCOMING MESSAGE: 'tx', 225 bytes>
<INCOMING MESSAGE: 'tx', 225 bytes>
<INCOMING MESSAGE: 'tx', 226 bytes>
<INCOMING MESSAGE: 'tx', 7423 bytes>
<INCOMING MESSAGE: 'tx', 521 bytes>
<INCOMING MESSAGE: 'tx', 191 bytes>
<INCOMING MESSAGE: 'tx', 191 bytes>
<INCOMING MESSAGE: 'tx', 225 bytes>

As you can see, it seems to be working...
However, TRB never did wedge or suffer any problems from the testing. I ran three testing attempts thus far. The third of which has some additional print statements that I included -- because the debug.log gets a bit hard to discern which lines are coming from the wedger test script, and which are normal traffic coming from the greater bitcoin network. The new print statements only execute if the requesting addr.IsLocal(), which is true for me, since my wedger.py script is executing on the same environment with my TRB. After the running of the test, I did do some counts of the data found in the debug log to extract some additional metrics. I need some more investigation there, and I'll leave it at that.

A current working theory of mine here is that, "wedging" or getting TRB into a defunct state from Transactions may be more difficult to do as the size of a transaction message response is much smaller than we would see with a nearly full size block, if that wasn't obvious. In an extreme case, it's hypothetically possible for one to construct a ~1Mb transaction that could cause some problems if it was requested over and over.
However, I could be doing something wrong here in my above testing. If anyone sees something that I've overlooked in my wedger.py changes, collecting the transactions from the debug.log, or elsewhere, please write in.
That's all I have for now, I'll keep looking into this as I can.