@@ -57,6 +57,7 @@ struct ParentInfo {
57
57
58
58
std::optional<std::string> PackageTRUCChecks (const CTransactionRef& ptx, int64_t vsize,
59
59
const std::string& reason_prefix, std::string& out_reason,
60
+ const ignore_rejects_type& ignore_rejects,
60
61
const Package& package,
61
62
const CTxMemPool::setEntries& mempool_ancestors)
62
63
{
@@ -69,13 +70,13 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
69
70
// Now we have all ancestors, so we can start checking TRUC rules.
70
71
if (ptx->version == TRUC_VERSION) {
71
72
// SingleTRUCChecks should have checked this already.
72
- if (! Assume ( vsize <= TRUC_MAX_VSIZE)) {
73
+ if (vsize > TRUC_MAX_VSIZE && !ignore_rejects. count (reason_prefix + " vsize-toobig " )) {
73
74
out_reason = reason_prefix + " vsize-toobig" ;
74
75
return strprintf (" version=3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes" ,
75
76
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (), vsize, TRUC_MAX_VSIZE);
76
77
}
77
78
78
- if (mempool_ancestors.size () + in_package_parents.size () + 1 > TRUC_ANCESTOR_LIMIT) {
79
+ if (mempool_ancestors.size () + in_package_parents.size () + 1 > TRUC_ANCESTOR_LIMIT && !ignore_rejects. count (reason_prefix + " ancestors-toomany " ) ) {
79
80
out_reason = reason_prefix + " ancestors-toomany" ;
80
81
return strprintf (" tx %s (wtxid=%s) would have too many ancestors" ,
81
82
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ());
@@ -84,7 +85,7 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
84
85
const bool has_parent{mempool_ancestors.size () + in_package_parents.size () > 0 };
85
86
if (has_parent) {
86
87
// A TRUC child cannot be too large.
87
- if (vsize > TRUC_CHILD_MAX_VSIZE) {
88
+ if (vsize > TRUC_CHILD_MAX_VSIZE && !ignore_rejects. count (reason_prefix + " child-toobig " ) ) {
88
89
out_reason = reason_prefix + " child-toobig" ;
89
90
return strprintf (" version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes" ,
90
91
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (),
@@ -110,7 +111,7 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
110
111
}();
111
112
112
113
// If there is a parent, it must have the right version.
113
- if (parent_info.m_version != TRUC_VERSION) {
114
+ if (parent_info.m_version != TRUC_VERSION && !ignore_rejects. count (reason_prefix + " spends-nontruc " ) ) {
114
115
out_reason = reason_prefix + " spends-nontruc" ;
115
116
return strprintf (" version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)" ,
116
117
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (),
@@ -125,15 +126,15 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
125
126
// Fail if we find another tx with the same parent. We don't check whether the
126
127
// sibling is to-be-replaced (done in SingleTRUCChecks) because these transactions
127
128
// are within the same package.
128
- if (input.prevout .hash == parent_info.m_txid ) {
129
+ if (input.prevout .hash == parent_info.m_txid && !ignore_rejects. count (reason_prefix + " sibling-known " ) ) {
129
130
out_reason = reason_prefix + " sibling-known" ;
130
131
return strprintf (" tx %s (wtxid=%s) would exceed descendant count limit" ,
131
132
parent_info.m_txid .ToString (),
132
133
parent_info.m_wtxid .ToString ());
133
134
}
134
135
135
136
// This tx can't have both a parent and an in-package child.
136
- if (input.prevout .hash == ptx->GetHash ()) {
137
+ if (input.prevout .hash == ptx->GetHash () && !ignore_rejects. count (reason_prefix + " parent-and-child-both " ) ) {
137
138
out_reason = reason_prefix + " parent-and-child-both" ;
138
139
return strprintf (" tx %s (wtxid=%s) would have too many ancestors" ,
139
140
package_tx->GetHash ().ToString (), package_tx->GetWitnessHash ().ToString ());
@@ -150,15 +151,15 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
150
151
} else {
151
152
// Non-TRUC transactions cannot have TRUC parents.
152
153
for (auto it : mempool_ancestors) {
153
- if (it->GetTx ().version == TRUC_VERSION) {
154
+ if (it->GetTx ().version == TRUC_VERSION && !ignore_rejects. count (reason_prefix + " spent-by-nontruc " ) ) {
154
155
out_reason = reason_prefix + " spent-by-nontruc" ;
155
156
return strprintf (" non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)" ,
156
157
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (),
157
158
it->GetSharedTx ()->GetHash ().ToString (), it->GetSharedTx ()->GetWitnessHash ().ToString ());
158
159
}
159
160
}
160
161
for (const auto & index: in_package_parents) {
161
- if (package.at (index)->version == TRUC_VERSION) {
162
+ if (package.at (index)->version == TRUC_VERSION && !ignore_rejects. count (reason_prefix + " spent-by-nontruc " ) ) {
162
163
out_reason = reason_prefix + " spent-by-nontruc" ;
163
164
return strprintf (" non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)" ,
164
165
ptx->GetHash ().ToString (),
@@ -173,19 +174,20 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
173
174
174
175
std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks (const CTransactionRef& ptx,
175
176
const std::string& reason_prefix, std::string& out_reason,
177
+ const ignore_rejects_type& ignore_rejects,
176
178
const CTxMemPool::setEntries& mempool_ancestors,
177
179
const std::set<Txid>& direct_conflicts,
178
180
int64_t vsize)
179
181
{
180
182
// Check TRUC and non-TRUC inheritance.
181
183
for (const auto & entry : mempool_ancestors) {
182
- if (ptx->version != TRUC_VERSION && entry->GetTx ().version == TRUC_VERSION) {
184
+ if (ptx->version != TRUC_VERSION && entry->GetTx ().version == TRUC_VERSION && !ignore_rejects. count (reason_prefix + " spent-by-nontruc " ) ) {
183
185
out_reason = reason_prefix + " spent-by-nontruc" ;
184
186
return std::make_pair (strprintf (" non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)" ,
185
187
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (),
186
188
entry->GetSharedTx ()->GetHash ().ToString (), entry->GetSharedTx ()->GetWitnessHash ().ToString ()),
187
189
nullptr );
188
- } else if (ptx->version == TRUC_VERSION && entry->GetTx ().version != TRUC_VERSION) {
190
+ } else if (ptx->version == TRUC_VERSION && entry->GetTx ().version != TRUC_VERSION && !ignore_rejects. count (reason_prefix + " spends-nontruc " ) ) {
189
191
out_reason = reason_prefix + " spends-nontruc" ;
190
192
return std::make_pair (strprintf (" version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)" ,
191
193
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (),
@@ -201,15 +203,15 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
201
203
// The rest of the rules only apply to transactions with version=3.
202
204
if (ptx->version != TRUC_VERSION) return std::nullopt;
203
205
204
- if (vsize > TRUC_MAX_VSIZE) {
206
+ if (vsize > TRUC_MAX_VSIZE && !ignore_rejects. count (reason_prefix + " vsize-toobig " ) ) {
205
207
out_reason = reason_prefix + " vsize-toobig" ;
206
208
return std::make_pair (strprintf (" version=3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes" ,
207
209
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (), vsize, TRUC_MAX_VSIZE),
208
210
nullptr );
209
211
}
210
212
211
213
// Check that TRUC_ANCESTOR_LIMIT would not be violated.
212
- if (mempool_ancestors.size () + 1 > TRUC_ANCESTOR_LIMIT) {
214
+ if (mempool_ancestors.size () + 1 > TRUC_ANCESTOR_LIMIT && !ignore_rejects. count (reason_prefix + " ancestors-toomany " ) ) {
213
215
out_reason = reason_prefix + " ancestors-toomany" ;
214
216
return std::make_pair (strprintf (" tx %s (wtxid=%s) would have too many ancestors" ,
215
217
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString ()),
@@ -219,7 +221,7 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
219
221
// Remaining checks only pertain to transactions with unconfirmed ancestors.
220
222
if (mempool_ancestors.size () > 0 ) {
221
223
// If this transaction spends TRUC parents, it cannot be too large.
222
- if (vsize > TRUC_CHILD_MAX_VSIZE) {
224
+ if (vsize > TRUC_CHILD_MAX_VSIZE && !ignore_rejects. count (reason_prefix + " child-toobig " ) ) {
223
225
out_reason = reason_prefix + " child-toobig" ;
224
226
return std::make_pair (strprintf (" version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes" ,
225
227
ptx->GetHash ().ToString (), ptx->GetWitnessHash ().ToString (), vsize, TRUC_CHILD_MAX_VSIZE),
@@ -238,7 +240,7 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
238
240
const bool child_will_be_replaced = !children.empty () &&
239
241
std::any_of (children.cbegin (), children.cend (),
240
242
[&direct_conflicts](const CTxMemPoolEntry& child){return direct_conflicts.count (child.GetTx ().GetHash ()) > 0 ;});
241
- if (parent_entry->GetCountWithDescendants () + 1 > TRUC_DESCENDANT_LIMIT && !child_will_be_replaced) {
243
+ if (parent_entry->GetCountWithDescendants () + 1 > TRUC_DESCENDANT_LIMIT && ( !child_will_be_replaced) && !ignore_rejects. count (reason_prefix + " descendants-toomany " ) ) {
242
244
// Allow sibling eviction for TRUC transaction: if another child already exists, even if
243
245
// we don't conflict inputs with it, consider evicting it under RBF rules. We rely on TRUC rules
244
246
// only permitting 1 descendant, as otherwise we would need to have logic for deciding
0 commit comments