revert changes to import priority. Re-try flat transaction fee. Change miner lock to something safer. Add lock cs_main to import validation when accepting to mempool.

This commit is contained in:
blackjok3r
2019-01-10 01:35:18 +08:00
parent 7bc81ad0de
commit 9646dd709a
3 changed files with 249 additions and 246 deletions

View File

@@ -1603,7 +1603,7 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
{ {
{ {
LOCK2(cs_main, mempool.cs); LOCK(mempool.cs);
uint256 hash = tx.GetHash(); uint256 hash = tx.GetHash();
double dPriorityDelta = 0; double dPriorityDelta = 0;
CAmount nFeeDelta = 0; CAmount nFeeDelta = 0;
@@ -1872,7 +1872,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
nLastTime = nNow; nLastTime = nNow;
// -limitfreerelay unit is thousand-bytes-per-minute // -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB // At default rate it would take over a month to fill 1GB
if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*50000) if (dFreeCount >= GetArg("-limitfreerelay", 15)*10*1000)
{ {
fprintf(stderr,"accept failure.7\n"); fprintf(stderr,"accept failure.7\n");
return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction"); return state.DoS(0, error("AcceptToMemoryPool: free transaction rejected by rate limiter"), REJECT_INSUFFICIENTFEE, "rate limited free transaction");
@@ -2709,6 +2709,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);
} }

View File

@@ -214,290 +214,286 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
CTransaction cheatTx; CTransaction cheatTx;
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;
SaplingMerkleTree sapling_tree;
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree)); // Priority order to process transactions
list<COrphan> vOrphan; // list memory doesn't move
map<uint256, vector<COrphan*> > mapDependers;
bool fPrintPriority = GetBoolArg("-printpriority", false);
// Priority order to process transactions // This vector will be sorted into a priority queue:
list<COrphan> vOrphan; // list memory doesn't move vector<TxPriority> vecPriority;
map<uint256, vector<COrphan*> > mapDependers; vecPriority.reserve(mempool.mapTx.size() + 1);
bool fPrintPriority = GetBoolArg("-printpriority", false);
// This vector will be sorted into a priority queue: // now add transactions from the mem pool
vector<TxPriority> vecPriority; for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
vecPriority.reserve(mempool.mapTx.size() + 1); mi != mempool.mapTx.end(); ++mi)
{
const CTransaction& tx = mi->GetTx();
// now add transactions from the mem pool int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); ? nMedianTimePast
mi != mempool.mapTx.end(); ++mi) : 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); // burn amount
nTotalIn += nValueIn;
dPriority += (double)nValueIn * 1000; // flat multiplier... max = 1e16.
} else {
int numNotaryVins = 0; bool fToCryptoAddress = false;
if ( komodo_is_notarytx(tx) == 1 )
fToCryptoAddress = true;
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))
}
if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 )
{
//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;
}
COrphan* porphan = NULL;
double dPriority = 0;
CAmount nTotalIn = 0;
bool fMissingInputs = false;
bool fNotarisation = false;
if (tx.IsCoinImport())
{
CAmount nValueIn = GetCoinImportValue(tx); // burn amount
//tx.vout[1].nValue import amount
//nTotalIn += nValueIn;
dPriority += 1e16; //(double)nValueIn * 1000; // flat multiplier
} else {
int numNotaryVins = 0; bool fToCryptoAddress = false;
if ( komodo_is_notarytx(tx) == 1 )
fToCryptoAddress = true;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{ {
// Read prev transaction // This should never happen; all transactions in the memory
if (!view.HaveCoins(txin.prevout.hash)) // pool should connect to either transactions in the chain
// or other transactions in the memory pool.
if (!mempool.mapTx.count(txin.prevout.hash))
{ {
// This should never happen; all transactions in the memory LogPrintf("ERROR: mempool transaction missing input\n");
// pool should connect to either transactions in the chain if (fDebug) assert("mempool transaction missing input" == 0);
// or other transactions in the memory pool. fMissingInputs = true;
if (!mempool.mapTx.count(txin.prevout.hash)) if (porphan)
{ vOrphan.pop_back();
LogPrintf("ERROR: mempool transaction missing input\n"); break;
if (fDebug) assert("mempool transaction missing input" == 0);
fMissingInputs = true;
if (porphan)
vOrphan.pop_back();
break;
}
// Has to wait for dependencies
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; // Has to wait for dependencies
nTotalIn += nValueIn; if (!porphan)
int nConf = nHeight - coins->nHeight;
// This is to test is a tx is a notarisation and assign it max priotity.
if ( fToCryptoAddress && NOTARYADDRS[0][0] != 0 && NUM_NOTARIES != 0 )
{ {
uint256 hash; CTransaction tx1; CTxDestination address; // Use list for automatic deletion
if ( GetTransaction(txin.prevout.hash,tx1,hash,false) && (ExtractDestination(tx1.vout[txin.prevout.n].scriptPubKey, address)) ) vOrphan.push_back(COrphan(&tx));
{ porphan = &vOrphan.back();
for (int i = 0; i < NUM_NOTARIES; i++)
if ( strcmp(NOTARYADDRS[i],CBitcoinAddress(address).ToString().c_str()) == 0 )
numNotaryVins++;
}
} }
dPriority += (double)nValueIn * nConf; 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;
} }
if ( NUM_NOTARIES != 0 && numNotaryVins >= NUM_NOTARIES / 5 ) const CCoins* coins = view.AccessCoins(txin.prevout.hash);
fNotarisation = true; assert(coins);
nTotalIn += tx.GetShieldedValueIn();
CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
nTotalIn += nValueIn;
int nConf = nHeight - coins->nHeight;
// This is to test is a tx is a notarisation and assign it max priotity.
if ( fToCryptoAddress && NOTARYADDRS[0][0] != 0 && NUM_NOTARIES != 0 )
{
uint256 hash; CTransaction tx1; CTxDestination address;
if ( GetTransaction(txin.prevout.hash,tx1,hash,false) && (ExtractDestination(tx1.vout[txin.prevout.n].scriptPubKey, address)) )
{
for (int i = 0; i < NUM_NOTARIES; i++)
if ( strcmp(NOTARYADDRS[i],CBitcoinAddress(address).ToString().c_str()) == 0 )
numNotaryVins++;
}
}
dPriority += (double)nValueIn * nConf;
} }
if ( NUM_NOTARIES != 0 && numNotaryVins >= NUM_NOTARIES / 5 )
if (fMissingInputs) continue; fNotarisation = true;
nTotalIn += tx.GetShieldedValueIn();
// 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 (fNotarisation) {
dPriority = 1e16;
fprintf(stderr, "Notarisation.%s set to maximum priority.\n",hash.ToString().c_str());
}
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 (fNotarisation) {
dPriority = 1e16;
//fprintf(stderr, "Notarisation.%s set to maximum priority.\n",hash.ToString().c_str());
}
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;
@@ -524,7 +520,11 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
blocktime = GetAdjustedTime(); blocktime = GetAdjustedTime();
//if ( blocktime > pindexPrev->GetMedianTimePast()+60 ) //if ( blocktime > pindexPrev->GetMedianTimePast()+60 )
// blocktime = pindexPrev->GetMedianTimePast() + 60; // blocktime = pindexPrev->GetMedianTimePast() + 60;
LEAVE_CRITICAL_SECTION(cs_main);
LEAVE_CRITICAL_SECTION(mempool.cs);
siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig); siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig);
ENTER_CRITICAL_SECTION(cs_main);
ENTER_CRITICAL_SECTION(mempool.cs);
} }
if ( siglen > 0 ) if ( siglen > 0 )
@@ -678,6 +678,8 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
//fprintf(stderr,"valid\n"); //fprintf(stderr,"valid\n");
} }
} }
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();
} }

View File

@@ -163,7 +163,7 @@ UniValue calc_MoM(const UniValue& params, bool fHelp)
UniValue migrate_converttoexport(const UniValue& params, bool fHelp) UniValue migrate_converttoexport(const UniValue& params, bool fHelp)
{ {
std::vector<uint8_t> rawproof; uint8_t *ptr; uint8_t i; uint32_t ccid = ASSETCHAINS_CC; std::vector<uint8_t> rawproof; uint8_t *ptr; uint8_t i; uint32_t ccid = ASSETCHAINS_CC; uint64_t txfee = 10000;
if (fHelp || params.size() != 2) if (fHelp || params.size() != 2)
throw runtime_error( throw runtime_error(
"migrate_converttoexport rawTx dest_symbol\n" "migrate_converttoexport rawTx dest_symbol\n"
@@ -205,7 +205,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp)
ptr = rawproof.data(); ptr = rawproof.data();
for (i=0; i<rawproof.size(); i++) for (i=0; i<rawproof.size(); i++)
ptr[i] = ASSETCHAINS_SYMBOL[i]; ptr[i] = ASSETCHAINS_SYMBOL[i];
CTxOut burnOut = MakeBurnOutput(burnAmount, ccid, targetSymbol, tx.vout,rawproof); CTxOut burnOut = MakeBurnOutput(burnAmount+txfee, ccid, targetSymbol, tx.vout,rawproof);
UniValue ret(UniValue::VOBJ); UniValue ret(UniValue::VOBJ);
ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout)))); ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout))));
tx.vout.clear(); tx.vout.clear();