mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-16 13:01:19 +02:00
Skip normal validation of pegin inputs
Special validation added in next commits.
This commit is contained in:
parent
ae54d4ad74
commit
89613b89c6
6 changed files with 51 additions and 1 deletions
|
|
@ -236,6 +236,9 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
|
||||||
{
|
{
|
||||||
if (!tx.IsCoinBase()) {
|
if (!tx.IsCoinBase()) {
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
for (unsigned int i = 0; i < tx.vin.size(); i++) {
|
||||||
|
if (tx.vin[i].m_is_pegin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!HaveCoin(tx.vin[i].prevout)) {
|
if (!HaveCoin(tx.vin[i].prevout)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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++) {
|
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
|
||||||
const CTxIn& txin = tx.vin[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
|
// Sequence numbers with the most significant bit set are not
|
||||||
// treated as relative lock-times, nor are they given any
|
// treated as relative lock-times, nor are they given any
|
||||||
// consensus-enforced meaning at this point.
|
// consensus-enforced meaning at this point.
|
||||||
|
|
@ -126,6 +131,11 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
|
||||||
unsigned int nSigOps = 0;
|
unsigned int nSigOps = 0;
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
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);
|
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
|
||||||
assert(!coin.IsSpent());
|
assert(!coin.IsSpent());
|
||||||
const CTxOut &prevout = coin.out;
|
const CTxOut &prevout = coin.out;
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,11 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < tx.vin.size(); i++)
|
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;
|
const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;
|
||||||
|
|
||||||
std::vector<std::vector<unsigned char> > vSolutions;
|
std::vector<std::vector<unsigned char> > vSolutions;
|
||||||
|
|
|
||||||
|
|
@ -1889,6 +1889,10 @@ static UniValue getblockstats(const JSONRPCRequest& request)
|
||||||
}
|
}
|
||||||
CAmount tx_total_in = 0;
|
CAmount tx_total_in = 0;
|
||||||
for (const CTxIn& in : tx->vin) {
|
for (const CTxIn& in : tx->vin) {
|
||||||
|
if (in.m_is_pegin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
CTransactionRef tx_in;
|
CTransactionRef tx_in;
|
||||||
uint256 hashBlock;
|
uint256 hashBlock;
|
||||||
if (!GetTransaction(in.prevout.hash, tx_in, Params().GetConsensus(), hashBlock, false)) {
|
if (!GetTransaction(in.prevout.hash, tx_in, Params().GetConsensus(), hashBlock, false)) {
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,12 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp, bool
|
||||||
prevheights.resize(tx.vin.size());
|
prevheights.resize(tx.vin.size());
|
||||||
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
|
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
|
||||||
const CTxIn& txin = tx.vin[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;
|
Coin coin;
|
||||||
if (!viewMemPool.GetCoin(txin.prevout, coin)) {
|
if (!viewMemPool.GetCoin(txin.prevout, coin)) {
|
||||||
return error("%s: Missing input", __func__);
|
return error("%s: Missing input", __func__);
|
||||||
|
|
@ -537,6 +543,10 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
|
||||||
|
|
||||||
assert(!tx.IsCoinBase());
|
assert(!tx.IsCoinBase());
|
||||||
for (const CTxIn& txin : tx.vin) {
|
for (const CTxIn& txin : tx.vin) {
|
||||||
|
if (txin.m_is_pegin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
const Coin& coin = view.AccessCoin(txin.prevout);
|
||||||
|
|
||||||
// At this point we haven't actually checked if the coins are all
|
// 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?
|
// do all inputs exist?
|
||||||
for (const CTxIn& txin : tx.vin) {
|
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)) {
|
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
|
||||||
coins_to_uncache.push_back(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.
|
// during reorgs to ensure COINBASE_MATURITY is still met.
|
||||||
bool fSpendsCoinbase = false;
|
bool fSpendsCoinbase = false;
|
||||||
for (const CTxIn &txin : tx.vin) {
|
for (const CTxIn &txin : tx.vin) {
|
||||||
|
// ELEMENTS:
|
||||||
|
if (txin.m_is_pegin) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const Coin &coin = view.AccessCoin(txin.prevout);
|
const Coin &coin = view.AccessCoin(txin.prevout);
|
||||||
if (coin.IsCoinBase()) {
|
if (coin.IsCoinBase()) {
|
||||||
fSpendsCoinbase = true;
|
fSpendsCoinbase = true;
|
||||||
|
|
@ -2040,7 +2060,11 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
// be in ConnectBlock because they require the UTXO set
|
// be in ConnectBlock because they require the UTXO set
|
||||||
prevheights.resize(tx.vin.size());
|
prevheights.resize(tx.vin.size());
|
||||||
for (size_t j = 0; j < tx.vin.size(); j++) {
|
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)) {
|
if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
|
||||||
|
|
|
||||||
|
|
@ -3080,6 +3080,10 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||||
// Notify that old coins are spent
|
// Notify that old coins are spent
|
||||||
for (const CTxIn& txin : wtxNew.tx->vin)
|
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);
|
CWalletTx &coin = mapWallet.at(txin.prevout.hash);
|
||||||
coin.BindWallet(this);
|
coin.BindWallet(this);
|
||||||
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
|
NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue