Skip to content

Commit

Permalink
Skip normal validation of pegin inputs
Browse files Browse the repository at this point in the history
Special validation added in next commits.
  • Loading branch information
stevenroose committed Jan 2, 2019
1 parent ae54d4a commit 89613b8
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
10 changes: 10 additions & 0 deletions src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions src/policy/policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
26 changes: 25 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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__);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down
4 changes: 4 additions & 0 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 89613b8

Please sign in to comment.