Skip normal validation of pegin inputs

Special validation added in next commits.
This commit is contained in:
Steven Roose 2018-12-11 15:11:40 +01:00
parent ae54d4ad74
commit 89613b89c6
6 changed files with 51 additions and 1 deletions

View file

@ -236,6 +236,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsCoinBase()) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
if (tx.vin[i].m_is_pegin) {
continue;
}
if (!HaveCoin(tx.vin[i].prevout)) {
return false;
}

View file

@ -54,6 +54,11 @@ std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
const CTxIn& txin = tx.vin[txinIndex];
// Peg-ins have no output height
if (txin.m_is_pegin) {
continue;
}
// Sequence numbers with the most significant bit set are not
// treated as relative lock-times, nor are they given any
// consensus-enforced meaning at this point.
@ -126,6 +131,11 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
unsigned int nSigOps = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
// Peg-in inputs are segwit-only
if (tx.vin[i].m_is_pegin) {
continue;
}
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
assert(!coin.IsSpent());
const CTxOut &prevout = coin.out;

View file

@ -163,6 +163,11 @@ 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.AccessCoin(tx.vin[i].prevout).out;
std::vector<std::vector<unsigned char> > vSolutions;

View file

@ -1889,6 +1889,10 @@ static UniValue getblockstats(const JSONRPCRequest& request)
}
CAmount tx_total_in = 0;
for (const CTxIn& in : tx->vin) {
if (in.m_is_pegin) {
continue;
}
CTransactionRef tx_in;
uint256 hashBlock;
if (!GetTransaction(in.prevout.hash, tx_in, Params().GetConsensus(), hashBlock, false)) {

View file

@ -395,6 +395,12 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool
prevheights.resize(tx.vin.size());
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
const CTxIn& txin = tx.vin[txinIndex];
// pegins should not restrict validity of sequence locks
if (txin.m_is_pegin) {
prevheights[txinIndex] = -1;
continue;
}
Coin coin;
if (!viewMemPool.GetCoin(txin.prevout, coin)) {
return error("%s: Missing input", __func__);
@ -537,6 +543,10 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
assert(!tx.IsCoinBase());
for (const CTxIn& txin : tx.vin) {
if (txin.m_is_pegin) {
continue;
}
const Coin& coin = view.AccessCoin(txin.prevout);
// At this point we haven't actually checked if the coins are all
@ -658,6 +668,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// do all inputs exist?
for (const CTxIn& txin : tx.vin) {
// ELEMENTS:
// Don't look for coins that only exist in parent chain
if (txin.m_is_pegin) {
continue;
}
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
coins_to_uncache.push_back(txin.prevout);
}
@ -714,6 +730,10 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// during reorgs to ensure COINBASE_MATURITY is still met.
bool fSpendsCoinbase = false;
for (const CTxIn &txin : tx.vin) {
// ELEMENTS:
if (txin.m_is_pegin) {
continue;
}
const Coin &coin = view.AccessCoin(txin.prevout);
if (coin.IsCoinBase()) {
fSpendsCoinbase = true;
@ -2040,7 +2060,11 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// be in ConnectBlock because they require the UTXO set
prevheights.resize(tx.vin.size());
for (size_t j = 0; j < tx.vin.size(); j++) {
prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight;
if (tx.vin[j].m_is_pegin) {
prevheights[j] = -1;
} else {
prevheights[j] = view.AccessCoin(tx.vin[j].prevout).nHeight;
}
}
if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {

View file

@ -3080,6 +3080,10 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
// Notify that old coins are spent
for (const CTxIn& txin : wtxNew.tx->vin)
{
// Pegins are not in our UTXO set.
if (txin.m_is_pegin)
continue;
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
coin.BindWallet(this);
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);