mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
mempool and policy support for peg-in inputs
This commit is contained in:
parent
6bad4e9d75
commit
ff5e9cd74d
3 changed files with 33 additions and 4 deletions
|
|
@ -120,6 +120,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
|||
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
{
|
||||
if (tx.vin[i].m_is_pegin) {
|
||||
// This deals with p2sh in general only
|
||||
continue;
|
||||
}
|
||||
const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
|
||||
|
||||
// Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed
|
||||
|
|
@ -169,7 +173,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
|||
if (tx.wit.vtxinwit.size() <= i || tx.wit.vtxinwit[i].scriptWitness.IsNull())
|
||||
continue;
|
||||
|
||||
const CTxOut &prev = mapInputs.GetOutputFor(tx.vin[i]);
|
||||
const CTxOut &prev = tx.vin[i].m_is_pegin ? GetPeginOutputFromWitness(tx.wit.vtxinwit[i].m_pegin_witness) : mapInputs.GetOutputFor(tx.vin[i]);
|
||||
|
||||
// get the scriptPubKey corresponding to this input:
|
||||
CScript prevScript = prev.scriptPubKey;
|
||||
|
|
|
|||
|
|
@ -709,8 +709,9 @@ void CTxMemPool::check(const CCoinsViewCache *pcoins) const
|
|||
parentSigOpCost += it2->GetSigOpCost();
|
||||
}
|
||||
} else {
|
||||
// peg-in inputs are not sanity-checked to be valid
|
||||
const CCoins* coins = pcoins->AccessCoins(txin.prevout.hash);
|
||||
assert(coins && coins->IsAvailable(txin.prevout.n));
|
||||
assert(txin.m_is_pegin || (coins && coins->IsAvailable(txin.prevout.n)));
|
||||
}
|
||||
// Check whether its inputs are marked in mapNextTx.
|
||||
auto it3 = mapNextTx.find(txin.prevout);
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
|
|||
// Note that this does not check for the presence of actual outputs (see the next check for that),
|
||||
// and only helps with filling in pfMissingInputs (to determine missing vs spent).
|
||||
BOOST_FOREACH(const CTxIn txin, tx.vin) {
|
||||
// Don't look for coins that only exist in parent chain
|
||||
if (txin.m_is_pegin) {
|
||||
continue;
|
||||
}
|
||||
if (!pcoinsTip->HaveCoinsInCache(txin.prevout.hash))
|
||||
vHashTxnToUncache.push_back(txin.prevout.hash);
|
||||
if (!view.HaveCoins(txin.prevout.hash)) {
|
||||
|
|
@ -1137,6 +1141,22 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
|
|||
if (!view.HaveInputs(tx))
|
||||
return state.Invalid(false, REJECT_DUPLICATE, "bad-txns-inputs-spent");
|
||||
|
||||
// Extract peg-in inputs, pass set to mempool entry. Validity of pegins checked in CheckInputs
|
||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||
if (tx.vin[i].m_is_pegin) {
|
||||
// Quick check of pegin witness and prevout to extract db entry
|
||||
if (tx.wit.vtxinwit.size() <= i || tx.wit.vtxinwit[i].m_pegin_witness.stack.size() < 6 || uint256(tx.wit.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.wit.vtxinwit[i].m_pegin_witness.stack[2]), tx.vin[i].prevout);
|
||||
// This assumes non-null prevout and genesis block hash
|
||||
if (view.IsWithdrawSpent(pegin)) {
|
||||
return state.Invalid(false, REJECT_CONFLICT, "pegin-already-claimed");
|
||||
}
|
||||
setPeginsSpent.insert(pegin);
|
||||
}
|
||||
}
|
||||
|
||||
// Bring the best block into scope
|
||||
view.GetBestBlock();
|
||||
|
||||
|
|
@ -1171,14 +1191,18 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
|
|||
double nPriorityDummy = 0;
|
||||
pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees);
|
||||
|
||||
CAmount inChainInputValue;
|
||||
double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue);
|
||||
// Neuter priority in mempool
|
||||
CAmount inChainInputValue = 0;
|
||||
double dPriority = 0;
|
||||
|
||||
// Keep track of transactions that spend a coinbase, which we re-scan
|
||||
// during reorgs to ensure COINBASE_MATURITY is still met.
|
||||
// Also track withdraw lock spends to allow them through free relay
|
||||
bool fSpendsCoinbase = false;
|
||||
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
|
||||
if (txin.m_is_pegin) {
|
||||
continue;
|
||||
}
|
||||
const CCoins *coins = view.AccessCoins(txin.prevout.hash);
|
||||
if (coins->IsCoinBase()) {
|
||||
fSpendsCoinbase = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue