| 1172 | } |
| 1173 | |
| 1174 | bool MemPoolAccept::SubmitPackage(const ATMPArgs& args, std::vector<Workspace>& workspaces, |
| 1175 | PackageValidationState& package_state, |
| 1176 | std::map<const uint256, const MempoolAcceptResult>& results) |
| 1177 | { |
| 1178 | AssertLockHeld(cs_main); |
| 1179 | AssertLockHeld(m_pool.cs); |
| 1180 | // Sanity check: none of the transactions should be in the mempool, and none of the transactions |
| 1181 | // should have a same-txid-different-witness equivalent in the mempool. |
| 1182 | assert(std::all_of(workspaces.cbegin(), workspaces.cend(), [this](const auto& ws){ |
| 1183 | return !m_pool.exists(GenTxid::Txid(ws.m_ptx->GetHash())); })); |
| 1184 | |
| 1185 | bool all_submitted = true; |
| 1186 | // ConsensusScriptChecks adds to the script cache and is therefore consensus-critical; |
| 1187 | // CheckInputsFromMempoolAndCache asserts that transactions only spend coins available from the |
| 1188 | // mempool or UTXO set. Submit each transaction to the mempool immediately after calling |
| 1189 | // ConsensusScriptChecks to make the outputs available for subsequent transactions. |
| 1190 | for (Workspace& ws : workspaces) { |
| 1191 | if (!ConsensusScriptChecks(args, ws)) { |
| 1192 | results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); |
| 1193 | // Since PolicyScriptChecks() passed, this should never fail. |
| 1194 | all_submitted = false; |
| 1195 | package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR, |
| 1196 | strprintf("BUG! PolicyScriptChecks succeeded but ConsensusScriptChecks failed: %s", |
| 1197 | ws.m_ptx->GetHash().ToString())); |
| 1198 | } |
| 1199 | |
| 1200 | // Re-calculate mempool ancestors to call addUnchecked(). They may have changed since the |
| 1201 | // last calculation done in PreChecks, since package ancestors have already been submitted. |
| 1202 | std::string unused_err_string; |
| 1203 | if(!m_pool.CalculateMemPoolAncestors(*ws.m_entry, ws.m_ancestors, m_limit_ancestors, |
| 1204 | m_limit_ancestor_size, m_limit_descendants, |
| 1205 | m_limit_descendant_size, unused_err_string)) { |
| 1206 | results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); |
| 1207 | // Since PreChecks() and PackageMempoolChecks() both enforce limits, this should never fail. |
| 1208 | all_submitted = false; |
| 1209 | package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR, |
| 1210 | strprintf("BUG! Mempool ancestors or descendants were underestimated: %s", |
| 1211 | ws.m_ptx->GetHash().ToString())); |
| 1212 | } |
| 1213 | // If we call LimitMempoolSize() for each individual Finalize(), the mempool will not take |
| 1214 | // the transaction's descendant feerate into account because it hasn't seen them yet. Also, |
| 1215 | // we risk evicting a transaction that a subsequent package transaction depends on. Instead, |
| 1216 | // allow the mempool to temporarily bypass limits, the maximum package size) while |
| 1217 | // submitting transactions individually and then trim at the very end. |
| 1218 | if (!Finalize(args, ws)) { |
| 1219 | results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); |
| 1220 | // Since LimitMempoolSize() won't be called, this should never fail. |
| 1221 | all_submitted = false; |
| 1222 | package_state.Invalid(PackageValidationResult::PCKG_MEMPOOL_ERROR, |
| 1223 | strprintf("BUG! Adding to mempool failed: %s", ws.m_ptx->GetHash().ToString())); |
| 1224 | } |
| 1225 | } |
| 1226 | |
| 1227 | // It may or may not be the case that all the transactions made it into the mempool. Regardless, |
| 1228 | // make sure we haven't exceeded max mempool size. |
| 1229 | LimitMempoolSize(m_pool, m_active_chainstate.CoinsTip(), |
| 1230 | gArgs.GetIntArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, |
| 1231 | std::chrono::hours{gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); |
nothing calls this directly
no test coverage detected