@@ -2694,6 +2694,7 @@ bool ContextualCheckInputs(
|
|||||||
|
|
||||||
if (tx.IsCoinImport())
|
if (tx.IsCoinImport())
|
||||||
{
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
|
ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
|
||||||
return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
|
return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
|
||||||
}
|
}
|
||||||
|
|||||||
454
src/miner.cpp
454
src/miner.cpp
@@ -214,272 +214,271 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
boost::optional<CTransaction> cheatSpend;
|
boost::optional<CTransaction> cheatSpend;
|
||||||
uint256 cbHash;
|
uint256 cbHash;
|
||||||
|
|
||||||
SaplingMerkleTree sapling_tree; uint64_t commission;
|
CBlockIndex* pindexPrev = 0;
|
||||||
int nHeight = 0;
|
|
||||||
const Consensus::Params &consensusParams = chainparams.GetConsensus();
|
|
||||||
|
|
||||||
CBlockIndex* pindexPrev = chainActive.LastTip();;
|
|
||||||
{
|
{
|
||||||
{ // contain lock to block generation and not staking loops.
|
ENTER_CRITICAL_SECTION(cs_main);
|
||||||
LOCK2(cs_main, mempool.cs);
|
ENTER_CRITICAL_SECTION(mempool.cs);
|
||||||
nHeight = pindexPrev->GetHeight() + 1;
|
pindexPrev = chainActive.LastTip();
|
||||||
uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, consensusParams);
|
const int nHeight = pindexPrev->GetHeight() + 1;
|
||||||
bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
|
const Consensus::Params &consensusParams = chainparams.GetConsensus();
|
||||||
|
uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, consensusParams);
|
||||||
|
bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
|
||||||
|
|
||||||
const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
|
const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
|
||||||
uint32_t proposedTime = GetAdjustedTime();
|
uint32_t proposedTime = GetAdjustedTime();
|
||||||
if (proposedTime == nMedianTimePast)
|
if (proposedTime == nMedianTimePast)
|
||||||
|
{
|
||||||
|
// too fast or stuck, this addresses the too fast issue, while moving
|
||||||
|
// forward as quickly as possible
|
||||||
|
for (int i; i < 100; i++)
|
||||||
{
|
{
|
||||||
// too fast or stuck, this addresses the too fast issue, while moving
|
proposedTime = GetAdjustedTime();
|
||||||
// forward as quickly as possible
|
if (proposedTime == nMedianTimePast)
|
||||||
for (int i; i < 100; i++)
|
MilliSleep(10);
|
||||||
{
|
|
||||||
proposedTime = GetAdjustedTime();
|
|
||||||
if (proposedTime == nMedianTimePast)
|
|
||||||
MilliSleep(10);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pblock->nTime = GetAdjustedTime();
|
}
|
||||||
|
pblock->nTime = GetAdjustedTime();
|
||||||
|
|
||||||
CCoinsViewCache view(pcoinsTip);
|
CCoinsViewCache view(pcoinsTip);
|
||||||
uint32_t expired;
|
uint32_t expired; uint64_t commission;
|
||||||
|
|
||||||
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
SaplingMerkleTree sapling_tree;
|
||||||
|
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
|
||||||
|
|
||||||
// Priority order to process transactions
|
// Priority order to process transactions
|
||||||
list<COrphan> vOrphan; // list memory doesn't move
|
list<COrphan> vOrphan; // list memory doesn't move
|
||||||
map<uint256, vector<COrphan*> > mapDependers;
|
map<uint256, vector<COrphan*> > mapDependers;
|
||||||
bool fPrintPriority = GetBoolArg("-printpriority", false);
|
bool fPrintPriority = GetBoolArg("-printpriority", false);
|
||||||
|
|
||||||
// This vector will be sorted into a priority queue:
|
// This vector will be sorted into a priority queue:
|
||||||
vector<TxPriority> vecPriority;
|
vector<TxPriority> vecPriority;
|
||||||
vecPriority.reserve(mempool.mapTx.size() + 1);
|
vecPriority.reserve(mempool.mapTx.size() + 1);
|
||||||
|
|
||||||
// now add transactions from the mem pool
|
// now add transactions from the mem pool
|
||||||
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
|
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
|
||||||
mi != mempool.mapTx.end(); ++mi)
|
mi != mempool.mapTx.end(); ++mi)
|
||||||
|
{
|
||||||
|
const CTransaction& tx = mi->GetTx();
|
||||||
|
|
||||||
|
int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
|
||||||
|
? nMedianTimePast
|
||||||
|
: pblock->GetBlockTime();
|
||||||
|
|
||||||
|
if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
|
||||||
{
|
{
|
||||||
const CTransaction& tx = mi->GetTx();
|
//fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
|
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 )
|
||||||
? nMedianTimePast
|
{
|
||||||
: pblock->GetBlockTime();
|
//fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure nHeight.%d nTime.%u vs locktime.%u\n",nHeight,(uint32_t)pblock->nTime,(uint32_t)tx.nLockTime);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
|
COrphan* porphan = NULL;
|
||||||
|
double dPriority = 0;
|
||||||
|
CAmount nTotalIn = 0;
|
||||||
|
bool fMissingInputs = false;
|
||||||
|
bool fNotarisation = false;
|
||||||
|
if (tx.IsCoinImport())
|
||||||
|
{
|
||||||
|
CAmount nValueIn = GetCoinImportValue(tx);
|
||||||
|
nTotalIn += nValueIn;
|
||||||
|
dPriority += (double)nValueIn * 1000; // flat multiplier
|
||||||
|
} else {
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight));
|
// Read prev transaction
|
||||||
continue;
|
if (!view.HaveCoins(txin.prevout.hash))
|
||||||
}
|
{
|
||||||
|
// This should never happen; all transactions in the memory
|
||||||
|
// pool should connect to either transactions in the chain
|
||||||
|
// or other transactions in the memory pool.
|
||||||
|
if (!mempool.mapTx.count(txin.prevout.hash))
|
||||||
|
{
|
||||||
|
LogPrintf("ERROR: mempool transaction missing input\n");
|
||||||
|
if (fDebug) assert("mempool transaction missing input" == 0);
|
||||||
|
fMissingInputs = true;
|
||||||
|
if (porphan)
|
||||||
|
vOrphan.pop_back();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 )
|
// Has to wait for dependencies
|
||||||
{
|
if (!porphan)
|
||||||
//fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure nHeight.%d nTime.%u vs locktime.%u\n",nHeight,(uint32_t)pblock->nTime,(uint32_t)tx.nLockTime);
|
{
|
||||||
continue;
|
// Use list for automatic deletion
|
||||||
}
|
vOrphan.push_back(COrphan(&tx));
|
||||||
|
porphan = &vOrphan.back();
|
||||||
|
}
|
||||||
|
mapDependers[txin.prevout.hash].push_back(porphan);
|
||||||
|
porphan->setDependsOn.insert(txin.prevout.hash);
|
||||||
|
nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const CCoins* coins = view.AccessCoins(txin.prevout.hash);
|
||||||
|
assert(coins);
|
||||||
|
|
||||||
COrphan* porphan = NULL;
|
CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
|
||||||
double dPriority = 0;
|
|
||||||
CAmount nTotalIn = 0;
|
|
||||||
bool fMissingInputs = false;
|
|
||||||
bool fNotarisation = false;
|
|
||||||
if (tx.IsCoinImport())
|
|
||||||
{
|
|
||||||
CAmount nValueIn = GetCoinImportValue(tx);
|
|
||||||
nTotalIn += nValueIn;
|
nTotalIn += nValueIn;
|
||||||
dPriority += (double)nValueIn * 1000; // flat multiplier
|
|
||||||
} else {
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
|
||||||
{
|
|
||||||
// Read prev transaction
|
|
||||||
if (!view.HaveCoins(txin.prevout.hash))
|
|
||||||
{
|
|
||||||
// This should never happen; all transactions in the memory
|
|
||||||
// pool should connect to either transactions in the chain
|
|
||||||
// or other transactions in the memory pool.
|
|
||||||
if (!mempool.mapTx.count(txin.prevout.hash))
|
|
||||||
{
|
|
||||||
LogPrintf("ERROR: mempool transaction missing input\n");
|
|
||||||
if (fDebug) assert("mempool transaction missing input" == 0);
|
|
||||||
fMissingInputs = true;
|
|
||||||
if (porphan)
|
|
||||||
vOrphan.pop_back();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has to wait for dependencies
|
int nConf = nHeight - coins->nHeight;
|
||||||
if (!porphan)
|
|
||||||
{
|
|
||||||
// Use list for automatic deletion
|
|
||||||
vOrphan.push_back(COrphan(&tx));
|
|
||||||
porphan = &vOrphan.back();
|
|
||||||
}
|
|
||||||
mapDependers[txin.prevout.hash].push_back(porphan);
|
|
||||||
porphan->setDependsOn.insert(txin.prevout.hash);
|
|
||||||
nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const CCoins* coins = view.AccessCoins(txin.prevout.hash);
|
|
||||||
assert(coins);
|
|
||||||
|
|
||||||
CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
|
dPriority += (double)nValueIn * nConf;
|
||||||
nTotalIn += nValueIn;
|
|
||||||
|
|
||||||
int nConf = nHeight - coins->nHeight;
|
|
||||||
|
|
||||||
dPriority += (double)nValueIn * nConf;
|
|
||||||
}
|
|
||||||
nTotalIn += tx.GetShieldedValueIn();
|
|
||||||
}
|
}
|
||||||
|
nTotalIn += tx.GetShieldedValueIn();
|
||||||
if (fMissingInputs) continue;
|
|
||||||
|
|
||||||
// Priority is sum(valuein * age) / modified_txsize
|
|
||||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
dPriority = tx.ComputePriority(dPriority, nTxSize);
|
|
||||||
|
|
||||||
uint256 hash = tx.GetHash();
|
|
||||||
mempool.ApplyDeltas(hash, dPriority, nTotalIn);
|
|
||||||
|
|
||||||
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
|
|
||||||
|
|
||||||
if (porphan)
|
|
||||||
{
|
|
||||||
porphan->dPriority = dPriority;
|
|
||||||
porphan->feeRate = feeRate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect transactions into block
|
if (fMissingInputs) continue;
|
||||||
uint64_t nBlockSize = 1000;
|
|
||||||
uint64_t nBlockTx = 0;
|
|
||||||
int64_t interest;
|
|
||||||
int nBlockSigOps = 100;
|
|
||||||
bool fSortedByFee = (nBlockPrioritySize <= 0);
|
|
||||||
|
|
||||||
TxPriorityCompare comparer(fSortedByFee);
|
// Priority is sum(valuein * age) / modified_txsize
|
||||||
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
dPriority = tx.ComputePriority(dPriority, nTxSize);
|
||||||
|
|
||||||
while (!vecPriority.empty())
|
uint256 hash = tx.GetHash();
|
||||||
|
mempool.ApplyDeltas(hash, dPriority, nTotalIn);
|
||||||
|
|
||||||
|
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
|
||||||
|
|
||||||
|
if (porphan)
|
||||||
{
|
{
|
||||||
// Take highest priority transaction off the priority queue:
|
porphan->dPriority = dPriority;
|
||||||
double dPriority = vecPriority.front().get<0>();
|
porphan->feeRate = feeRate;
|
||||||
CFeeRate feeRate = vecPriority.front().get<1>();
|
}
|
||||||
const CTransaction& tx = *(vecPriority.front().get<2>());
|
else
|
||||||
|
vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
|
||||||
|
}
|
||||||
|
|
||||||
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
// Collect transactions into block
|
||||||
vecPriority.pop_back();
|
uint64_t nBlockSize = 1000;
|
||||||
|
uint64_t nBlockTx = 0;
|
||||||
|
int64_t interest;
|
||||||
|
int nBlockSigOps = 100;
|
||||||
|
bool fSortedByFee = (nBlockPrioritySize <= 0);
|
||||||
|
|
||||||
// Size limits
|
TxPriorityCompare comparer(fSortedByFee);
|
||||||
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||||
if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx
|
|
||||||
{
|
|
||||||
//fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy limits on sigOps:
|
while (!vecPriority.empty())
|
||||||
unsigned int nTxSigOps = GetLegacySigOpCount(tx);
|
{
|
||||||
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
|
// Take highest priority transaction off the priority queue:
|
||||||
{
|
double dPriority = vecPriority.front().get<0>();
|
||||||
//fprintf(stderr,"A nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS);
|
CFeeRate feeRate = vecPriority.front().get<1>();
|
||||||
continue;
|
const CTransaction& tx = *(vecPriority.front().get<2>());
|
||||||
}
|
|
||||||
// Skip free transactions if we're past the minimum block size:
|
|
||||||
const uint256& hash = tx.GetHash();
|
|
||||||
double dPriorityDelta = 0;
|
|
||||||
CAmount nFeeDelta = 0;
|
|
||||||
mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
|
|
||||||
if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
|
|
||||||
{
|
|
||||||
//fprintf(stderr,"fee rate skip\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Prioritise by fee once past the priority size or we run out of high-priority
|
|
||||||
// transactions:
|
|
||||||
if (!fSortedByFee &&
|
|
||||||
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
|
|
||||||
{
|
|
||||||
fSortedByFee = true;
|
|
||||||
comparer = TxPriorityCompare(fSortedByFee);
|
|
||||||
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!view.HaveInputs(tx))
|
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||||
{
|
vecPriority.pop_back();
|
||||||
//fprintf(stderr,"dont have inputs\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut();
|
|
||||||
|
|
||||||
nTxSigOps += GetP2SHSigOpCount(tx, view);
|
// Size limits
|
||||||
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
|
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
{
|
if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx
|
||||||
//fprintf(stderr,"B nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS);
|
{
|
||||||
continue;
|
//fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize);
|
||||||
}
|
continue;
|
||||||
// Note that flags: we don't want to set mempool/IsStandard()
|
}
|
||||||
// policy here, but we still have to ensure that the block we
|
|
||||||
// create only contains transactions that are valid in new blocks.
|
|
||||||
CValidationState state;
|
|
||||||
PrecomputedTransactionData txdata(tx);
|
|
||||||
if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
|
|
||||||
{
|
|
||||||
//fprintf(stderr,"context failure\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
UpdateCoins(tx, view, nHeight);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const OutputDescription &outDescription, tx.vShieldedOutput) {
|
// Legacy limits on sigOps:
|
||||||
sapling_tree.append(outDescription.cm);
|
unsigned int nTxSigOps = GetLegacySigOpCount(tx);
|
||||||
}
|
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"A nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Skip free transactions if we're past the minimum block size:
|
||||||
|
const uint256& hash = tx.GetHash();
|
||||||
|
double dPriorityDelta = 0;
|
||||||
|
CAmount nFeeDelta = 0;
|
||||||
|
mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
|
||||||
|
if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"fee rate skip\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Prioritise by fee once past the priority size or we run out of high-priority
|
||||||
|
// transactions:
|
||||||
|
if (!fSortedByFee &&
|
||||||
|
((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
|
||||||
|
{
|
||||||
|
fSortedByFee = true;
|
||||||
|
comparer = TxPriorityCompare(fSortedByFee);
|
||||||
|
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||||
|
}
|
||||||
|
|
||||||
// Added
|
if (!view.HaveInputs(tx))
|
||||||
pblock->vtx.push_back(tx);
|
{
|
||||||
pblocktemplate->vTxFees.push_back(nTxFees);
|
//fprintf(stderr,"dont have inputs\n");
|
||||||
pblocktemplate->vTxSigOps.push_back(nTxSigOps);
|
continue;
|
||||||
nBlockSize += nTxSize;
|
}
|
||||||
++nBlockTx;
|
CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut();
|
||||||
nBlockSigOps += nTxSigOps;
|
|
||||||
nFees += nTxFees;
|
|
||||||
|
|
||||||
if (fPrintPriority)
|
nTxSigOps += GetP2SHSigOpCount(tx, view);
|
||||||
|
if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"B nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Note that flags: we don't want to set mempool/IsStandard()
|
||||||
|
// policy here, but we still have to ensure that the block we
|
||||||
|
// create only contains transactions that are valid in new blocks.
|
||||||
|
CValidationState state;
|
||||||
|
PrecomputedTransactionData txdata(tx);
|
||||||
|
if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
|
||||||
|
{
|
||||||
|
//fprintf(stderr,"context failure\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
UpdateCoins(tx, view, nHeight);
|
||||||
|
|
||||||
|
BOOST_FOREACH(const OutputDescription &outDescription, tx.vShieldedOutput) {
|
||||||
|
sapling_tree.append(outDescription.cm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Added
|
||||||
|
pblock->vtx.push_back(tx);
|
||||||
|
pblocktemplate->vTxFees.push_back(nTxFees);
|
||||||
|
pblocktemplate->vTxSigOps.push_back(nTxSigOps);
|
||||||
|
nBlockSize += nTxSize;
|
||||||
|
++nBlockTx;
|
||||||
|
nBlockSigOps += nTxSigOps;
|
||||||
|
nFees += nTxFees;
|
||||||
|
|
||||||
|
if (fPrintPriority)
|
||||||
|
{
|
||||||
|
LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add transactions that depend on this one to the priority queue
|
||||||
|
if (mapDependers.count(hash))
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
|
||||||
{
|
{
|
||||||
LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
|
if (!porphan->setDependsOn.empty())
|
||||||
}
|
|
||||||
|
|
||||||
// Add transactions that depend on this one to the priority queue
|
|
||||||
if (mapDependers.count(hash))
|
|
||||||
{
|
|
||||||
BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
|
|
||||||
{
|
{
|
||||||
if (!porphan->setDependsOn.empty())
|
porphan->setDependsOn.erase(hash);
|
||||||
|
if (porphan->setDependsOn.empty())
|
||||||
{
|
{
|
||||||
porphan->setDependsOn.erase(hash);
|
vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
|
||||||
if (porphan->setDependsOn.empty())
|
std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
||||||
{
|
|
||||||
vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
|
|
||||||
std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nLastBlockTx = nBlockTx;
|
nLastBlockTx = nBlockTx;
|
||||||
nLastBlockSize = nBlockSize;
|
nLastBlockSize = nBlockSize;
|
||||||
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
|
||||||
//pblock->nTime = blocktime + 1;
|
//pblock->nTime = blocktime + 1;
|
||||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||||
|
|
||||||
} // contain lock to block generation only!
|
|
||||||
|
|
||||||
int32_t stakeHeight = chainActive.Height() + 1;
|
int32_t stakeHeight = chainActive.Height() + 1;
|
||||||
|
|
||||||
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
|
//LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
|
||||||
if ( ASSETCHAINS_SYMBOL[0] != 0 && isStake )
|
if ( ASSETCHAINS_SYMBOL[0] != 0 && isStake )
|
||||||
{
|
{
|
||||||
|
LEAVE_CRITICAL_SECTION(cs_main);
|
||||||
|
LEAVE_CRITICAL_SECTION(mempool.cs);
|
||||||
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr;
|
uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr;
|
||||||
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight);
|
CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight);
|
||||||
|
|
||||||
@@ -548,6 +547,11 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
if (scriptPubKeyIn.IsPayToScriptHash() || scriptPubKeyIn.IsPayToCryptoCondition())
|
if (scriptPubKeyIn.IsPayToScriptHash() || scriptPubKeyIn.IsPayToCryptoCondition())
|
||||||
{
|
{
|
||||||
fprintf(stderr,"CreateNewBlock: attempt to add timelock to pay2sh or pay2cc\n");
|
fprintf(stderr,"CreateNewBlock: attempt to add timelock to pay2sh or pay2cc\n");
|
||||||
|
if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) )
|
||||||
|
{
|
||||||
|
LEAVE_CRITICAL_SECTION(cs_main);
|
||||||
|
LEAVE_CRITICAL_SECTION(mempool.cs);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,6 +644,11 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,"error adding notaryvin, need to create 0.0001 utxos\n");
|
fprintf(stderr,"error adding notaryvin, need to create 0.0001 utxos\n");
|
||||||
|
if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) )
|
||||||
|
{
|
||||||
|
LEAVE_CRITICAL_SECTION(cs_main);
|
||||||
|
LEAVE_CRITICAL_SECTION(mempool.cs);
|
||||||
|
}
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -654,6 +663,11 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
|
|||||||
//fprintf(stderr,"valid\n");
|
//fprintf(stderr,"valid\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) )
|
||||||
|
{
|
||||||
|
LEAVE_CRITICAL_SECTION(cs_main);
|
||||||
|
LEAVE_CRITICAL_SECTION(mempool.cs);
|
||||||
|
}
|
||||||
//fprintf(stderr,"done new block\n");
|
//fprintf(stderr,"done new block\n");
|
||||||
return pblocktemplate.release();
|
return pblocktemplate.release();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user