| 1276 | } |
| 1277 | |
| 1278 | PackageMempoolAcceptResult MemPoolAccept::AcceptMultipleTransactions(const std::vector<CTransactionRef>& txns, ATMPArgs& args) |
| 1279 | { |
| 1280 | AssertLockHeld(cs_main); |
| 1281 | |
| 1282 | // These context-free package limits can be done before taking the mempool lock. |
| 1283 | PackageValidationState package_state; |
| 1284 | if (!CheckPackage(txns, package_state)) return PackageMempoolAcceptResult(package_state, {}); |
| 1285 | |
| 1286 | std::vector<Workspace> workspaces{}; |
| 1287 | workspaces.reserve(txns.size()); |
| 1288 | std::transform(txns.cbegin(), txns.cend(), std::back_inserter(workspaces), |
| 1289 | [&](const auto& tx) { return Workspace(tx, args.m_chainparams.HashGenesisBlock()); }); |
| 1290 | std::map<const uint256, const MempoolAcceptResult> results; |
| 1291 | |
| 1292 | LOCK(m_pool.cs); |
| 1293 | |
| 1294 | // Do all PreChecks first and fail fast to avoid running expensive script checks when unnecessary. |
| 1295 | for (Workspace& ws : workspaces) { |
| 1296 | if (!PreChecks(args, ws)) { |
| 1297 | package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed"); |
| 1298 | // Exit early to avoid doing pointless work. Update the failed tx result; the rest are unfinished. |
| 1299 | results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); |
| 1300 | return PackageMempoolAcceptResult(package_state, std::move(results)); |
| 1301 | } |
| 1302 | // Make the coins created by this transaction available for subsequent transactions in the |
| 1303 | // package to spend. Since we already checked conflicts in the package and we don't allow |
| 1304 | // replacements, we don't need to track the coins spent. Note that this logic will need to be |
| 1305 | // updated if package replace-by-fee is allowed in the future. |
| 1306 | assert(!args.m_allow_bip125_replacement); |
| 1307 | m_viewmempool.PackageAddTransaction(ws.m_ptx); |
| 1308 | } |
| 1309 | |
| 1310 | // Apply package mempool ancestor/descendant limits. Skip if there is only one transaction, |
| 1311 | // because it's unnecessary. Also, CPFP carve out can increase the limit for individual |
| 1312 | // transactions, but this exemption is not extended to packages in CheckPackageLimits(). |
| 1313 | std::string err_string; |
| 1314 | if (txns.size() > 1 && !PackageMempoolChecks(txns, package_state)) { |
| 1315 | return PackageMempoolAcceptResult(package_state, std::move(results)); |
| 1316 | } |
| 1317 | |
| 1318 | for (Workspace& ws : workspaces) { |
| 1319 | if (!PolicyScriptChecks(args, ws)) { |
| 1320 | // Exit early to avoid doing pointless work. Update the failed tx result; the rest are unfinished. |
| 1321 | package_state.Invalid(PackageValidationResult::PCKG_TX, "transaction failed"); |
| 1322 | results.emplace(ws.m_ptx->GetWitnessHash(), MempoolAcceptResult::Failure(ws.m_state)); |
| 1323 | return PackageMempoolAcceptResult(package_state, std::move(results)); |
| 1324 | } |
| 1325 | if (args.m_test_accept) { |
| 1326 | // When test_accept=true, transactions that pass PolicyScriptChecks are valid because there are |
| 1327 | // no further mempool checks (passing PolicyScriptChecks implies passing ConsensusScriptChecks). |
| 1328 | results.emplace(ws.m_ptx->GetWitnessHash(), |
| 1329 | MempoolAcceptResult::Success(std::move(ws.m_replaced_transactions), |
| 1330 | ws.m_vsize, ws.m_base_fees)); |
| 1331 | } |
| 1332 | } |
| 1333 | |
| 1334 | if (args.m_test_accept) return PackageMempoolAcceptResult(package_state, std::move(results)); |
| 1335 |
no test coverage detected