@@ -107,26 +107,46 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
107
107
std::vector<CTransaction> mempool_txs;
108
108
size_t iter{0 };
109
109
110
+ int64_t replacement_vsize = fuzzed_data_provider.ConsumeIntegralInRange <int64_t >(1 , 1000000 );
111
+
112
+ // Keep track of the total vsize of CTxMemPoolEntry's being added to the mempool to avoid overflow
113
+ // Add replacement_vsize since this is added to new diagram during RBF check
114
+ int64_t running_vsize_total{replacement_vsize};
115
+
110
116
LOCK2 (cs_main, pool.cs );
111
117
112
118
LIMITED_WHILE (fuzzed_data_provider.ConsumeBool (), NUM_ITERS)
113
119
{
114
120
// Make sure txns only have one input, and that a unique input is given to avoid circular references
115
121
std::optional<CMutableTransaction> parent = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
116
122
if (!parent) {
117
- continue ;
123
+ return ;
118
124
}
119
125
assert (iter <= g_outpoints.size ());
120
126
parent->vin .resize (1 );
121
127
parent->vin [0 ].prevout = g_outpoints[iter++];
122
128
123
129
mempool_txs.emplace_back (*parent);
124
- pool.addUnchecked (ConsumeTxMemPoolEntry (fuzzed_data_provider, mempool_txs.back ()));
130
+ const auto parent_entry = ConsumeTxMemPoolEntry (fuzzed_data_provider, mempool_txs.back ());
131
+ running_vsize_total += parent_entry.GetTxSize ();
132
+ if (running_vsize_total > std::numeric_limits<int32_t >::max ()) {
133
+ // We aren't adding this final tx to mempool, so we don't want to conflict with it
134
+ mempool_txs.pop_back ();
135
+ break ;
136
+ }
137
+ pool.addUnchecked (parent_entry);
125
138
if (fuzzed_data_provider.ConsumeBool () && !child->vin .empty ()) {
126
139
child->vin [0 ].prevout = COutPoint{mempool_txs.back ().GetHash (), 0 };
127
140
}
128
141
mempool_txs.emplace_back (*child);
129
- pool.addUnchecked (ConsumeTxMemPoolEntry (fuzzed_data_provider, mempool_txs.back ()));
142
+ const auto child_entry = ConsumeTxMemPoolEntry (fuzzed_data_provider, mempool_txs.back ());
143
+ running_vsize_total += child_entry.GetTxSize ();
144
+ if (running_vsize_total > std::numeric_limits<int32_t >::max ()) {
145
+ // We aren't adding this final tx to mempool, so we don't want to conflict with it
146
+ mempool_txs.pop_back ();
147
+ break ;
148
+ }
149
+ pool.addUnchecked (child_entry);
130
150
131
151
if (fuzzed_data_provider.ConsumeBool ()) {
132
152
pool.PrioritiseTransaction (mempool_txs.back ().GetHash ().ToUint256 (), fuzzed_data_provider.ConsumeIntegralInRange <int32_t >(-100000 , 100000 ));
@@ -149,7 +169,6 @@ FUZZ_TARGET(package_rbf, .init = initialize_package_rbf)
149
169
150
170
// Calculate the feerate diagrams for a replacement.
151
171
CAmount replacement_fees = ConsumeMoney (fuzzed_data_provider);
152
- int64_t replacement_vsize = fuzzed_data_provider.ConsumeIntegralInRange <int64_t >(1 , 1000000 );
153
172
auto calc_results{pool.CalculateFeerateDiagramsForRBF (replacement_fees, replacement_vsize, direct_conflicts, all_conflicts)};
154
173
155
174
if (calc_results.has_value ()) {
0 commit comments