Browse Source

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.

pull/27/head
blackjok3r 5 years ago
parent
commit
9646dd709a
  1. 5
      src/main.cpp
  2. 476
      src/miner.cpp
  3. 4
      src/rpc/crosschain.cpp

5
src/main.cpp

@ -1603,7 +1603,7 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio
CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree)
{
{
LOCK2(cs_main, mempool.cs);
LOCK(mempool.cs);
uint256 hash = tx.GetHash();
double dPriorityDelta = 0;
CAmount nFeeDelta = 0;
@ -1872,7 +1872,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
nLastTime = nNow;
// -limitfreerelay unit is thousand-bytes-per-minute
// 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");
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())
{
LOCK(cs_main);
ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
return VerifyCoinImport(tx.vin[0].scriptSig, checker, state);
}

476
src/miner.cpp

@ -214,290 +214,286 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
CTransaction cheatTx;
boost::optional<CTransaction> cheatSpend;
uint256 cbHash;
SaplingMerkleTree sapling_tree; uint64_t commission;
int nHeight = 0;
const Consensus::Params &consensusParams = chainparams.GetConsensus();
CBlockIndex* pindexPrev = chainActive.LastTip();;
CBlockIndex* pindexPrev = 0;
{
{ // contain lock to block generation and not staking loops.
LOCK2(cs_main, mempool.cs);
nHeight = pindexPrev->GetHeight() + 1;
uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, consensusParams);
bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
uint32_t proposedTime = GetAdjustedTime();
if (proposedTime == nMedianTimePast)
ENTER_CRITICAL_SECTION(cs_main);
ENTER_CRITICAL_SECTION(mempool.cs);
pindexPrev = chainActive.LastTip();
const int nHeight = pindexPrev->GetHeight() + 1;
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();
uint32_t proposedTime = GetAdjustedTime();
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
// forward as quickly as possible
for (int i; i < 100; i++)
{
proposedTime = GetAdjustedTime();
if (proposedTime == nMedianTimePast)
MilliSleep(10);
}
proposedTime = GetAdjustedTime();
if (proposedTime == nMedianTimePast)
MilliSleep(10);
}
pblock->nTime = GetAdjustedTime();
CCoinsViewCache view(pcoinsTip);
uint32_t expired;
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);
}
pblock->nTime = GetAdjustedTime();
CCoinsViewCache view(pcoinsTip);
uint32_t expired; uint64_t commission;
SaplingMerkleTree 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);
// This vector will be sorted into a priority queue:
vector<TxPriority> vecPriority;
vecPriority.reserve(mempool.mapTx.size() + 1);
// now add transactions from the mem pool
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
mi != mempool.mapTx.end(); ++mi)
{
const CTransaction& tx = mi->GetTx();
// This vector will be sorted into a priority queue:
vector<TxPriority> vecPriority;
vecPriority.reserve(mempool.mapTx.size() + 1);
int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
? nMedianTimePast
: pblock->GetBlockTime();
// now add transactions from the mem pool
for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
mi != mempool.mapTx.end(); ++mi)
if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
{
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))
{
//fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight));
continue;
}
//fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight));
continue;
}
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;
}
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())
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)
{
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
if (!view.HaveCoins(txin.prevout.hash))
{
// 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))
{
// 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;
}
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
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;
// Has to wait for dependencies
if (!porphan)
{
// Use list for automatic deletion
vOrphan.push_back(COrphan(&tx));
porphan = &vOrphan.back();
}
const CCoins* coins = view.AccessCoins(txin.prevout.hash);
assert(coins);
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;
nTotalIn += nValueIn;
CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
nTotalIn += nValueIn;
int nConf = nHeight - coins->nHeight;
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 )
// 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)) )
{
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++;
}
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 )
fNotarisation = true;
nTotalIn += tx.GetShieldedValueIn();
dPriority += (double)nValueIn * nConf;
}
if ( NUM_NOTARIES != 0 && numNotaryVins >= NUM_NOTARIES / 5 )
fNotarisation = true;
nTotalIn += tx.GetShieldedValueIn();
}
if (fMissingInputs) continue;
if (fMissingInputs) continue;
// Priority is sum(valuein * age) / modified_txsize
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
dPriority = tx.ComputePriority(dPriority, nTxSize);
// 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);
uint256 hash = tx.GetHash();
mempool.ApplyDeltas(hash, dPriority, nTotalIn);
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
if (fNotarisation) {
dPriority = 1e16;
fprintf(stderr, "Notarisation.%s set to maximum priority.\n",hash.ToString().c_str());
}
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())));
if (porphan)
{
porphan->dPriority = dPriority;
porphan->feeRate = feeRate;
}
else
vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
}
// Collect transactions into block
uint64_t nBlockSize = 1000;
uint64_t nBlockTx = 0;
int64_t interest;
int nBlockSigOps = 100;
bool fSortedByFee = (nBlockPrioritySize <= 0);
// Collect transactions into block
uint64_t nBlockSize = 1000;
uint64_t nBlockTx = 0;
int64_t interest;
int nBlockSigOps = 100;
bool fSortedByFee = (nBlockPrioritySize <= 0);
TxPriorityCompare comparer(fSortedByFee);
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
TxPriorityCompare comparer(fSortedByFee);
std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
while (!vecPriority.empty())
{
// Take highest priority transaction off the priority queue:
double dPriority = vecPriority.front().get<0>();
CFeeRate feeRate = vecPriority.front().get<1>();
const CTransaction& tx = *(vecPriority.front().get<2>());
while (!vecPriority.empty())
{
// Take highest priority transaction off the priority queue:
double dPriority = vecPriority.front().get<0>();
CFeeRate feeRate = vecPriority.front().get<1>();
const CTransaction& tx = *(vecPriority.front().get<2>());
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
vecPriority.pop_back();
std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
vecPriority.pop_back();
// Size limits
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
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;
}
// Size limits
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
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:
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);
}
// Legacy limits on sigOps:
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);
}
if (!view.HaveInputs(tx))
{
//fprintf(stderr,"dont have inputs\n");
continue;
}
CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut();
if (!view.HaveInputs(tx))
{
//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);
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);
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);
}
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;
// 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());
}
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))
// Add transactions that depend on this one to the priority queue
if (mapDependers.count(hash))
{
BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
{
BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
if (!porphan->setDependsOn.empty())
{
if (!porphan->setDependsOn.empty())
porphan->setDependsOn.erase(hash);
if (porphan->setDependsOn.empty())
{
porphan->setDependsOn.erase(hash);
if (porphan->setDependsOn.empty())
{
vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
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;
nLastBlockSize = nBlockSize;
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
//pblock->nTime = blocktime + 1;
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
} // contain lock to block generation only!
nLastBlockTx = nBlockTx;
nLastBlockSize = nBlockSize;
blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
//pblock->nTime = blocktime + 1;
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
int32_t stakeHeight = chainActive.Height() + 1;
@ -524,7 +520,11 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
blocktime = GetAdjustedTime();
//if ( 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);
ENTER_CRITICAL_SECTION(cs_main);
ENTER_CRITICAL_SECTION(mempool.cs);
}
if ( siglen > 0 )
@ -678,6 +678,8 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount,
//fprintf(stderr,"valid\n");
}
}
LEAVE_CRITICAL_SECTION(cs_main);
LEAVE_CRITICAL_SECTION(mempool.cs);
//fprintf(stderr,"done new block\n");
return pblocktemplate.release();
}

4
src/rpc/crosschain.cpp

@ -163,7 +163,7 @@ UniValue calc_MoM(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)
throw runtime_error(
"migrate_converttoexport rawTx dest_symbol\n"
@ -205,7 +205,7 @@ UniValue migrate_converttoexport(const UniValue& params, bool fHelp)
ptr = rawproof.data();
for (i=0; i<rawproof.size(); 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);
ret.push_back(Pair("payouts", HexStr(E_MARSHAL(ss << tx.vout))));
tx.vout.clear();

Loading…
Cancel
Save