Skip to content
Bitcoin Roots

v29.4-roots.4 · Commit 3: [PATCH 03/37] policy: restore conservative relay and network controls

src/policy/truc_policy.cpp

Before: src/policy/truc_policy.cpp · After: src/policy/truc_policy.cpp

File metadata
index 69e8d5ed1d2961d225c9278d68d6132e4322e91b..d1c9e1ca1267ddfacad449ff5d1b90fc7f3317de 100644

Download original patch · Release notes

Diff rows 1–174 of 174. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

src/policy/truc_policy.cpp CHANGED
@@ -56,6 +56,8 @@ struct ParentInfo {
56
56
  };
57
57
 
58
58
  std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t vsize,
59
+ const std::string& reason_prefix, std::string& out_reason,
60
+ const ignore_rejects_type& ignore_rejects,
59
61
  const Package& package,
60
62
  const CTxMemPool::setEntries& mempool_ancestors)
61
63
  {
@@ -68,12 +70,14 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
68
70
  // Now we have all ancestors, so we can start checking TRUC rules.
69
71
  if (ptx->version == TRUC_VERSION) {
70
72
  // SingleTRUCChecks should have checked this already.
71
- if (!Assume(vsize <= TRUC_MAX_VSIZE)) {
73
+ if (!Assume(vsize <= TRUC_MAX_VSIZE || ignore_rejects.count(reason_prefix + "vsize-toobig"))) {
74
+ out_reason = reason_prefix + "vsize-toobig";
72
75
  return strprintf("version=3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
73
76
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, TRUC_MAX_VSIZE);
74
77
  }
75
78
 
76
- 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")) {
80
+ out_reason = reason_prefix + "ancestors-toomany";
77
81
  return strprintf("tx %s (wtxid=%s) would have too many ancestors",
78
82
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString());
79
83
  }
@@ -81,7 +85,8 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
81
85
  const bool has_parent{mempool_ancestors.size() + in_package_parents.size() > 0};
82
86
  if (has_parent) {
83
87
  // A TRUC child cannot be too large.
84
- if (vsize > TRUC_CHILD_MAX_VSIZE) {
88
+ if (vsize > TRUC_CHILD_MAX_VSIZE && !ignore_rejects.count(reason_prefix + "child-toobig")) {
89
+ out_reason = reason_prefix + "child-toobig";
85
90
  return strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
86
91
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
87
92
  vsize, TRUC_CHILD_MAX_VSIZE);
@@ -106,7 +111,8 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
106
111
  }();
107
112
 
108
113
  // If there is a parent, it must have the right version.
109
- if (parent_info.m_version != TRUC_VERSION) {
114
+ if (parent_info.m_version != TRUC_VERSION && !ignore_rejects.count(reason_prefix + "spends-nontruc")) {
115
+ out_reason = reason_prefix + "spends-nontruc";
110
116
  return strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
111
117
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
112
118
  parent_info.m_txid.ToString(), parent_info.m_wtxid.ToString());
@@ -120,21 +126,24 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
120
126
  // Fail if we find another tx with the same parent. We don't check whether the
121
127
  // sibling is to-be-replaced (done in SingleTRUCChecks) because these transactions
122
128
  // are within the same package.
123
- if (input.prevout.hash == parent_info.m_txid) {
129
+ if (input.prevout.hash == parent_info.m_txid && !ignore_rejects.count(reason_prefix + "sibling-known")) {
130
+ out_reason = reason_prefix + "sibling-known";
124
131
  return strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
125
132
  parent_info.m_txid.ToString(),
126
133
  parent_info.m_wtxid.ToString());
127
134
  }
128
135
 
129
136
  // This tx can't have both a parent and an in-package child.
130
- if (input.prevout.hash == ptx->GetHash()) {
137
+ if (input.prevout.hash == ptx->GetHash() && !ignore_rejects.count(reason_prefix + "parent-and-child-both")) {
138
+ out_reason = reason_prefix + "parent-and-child-both";
131
139
  return strprintf("tx %s (wtxid=%s) would have too many ancestors",
132
140
  package_tx->GetHash().ToString(), package_tx->GetWitnessHash().ToString());
133
141
  }
134
142
  }
135
143
  }
136
144
 
137
- if (parent_info.m_has_mempool_descendant) {
145
+ if (parent_info.m_has_mempool_descendant && !ignore_rejects.count(reason_prefix + "descendant-toomany")) {
146
+ out_reason = reason_prefix + "descendant-toomany";
138
147
  return strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
139
148
  parent_info.m_txid.ToString(), parent_info.m_wtxid.ToString());
140
149
  }
@@ -142,14 +151,16 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
142
151
  } else {
143
152
  // Non-TRUC transactions cannot have TRUC parents.
144
153
  for (auto it : mempool_ancestors) {
145
- if (it->GetTx().version == TRUC_VERSION) {
154
+ if (it->GetTx().version == TRUC_VERSION && !ignore_rejects.count(reason_prefix + "spent-by-nontruc")) {
155
+ out_reason = reason_prefix + "spent-by-nontruc";
146
156
  return strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
147
157
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
148
158
  it->GetSharedTx()->GetHash().ToString(), it->GetSharedTx()->GetWitnessHash().ToString());
149
159
  }
150
160
  }
151
161
  for (const auto& index: in_package_parents) {
152
- if (package.at(index)->version == TRUC_VERSION) {
162
+ if (package.at(index)->version == TRUC_VERSION && !ignore_rejects.count(reason_prefix + "spent-by-nontruc")) {
163
+ out_reason = reason_prefix + "spent-by-nontruc";
153
164
  return strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
154
165
  ptx->GetHash().ToString(),
155
166
  ptx->GetWitnessHash().ToString(),
@@ -161,19 +172,31 @@ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t
161
172
  return std::nullopt;
162
173
  }
163
174
 
175
+ std::optional<std::string> PackageTRUCChecks(const CTransactionRef& ptx, int64_t vsize,
176
+ const Package& package,
177
+ const CTxMemPool::setEntries& mempool_ancestors)
178
+ {
179
+ std::string out_reason;
180
+ return PackageTRUCChecks(ptx, vsize, "", out_reason, empty_ignore_rejects, package, mempool_ancestors);
181
+ }
182
+
164
183
  std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CTransactionRef& ptx,
184
+ const std::string& reason_prefix, std::string& out_reason,
185
+ const ignore_rejects_type& ignore_rejects,
165
186
  const CTxMemPool::setEntries& mempool_ancestors,
166
187
  const std::set<Txid>& direct_conflicts,
167
188
  int64_t vsize)
168
189
  {
169
190
  // Check TRUC and non-TRUC inheritance.
170
191
  for (const auto& entry : mempool_ancestors) {
171
- if (ptx->version != TRUC_VERSION && entry->GetTx().version == TRUC_VERSION) {
192
+ if (ptx->version != TRUC_VERSION && entry->GetTx().version == TRUC_VERSION && !ignore_rejects.count(reason_prefix + "spent-by-nontruc")) {
193
+ out_reason = reason_prefix + "spent-by-nontruc";
172
194
  return std::make_pair(strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
173
195
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
174
196
  entry->GetSharedTx()->GetHash().ToString(), entry->GetSharedTx()->GetWitnessHash().ToString()),
175
197
  nullptr);
176
- } else if (ptx->version == TRUC_VERSION && entry->GetTx().version != TRUC_VERSION) {
198
+ } else if (ptx->version == TRUC_VERSION && entry->GetTx().version != TRUC_VERSION && !ignore_rejects.count(reason_prefix + "spends-nontruc")) {
199
+ out_reason = reason_prefix + "spends-nontruc";
177
200
  return std::make_pair(strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
178
201
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(),
179
202
  entry->GetSharedTx()->GetHash().ToString(), entry->GetSharedTx()->GetWitnessHash().ToString()),
@@ -188,14 +211,16 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
188
211
  // The rest of the rules only apply to transactions with version=3.
189
212
  if (ptx->version != TRUC_VERSION) return std::nullopt;
190
213
 
191
- if (vsize > TRUC_MAX_VSIZE) {
214
+ if (vsize > TRUC_MAX_VSIZE && !ignore_rejects.count(reason_prefix + "vsize-toobig")) {
215
+ out_reason = reason_prefix + "vsize-toobig";
192
216
  return std::make_pair(strprintf("version=3 tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
193
217
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, TRUC_MAX_VSIZE),
194
218
  nullptr);
195
219
  }
196
220
 
197
221
  // Check that TRUC_ANCESTOR_LIMIT would not be violated.
198
- if (mempool_ancestors.size() + 1 > TRUC_ANCESTOR_LIMIT) {
222
+ if (mempool_ancestors.size() + 1 > TRUC_ANCESTOR_LIMIT && !ignore_rejects.count(reason_prefix + "ancestors-toomany")) {
223
+ out_reason = reason_prefix + "ancestors-toomany";
199
224
  return std::make_pair(strprintf("tx %s (wtxid=%s) would have too many ancestors",
200
225
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString()),
201
226
  nullptr);
@@ -204,7 +229,8 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
204
229
  // Remaining checks only pertain to transactions with unconfirmed ancestors.
205
230
  if (mempool_ancestors.size() > 0) {
206
231
  // If this transaction spends TRUC parents, it cannot be too large.
207
- if (vsize > TRUC_CHILD_MAX_VSIZE) {
232
+ if (vsize > TRUC_CHILD_MAX_VSIZE && !ignore_rejects.count(reason_prefix + "child-toobig")) {
233
+ out_reason = reason_prefix + "child-toobig";
208
234
  return std::make_pair(strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
209
235
  ptx->GetHash().ToString(), ptx->GetWitnessHash().ToString(), vsize, TRUC_CHILD_MAX_VSIZE),
210
236
  nullptr);
@@ -222,7 +248,7 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
222
248
  const bool child_will_be_replaced = !children.empty() &&
223
249
  std::any_of(children.cbegin(), children.cend(),
224
250
  [&direct_conflicts](const CTxMemPoolEntry& child){return direct_conflicts.count(child.GetTx().GetHash()) > 0;});
225
- if (parent_entry->GetCountWithDescendants() + 1 > TRUC_DESCENDANT_LIMIT && !child_will_be_replaced) {
251
+ if (parent_entry->GetCountWithDescendants() + 1 > TRUC_DESCENDANT_LIMIT && (!child_will_be_replaced) && !ignore_rejects.count(reason_prefix + "descendants-toomany")) {
226
252
  // Allow sibling eviction for TRUC transaction: if another child already exists, even if
227
253
  // we don't conflict inputs with it, consider evicting it under RBF rules. We rely on TRUC rules
228
254
  // only permitting 1 descendant, as otherwise we would need to have logic for deciding
@@ -233,6 +259,7 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
233
259
 
234
260
  // Return the sibling if its eviction can be considered. Provide the "descendant count
235
261
  // limit" string either way, as the caller may decide not to do sibling eviction.
262
+ out_reason = reason_prefix + "descendants-toomany";
236
263
  return std::make_pair(strprintf("tx %u (wtxid=%s) would exceed descendant count limit",
237
264
  parent_entry->GetSharedTx()->GetHash().ToString(),
238
265
  parent_entry->GetSharedTx()->GetWitnessHash().ToString()),
@@ -241,3 +268,12 @@ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CT
241
268
  }
242
269
  return std::nullopt;
243
270
  }
271
+
272
+ std::optional<std::pair<std::string, CTransactionRef>> SingleTRUCChecks(const CTransactionRef& ptx,
273
+ const CTxMemPool::setEntries& mempool_ancestors,
274
+ const std::set<Txid>& direct_conflicts,
275
+ int64_t vsize)
276
+ {
277
+ std::string out_reason;
278
+ return SingleTRUCChecks(ptx, "", out_reason, empty_ignore_rejects, mempool_ancestors, direct_conflicts, vsize);
279
+ }