[#node-TxOrphanage]
= xref:node.adoc[node]::TxOrphanage
:relfileprefix: ../
:mrdocs:

A class to track orphan transactions (failed on TX&lowbar;MISSING&lowbar;INPUTS) Since we cannot distinguish orphans from bad transactions with non&hyphen;existent inputs, we heavily limit the amount of announcements (unique (NodeId, wtxid) pairs), the number of inputs, and size of the orphans stored (both individual and summed)&period; We also try to prevent adversaries from churning this data structure&colon; once global limits are reached, we continuously evict the oldest announcement (sorting non&hyphen;reconsiderable orphans before reconsiderable ones) from the most resource&hyphen;intensive peer until we are back within limits&period; &hyphen; Peers can exceed their individual limits (e&period;g&period; because they are very useful transaction relay peers) as long as the global limits are not exceeded&period; &hyphen; As long as the orphan has 1 announcer, it remains in the orphanage&period; &hyphen; No peer can trigger the eviction of another peer&apos;s orphans&period; &hyphen; Peers&apos; orphans are effectively protected from eviction as long as they don&apos;t exceed their limits&period; Not thread&hyphen;safe&period; Requires external synchronization&period;

== Synopsis

Declared in `&lt;node&sol;txorphanage&period;h&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
class TxOrphanage;
----

== Types

[cols="1,4"]
|===
| Name| Description
| xref:node/TxOrphanage/OrphanInfo.adoc[`OrphanInfo`] 
| Allows providing orphan information externally
|===


== Type Aliases

[cols="1,4"]
|===
| Name| Description
| xref:node/TxOrphanage/Count.adoc[`Count`] 
| Count of announcements or orphans&period;
| xref:node/TxOrphanage/Usage.adoc[`Usage`] 
| Memory usage (weight) measured in weight units&period;
|===


== Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:node/TxOrphanage/2destructor.adoc[`&#126;TxOrphanage`] [.small]#[destructor]# [.small]#[virtual]#
| Destroy the orphanage and release all stored orphans&period;
| xref:node/TxOrphanage/AddAnnouncer.adoc[`AddAnnouncer`]  [.small]#[virtual]#
| Add an additional announcer to an orphan if it exists&period; Otherwise, do nothing&period;
| xref:node/TxOrphanage/AddChildrenToWorkSet.adoc[`AddChildrenToWorkSet`]  [.small]#[virtual]#
| Add any orphans that list a particular tx as a parent into the from peer&apos;s work set
| xref:node/TxOrphanage/AddTx.adoc[`AddTx`]  [.small]#[virtual]#
| Add a new orphan transaction
| xref:node/TxOrphanage/AnnouncementsFromPeer.adoc[`AnnouncementsFromPeer`]  [.small]#[virtual]#
| Number of orphans stored from this peer&period;
| xref:node/TxOrphanage/CountAnnouncements.adoc[`CountAnnouncements`]  [.small]#[virtual]#
| Number of announcements, i&period;e&period; total size of m&lowbar;orphans&period; Ones for the same wtxid are not de&hyphen;duplicated&period; Not the same as TotalLatencyScore()&period;
| xref:node/TxOrphanage/CountUniqueOrphans.adoc[`CountUniqueOrphans`]  [.small]#[virtual]#
| Number of unique orphans (by wtxid)&period;
| xref:node/TxOrphanage/EraseForBlock.adoc[`EraseForBlock`]  [.small]#[virtual]#
| Erase all orphans included in or invalidated by a new block
| xref:node/TxOrphanage/EraseForPeer.adoc[`EraseForPeer`]  [.small]#[virtual]#
| Maybe erase all orphans announced by a peer (eg, after that peer disconnects)&period; If an orphan has been announced by another peer, don&apos;t erase, just remove this peer from the list of announcers&period;
| xref:node/TxOrphanage/EraseTx.adoc[`EraseTx`]  [.small]#[virtual]#
| Erase an orphan by wtxid, including all announcements if there are multiple&period; Returns true if an orphan was erased, false if no tx with this wtxid exists&period;
| xref:node/TxOrphanage/GetChildrenFromSamePeer.adoc[`GetChildrenFromSamePeer`]  [.small]#[virtual]#
| Get all children that spend from this tx and were received from nodeid&period; Sorted reconsiderable before non&hyphen;reconsiderable, then from most recent to least recent&period;
| xref:node/TxOrphanage/GetOrphanTransactions.adoc[`GetOrphanTransactions`]  [.small]#[virtual]#
| Get all orphan transactions
| xref:node/TxOrphanage/GetTx.adoc[`GetTx`]  [.small]#[virtual]#
| Get a transaction by its witness txid
| xref:node/TxOrphanage/GetTxToReconsider.adoc[`GetTxToReconsider`]  [.small]#[virtual]#
| Extract a transaction from a peer&apos;s work set, and flip it back to non&hyphen;reconsiderable&period; Returns nullptr if there are no transactions to work on&period; Otherwise returns the transaction reference, and removes it from the work set&period;
| xref:node/TxOrphanage/HaveTx.adoc[`HaveTx`]  [.small]#[virtual]#
| Check if we already have an orphan transaction (by wtxid only)
| xref:node/TxOrphanage/HaveTxFromPeer.adoc[`HaveTxFromPeer`]  [.small]#[virtual]#
| Check if a &lcub;tx, peer&rcub; exists in the orphanage&period;
| xref:node/TxOrphanage/HaveTxToReconsider.adoc[`HaveTxToReconsider`]  [.small]#[virtual]#
| Does this peer have any work to do?
| xref:node/TxOrphanage/LatencyScoreFromPeer.adoc[`LatencyScoreFromPeer`]  [.small]#[virtual]#
| Latency score of transactions announced by this peer&period;
| xref:node/TxOrphanage/MaxGlobalLatencyScore.adoc[`MaxGlobalLatencyScore`]  [.small]#[virtual]#
| Get the maximum global latency score allowed
| xref:node/TxOrphanage/MaxGlobalUsage.adoc[`MaxGlobalUsage`]  [.small]#[virtual]#
| Get the maximum global usage allowed
| xref:node/TxOrphanage/MaxPeerLatencyScore.adoc[`MaxPeerLatencyScore`]  [.small]#[virtual]#
| Get the maximum latency score allowed per peer
| xref:node/TxOrphanage/ReservedPeerUsage.adoc[`ReservedPeerUsage`]  [.small]#[virtual]#
| Get the reserved usage per peer
| xref:node/TxOrphanage/SanityCheck.adoc[`SanityCheck`]  [.small]#[virtual]#
| Check consistency between PeerOrphanInfo and m&lowbar;orphans&period; Recalculate counters and ensure they match what is cached&period;
| xref:node/TxOrphanage/TotalLatencyScore.adoc[`TotalLatencyScore`]  [.small]#[virtual]#
| Get the total latency score of all orphans
| xref:node/TxOrphanage/TotalOrphanUsage.adoc[`TotalOrphanUsage`]  [.small]#[virtual]#
| Get the total usage (weight) of all orphans&period; If an orphan has multiple announcers, its usage is only counted once within this total&period;
| xref:node/TxOrphanage/UsageByPeer.adoc[`UsageByPeer`]  [.small]#[virtual]#
| Total usage (weight) of orphans for which this peer is an announcer&period; If an orphan has multiple announcers, its weight will be accounted for in each PeerOrphanInfo, so the total of all peers&apos; UsageByPeer() may be larger than TotalOrphanUsage()&period; Similarly, UsageByPeer() may be far higher than ReservedPeerUsage(), particularly if many peers have provided the same orphans&period;
|===


== Non-Member Functions

[cols="1,4"]
|===
| Name| Description
| xref:node/MakeTxOrphanage-01.adoc[`MakeTxOrphanage`]
| Create a new TxOrphanage instance
| xref:node/MakeTxOrphanage-05.adoc[`MakeTxOrphanage`]
| Create a new TxOrphanage instance with explicit limits&period;
|===


[.small]#Created with https://www.mrdocs.com[MrDocs]#
