| 1237 | } |
| 1238 | |
| 1239 | bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, |
| 1240 | bool* pfMissingInputs, bool fOverrideMempoolLimit, bool fRejectAbsurdFee) |
| 1241 | { |
| 1242 | AssertLockHeld(cs_main); |
| 1243 | if (pfMissingInputs) |
| 1244 | *pfMissingInputs = false; |
| 1245 | |
| 1246 | if (!CheckTransaction(tx, state)) |
| 1247 | return error("AcceptToMemoryPool: CheckTransaction failed"); |
| 1248 | |
| 1249 | // Coinbase is only valid in a block, not as a loose transaction |
| 1250 | if (tx.IsCoinBase()) { |
| 1251 | return state.DoS(100, error("AcceptToMemoryPool: coinbase as individual tx"), |
| 1252 | REJECT_INVALID, "coinbase"); |
| 1253 | } |
| 1254 | |
| 1255 | // Rather not work on nonstandard transactions (unless -testnet/-regtest) |
| 1256 | string reason; |
| 1257 | if (Params().RequireStandard() && !IsStandardTx(tx, reason)) |
| 1258 | return state.DoS(0, |
| 1259 | error("AcceptToMemoryPool: nonstandard transaction: %s", reason), |
| 1260 | REJECT_NONSTANDARD, reason); |
| 1261 | |
| 1262 | // Only accept nLockTime-using transactions that can be mined in the next |
| 1263 | // block; we don't want our mempool filled up with transactions that can't |
| 1264 | // be mined yet. |
| 1265 | if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) |
| 1266 | return state.DoS(0, error("AcceptToMemoryPool: non-final"), |
| 1267 | REJECT_NONSTANDARD, "non-final"); |
| 1268 | |
| 1269 | // is it already in the memory pool? |
| 1270 | uint256 hash = tx.GetHash(); |
| 1271 | if (pool.exists(hash)) |
| 1272 | return false; |
| 1273 | |
| 1274 | // Check for conflicts with in-memory transactions |
| 1275 | bool fRespend = false; |
| 1276 | COutPoint relayForOutpoint; |
| 1277 | { |
| 1278 | LOCK(pool.cs); // protect pool.mapNextTx |
| 1279 | for (unsigned int i = 0; i < tx.vin.size(); i++) |
| 1280 | { |
| 1281 | COutPoint outpoint = tx.vin[i].prevout; |
| 1282 | // A respend is a tx that conflicts with a member of the pool |
| 1283 | if (pool.mapNextTx.count(outpoint)) |
| 1284 | { |
| 1285 | fRespend = true; |
| 1286 | // Relay only one tx per respent outpoint, but not if tx is equivalent to pool member |
| 1287 | if (!doubleSpendFilter.contains(outpoint) && !tx.IsEquivalentTo(*pool.mapNextTx[outpoint].ptx)) |
| 1288 | { |
| 1289 | relayForOutpoint = outpoint; |
| 1290 | break; |
| 1291 | } |
| 1292 | } |
| 1293 | } |
| 1294 | if (fRespend && (relayForOutpoint.IsNull() || RespendRelayExceeded(tx))) |
| 1295 | return false; |
| 1296 | } |
no test coverage detected