mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-13 12:33:42 +02:00
Prevent pegin double spends from entering the mempool
This bug got introduced with the 0.17 rebase. In 0.14.1 the double pegin claim check was done in the beginning of the validation logic, where the coins view was the actual UTXO set. In 0.17, Core moved several checks because the intermediate method CheckInputs was removed and some logic moved to tx_verify.cpp, where we also put the pegin check. In the mempool acceptance check, however (as opposed to the ConnectBlock check), CheckTxInputs is called with only a partial UTXO view for optimization reasons. This commit adds an extra pegin check in the beginning of the mempool code where we have a full UTXO view.
This commit is contained in:
parent
50c557083d
commit
af2264665e
1 changed files with 19 additions and 2 deletions
|
|
@ -681,10 +681,27 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
|||
}
|
||||
|
||||
// do all inputs exist?
|
||||
for (const CTxIn& txin : tx.vin) {
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||
const CTxIn& txin = tx.vin[i];
|
||||
|
||||
// ELEMENTS:
|
||||
// Don't look for coins that only exist in parent chain
|
||||
// For pegin inputs check whether the pegins have already been claimed before.
|
||||
// This only checks the UTXO set for already claimed pegins. For mempool conflicts,
|
||||
// we rely on the GetConflictTx check done above.
|
||||
if (txin.m_is_pegin) {
|
||||
// Quick sanity check on witness first.
|
||||
if (tx.witness.vtxinwit.size() <= i ||
|
||||
tx.witness.vtxinwit[i].m_pegin_witness.stack.size() < 6 ||
|
||||
uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]).IsNull() ||
|
||||
tx.vin[i].prevout.hash.IsNull()) {
|
||||
return state.Invalid(false, REJECT_INVALID, "pegin-no-witness");
|
||||
}
|
||||
|
||||
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), tx.vin[i].prevout);
|
||||
// This assumes non-null prevout and genesis block hash
|
||||
if (view.IsPeginSpent(pegin)) {
|
||||
return state.Invalid(false, REJECT_INVALID, "pegin-already-claimed");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue