An orphan transaction is a transaction with missing inputs. The p2p code uses a TxOrphanage to store orphan transactions, to be reconsidered later if/when its parent transaction(s) are known.
We have discussed TxOrphanage in previous review club meetings n21527 and n30000.
PR #30793 adds a new RPC, getorphantxs, to
return the contents of the node’s orphanage at that moment.
Its format is similar to the getrawmempool RPC, which also returns information on all transactions in the mempool. Lower verbosity returns the txids,
and higher verbosity returns fields about each entry.
Its purpose is similar to that of getrawaddrman. Most likely, developers will be the main users.
What is an orphan transaction? At what point do transactions enter the orphanage (can you find the code)?
What command can you run to get a list of available RPCs?
What is the benefit of the first commit, which creates a public OrphanTxBase and extends that in a protected struct OrphanTx?
What is the difference between public, protected, and private? When should you use each for
a class member/method?
If an RPC has a non-string argument, does anything special need to be done to handle it?
What specifically does it mean that the RPC is
“hidden”? Why hidden and not net?
Why can’t we just directly access the orphanage from the RPC code? Why don’t we just add a
PeerManager function that returns a reference to the TxOrphanage, which would be more extensible?
What is the maximum size of the result from this RPC? Is there a limit to how many orphans are retained? Is there a
limit to how much time orphans can stay in the orphanage?
Bonus question: Since when has there been a maximum orphanage size (can you find the commit or PR using git log, git blame, or github search)?
These two
items suggest that the RPC can be called with a boolean verbose or an integer verbosity. What does True correspond to, and what does False correspond to, in the function ParseVerbosity?
Using this RPC, would we be able to tell how long a transaction has been in the orphanage? If yes, how would you do it?
Using this RPC, would we be able to tell what the inputs of an orphan transaction are? If yes, how would you do it?
Does the functional test cover the new code thoroughly? How did you evaluate coverage?
<danielabrozzoni> in PeerManagerImpl::ProcessMessage, when a TX message is received, the transaction is validated; if it fails with TX_MISSING_INPUTS, parents are evaluated and it might be added to the orphanage
<danielabrozzoni> i think the idea is to expose only some info about orphan txs, but not all of them, so there is a public structure and a protected one. i'm not sure why OrphanTx extends OrphanTxBase, maybe to avoid changing a lot of code to use the new Base structure?
<monlovesmango> public is for things that can be accessed externally, protected is for when only children can access, and private is for no external access
<glozow> I suppose there isn't 1 right answer to this question. I've seen "use private as much as possible" and "private for members, protected for internal methods"
<kevkevin> So this means that if we extend OrphanTx then that class should be able to access the variables defined there? Where if it was private we would not be able to?
<glozow> Why can’t we just directly access the orphanage from the RPC code? Why don’t we just add a PeerManager function that returns a reference to the `TxOrphanage`, which would be more extensible?
<glozow> Bonus question for the line that kevkevin sent (exercise your `git log` and `git blame` skills): Since when has there been a maximum orphanage size? What about maximum orphan size?
<glozow> for verbosity = 2, I was looking for answer along the lines of "max size of the hex is 400kB since orphan transactions can't be larger than that"
<glozow> luisschwab: right, you don't want the last time the line was touched, you want to keep digging until you find the original commit it was introduced
<danielabrozzoni> yes, you can calculate when a transaction was inserted by looking at the expiration (using verbosity = 1) and subtracting ORPHAN_TX_EXPIRE_TIME
<glozow> A good way to test is of course to try it on mainnet, and look at the transactions in your orphanage. I sanity checked against mempool.space to see that the sizes for example, because it was a little bit suspicious how many were vsize = 141 :P