Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fixes for issues #878

Merged
merged 10 commits into from
Dec 18, 2020
Merged
9 changes: 9 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ void Shutdown(NodeContext& node)
/// Be sure that anything that writes files or flushes caches only does this if the respective
/// module was initialized.
util::ThreadRename("qtum-shutoff");

#ifdef ENABLE_WALLET
// Force stop the stakers before any other components
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
pwallet->StopStake();
}
#endif

mempool.AddTransactionsUpdated(1);

StopHTTPRPC();
Expand Down Expand Up @@ -433,6 +441,7 @@ void SetupServerArgs()
gArgs.AddArg("-logevents", strprintf("Maintain a full EVM log index, used by searchlogs and gettransactionreceipt rpc calls (default: %u)", DEFAULT_LOGEVENTS), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-addrindex", strprintf("Maintain a full address index (default: %u)", DEFAULT_ADDRINDEX), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-deleteblockchaindata", "Delete the local copy of the block chain data", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
gArgs.AddArg("-forceinitialblocksdownloadmode", strprintf("Force initial blocks download mode for the node (default: %u)", DEFAULT_FORCE_INITIAL_BLOCKS_DOWNLOAD_MODE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);

gArgs.AddArg("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes.", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
gArgs.AddArg("-asmap=<file>", strprintf("Specify asn mapping used for bucketing of the peers (default: %s). Relative paths will be prefixed by the net-specific datadir location.", DEFAULT_ASMAP_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
Expand Down
17 changes: 15 additions & 2 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ bool BlockAssembler::AttemptToAddContractToBlock(CTxMemPool::txiter iter, uint64
}
if (gArgs.GetBoolArg("-disablecontractstaking", false))
{
// Contract staking is disabled for the staker
return false;
}

Expand All @@ -491,6 +492,7 @@ bool BlockAssembler::AttemptToAddContractToBlock(CTxMemPool::txiter iter, uint64
if(!convert.extractionQtumTransactions(resultConverter)){
//this check already happens when accepting txs into mempool
//therefore, this can only be triggered by using raw transactions on the staker itself
LogPrintf("AttemptToAddContractToBlock(): Fail to extract contacts from tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}
std::vector<QtumTransaction> qtumTransactions = resultConverter.first;
Expand All @@ -499,15 +501,20 @@ bool BlockAssembler::AttemptToAddContractToBlock(CTxMemPool::txiter iter, uint64
txGas += qtumTransaction.gas();
if(txGas > txGasLimit) {
// Limit the tx gas limit by the soft limit if such a limit has been specified.
LogPrintf("AttemptToAddContractToBlock(): The gas needed is bigger than -staker-max-tx-gas-limit for the contract tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}

if(bceResult.usedGas + qtumTransaction.gas() > softBlockGasLimit){
//if this transaction's gasLimit could cause block gas limit to be exceeded, then don't add it
// If this transaction's gasLimit could cause block gas limit to be exceeded, then don't add it
// Log if the contract is the only contract tx
if(bceResult.usedGas == 0)
LogPrintf("AttemptToAddContractToBlock(): The gas needed is bigger than -staker-soft-block-gas-limit for the contract tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}
if(qtumTransaction.gasPrice() < minGasPrice){
//if this transaction's gasPrice is less than the current DGP minGasPrice don't add it
LogPrintf("AttemptToAddContractToBlock(): The gas price is less than -staker-min-tx-gas-price for the contract tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}
}
Expand All @@ -517,20 +524,25 @@ bool BlockAssembler::AttemptToAddContractToBlock(CTxMemPool::txiter iter, uint64
//error, don't add contract
globalState->setRoot(oldHashStateRoot);
globalState->setRootUTXO(oldHashUTXORoot);
LogPrintf("AttemptToAddContractToBlock(): Perform byte code fails for the contract tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}

ByteCodeExecResult testExecResult;
if(!exec.processingResults(testExecResult)){
globalState->setRoot(oldHashStateRoot);
globalState->setRootUTXO(oldHashUTXORoot);
LogPrintf("AttemptToAddContractToBlock(): Processing results fails for the contract tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}

if(bceResult.usedGas + testExecResult.usedGas > softBlockGasLimit){
//if this transaction could cause block gas limit to be exceeded, then don't add it
// If this transaction could cause block gas limit to be exceeded, then don't add it
globalState->setRoot(oldHashStateRoot);
globalState->setRootUTXO(oldHashUTXORoot);
// Log if the contract is the only contract tx
if(bceResult.usedGas == 0)
LogPrintf("AttemptToAddContractToBlock(): The gas used is bigger than -staker-soft-block-gas-limit for the contract tx %s\n", iter->GetTx().GetHash().ToString());
return false;
}

Expand Down Expand Up @@ -1185,6 +1197,7 @@ bool CheckStake(const std::shared_ptr<const CBlock> pblock, CWallet& wallet)
if (pblock->hashPrevBlock != ::ChainActive().Tip()->GetBlockHash())
return error("CheckStake() : generated block is stale");

LOCK(wallet.cs_wallet);
for(const CTxIn& vin : pblock->vtx[1]->vin) {
if (wallet.IsSpent(vin.prevout.hash, vin.prevout.n)) {
return error("CheckStake() : generated block became invalid due to stake UTXO being spent");
Expand Down
10 changes: 10 additions & 0 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4579,6 +4579,7 @@ void CleanBlockIndex()
SyncWithValidationInterfaceQueue();

LOCK(cs_main);
std::vector<uint256> indexEraseDB;
for(uint256 blockHash : indexNeedErase)
{
BlockMap::iterator it=::BlockIndex().find(blockHash);
Expand All @@ -4589,9 +4590,18 @@ void CleanBlockIndex()
{
delete pindex;
::BlockIndex().erase(it);
indexEraseDB.push_back(blockHash);
}
}
}

if(pblocktree)
{
if(!pblocktree->EraseBlockIndex(indexEraseDB))
{
LogPrintf("Fail to erase block indexes.\n");
}
}
}
}

Expand Down
15 changes: 13 additions & 2 deletions src/pos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ uint256 ComputeStakeModifier(const CBlockIndex* pindexPrev, const uint256& kerne
// coinstake must meet hash target according to the protocol:
// kernel (input 0) must meet the formula
// hash(nStakeModifier + blockFrom.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) < bnTarget * nWeight
// kernel (input 0) must meet the formula after overflow fix in reduce block time fork
// hash(nStakeModifier + blockFrom.nTime + txPrev.vout.hash + txPrev.vout.n + nTime) / nWeight < bnTarget
// this ensures that the chance of getting a coinstake is proportional to the
// amount of coins one owns.
// The reason this hash is chosen is the following:
Expand All @@ -65,14 +67,19 @@ bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t
if (nTimeBlock < blockFromTime) // Transaction timestamp violation
return error("CheckStakeKernelHash() : nTime violation");

// Get height
int nHeight = pindexPrev->nHeight + 1;
bool fNoBNOverflow = nHeight >= Params().GetConsensus().nReduceBlocktimeHeight;

// Base target
arith_uint256 bnTarget;
bnTarget.SetCompact(nBits);

// Weighted target
int64_t nValueIn = prevoutValue;
arith_uint256 bnWeight = arith_uint256(nValueIn);
bnTarget *= bnWeight;
if(!fNoBNOverflow)
bnTarget *= bnWeight;

targetProofOfStake = ArithToUint256(bnTarget);

Expand All @@ -93,7 +100,11 @@ bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t
}

// Now check if proof-of-stake hash meets target protocol
if (UintToArith256(hashProofOfStake) > bnTarget)
arith_uint256 bnProofOfStake = UintToArith256(hashProofOfStake);
if(fNoBNOverflow)
bnProofOfStake /= bnWeight;

if (bnProofOfStake > bnTarget)
return false;

if (LogInstance().WillLogCategory(BCLog::COINSTAKE) && !fPrintProofOfStake)
Expand Down
7 changes: 0 additions & 7 deletions src/qt/createcontract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ CreateContract::CreateContract(const PlatformStyle *platformStyle, QWidget *pare
// Set stylesheet
SetObjectStyleSheet(ui->pushButtonClearAll, StyleSheetNames::ButtonDark);

setLinkLabels();
m_ABIFunctionField = new ABIFunctionField(platformStyle, ABIFunctionField::Create, ui->scrollAreaConstructor);
ui->scrollAreaConstructor->setWidget(m_ABIFunctionField);
ui->labelBytecode->setToolTip(tr("The bytecode of the contract"));
Expand Down Expand Up @@ -107,12 +106,6 @@ CreateContract::~CreateContract()
delete ui;
}

void CreateContract::setLinkLabels()
{
ui->labelSolidity->setOpenExternalLinks(true);
ui->labelSolidity->setText("<a href=\"https://qmix.qtum.org/\">Solidity compiler</a>");
}

void CreateContract::setModel(WalletModel *_model)
{
m_model = _model;
Expand Down
1 change: 0 additions & 1 deletion src/qt/createcontract.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class CreateContract : public QWidget
explicit CreateContract(const PlatformStyle *platformStyle, QWidget *parent = 0);
~CreateContract();

void setLinkLabels();
void setClientModel(ClientModel *clientModel);
void setModel(WalletModel *model);
bool isValidBytecode();
Expand Down
13 changes: 0 additions & 13 deletions src/qt/forms/createcontract.ui
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,6 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelSolidity">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Solidity</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
Expand Down
9 changes: 8 additions & 1 deletion src/qt/forms/restoredialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>580</width>
<height>400</height>
<height>429</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -123,6 +123,13 @@
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbInitialBlocksDownload">
<property name="text">
<string>Force initial blocks download mode - fix the blockchain data.</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbLocalDeleteData">
<property name="sizePolicy">
Expand Down
9 changes: 6 additions & 3 deletions src/qt/forms/sendcoinsentry.ui
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@
<layout class="QHBoxLayout" name="horizontalLayoutAmount" stretch="0,0,1,0">
<item>
<widget class="BitcoinAmountField" name="payAmount">
<property name="toolTip">
<string>The amount to send in the selected unit</string>
</property>
<property name="toolTip">
<string>The amount to send in the selected unit</string>
</property>
</widget>
</item>
<item>
Expand Down Expand Up @@ -93,6 +93,9 @@
</item>
<item>
<widget class="QPushButton" name="useAvailableBalanceButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Use available balance</string>
</property>
Expand Down
4 changes: 4 additions & 0 deletions src/qt/restoredialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ QString RestoreDialog::getParam()
{
param = "-deleteblockchaindata";
}
else if(ui->rbInitialBlocksDownload->isChecked())
{
param = "-forceinitialblocksdownloadmode";
}

return param;
}
Expand Down
41 changes: 41 additions & 0 deletions src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,46 @@ UniValue getaddresstxids(const JSONRPCRequest& request)

return result;
}

UniValue listconf(const JSONRPCRequest& request)
{
RPCHelpMan{"listconf",
"\nReturns the current options that qtumd was started with.\n",
{},
RPCResult{
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "param1", "Value for param1"},
{RPCResult::Type::STR, "param2", "Value for param2"},
{RPCResult::Type::STR, "param3", "Value for param3"},
}
},
RPCExamples{
HelpExampleCli("listconf", "")
+ HelpExampleRpc("listconf", "")
},
}.Check(request);

UniValue ret(UniValue::VOBJ);

for (const auto& arg : gArgs.getCmdArgsList()) {
UniValue listValues(UniValue::VARR);
for (const auto& value : arg.second) {
Optional<unsigned int> flags = gArgs.GetArgFlags('-' + arg.first);
if (flags) {
UniValue value_param = (*flags & gArgs.SENSITIVE) ? "****" : value;
listValues.push_back(value_param);
}
}

int size = listValues.size();
if(size > 0)
{
ret.pushKV(arg.first, size == 1 ? listValues[0] : listValues);
}
}
return ret;
}
///////////////////////////////////////////////////////////////////////

static UniValue createmultisig(const JSONRPCRequest& request)
Expand Down Expand Up @@ -1300,6 +1340,7 @@ static const CRPCCommand commands[] =
{ "util", "getaddressmempool", &getaddressmempool, {"addresses"} },
{ "util", "getblockhashes", &getblockhashes, {"high","low","options"} },
{ "util", "getspentinfo", &getspentinfo, {"argument"} },
{ "util", "listconf", &listconf, {} },
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
// clang-format on
Expand Down
8 changes: 8 additions & 0 deletions src/txdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,3 +841,11 @@ bool CCoinsViewDB::Upgrade() {
LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
return !ShutdownRequested();
}

bool CBlockTreeDB::EraseBlockIndex(const std::vector<uint256> &vect)
{
CDBBatch batch(*this);
for (std::vector<uint256>::const_iterator it=vect.begin(); it!=vect.end(); it++)
batch.Erase(std::make_pair(DB_BLOCK_INDEX, *it));
return WriteBatch(batch);
}
2 changes: 2 additions & 0 deletions src/txdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ class CBlockTreeDB : public CDBWrapper
bool ReadDelegateIndex(unsigned int height, uint160& address, uint8_t& fee);
bool EraseDelegateIndex(unsigned int height);

bool EraseBlockIndex(const std::vector<uint256>&vect);

// Block explorer database functions
bool WriteAddressIndex(const std::vector<std::pair<CAddressIndexKey, CAmount> > &vect);
bool EraseAddressIndex(const std::vector<std::pair<CAddressIndexKey, CAmount> > &vect);
Expand Down
5 changes: 5 additions & 0 deletions src/util/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,11 @@ void ArgsManager::LogArgs() const
logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
}

std::map<std::string, std::vector<util::SettingsValue>> ArgsManager::getCmdArgsList() const
{
return m_settings.command_line_options;
}

bool RenameOver(fs::path src, fs::path dest)
{
#ifdef WIN32
Expand Down
5 changes: 5 additions & 0 deletions src/util/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ class ArgsManager
*/
void LogArgs() const;

/**
* Return command line arguments
*/
std::map<std::string, std::vector<util::SettingsValue>> getCmdArgsList() const;

private:
// Helper function for LogArgs().
void logArgsPrefix(
Expand Down
4 changes: 4 additions & 0 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,10 @@ void CChainState::InitCoinsCache()
//
bool CChainState::IsInitialBlockDownload() const
{
static bool fForceInitialBlocksDownloadMode = gArgs.GetBoolArg("-forceinitialblocksdownloadmode", DEFAULT_FORCE_INITIAL_BLOCKS_DOWNLOAD_MODE);
if(fForceInitialBlocksDownloadMode)
return true;

// Optimization: pre-test latch before taking the lock.
if (m_cached_finished_ibd.load(std::memory_order_relaxed))
return false;
Expand Down
3 changes: 3 additions & 0 deletions src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ static const size_t MAX_CONTRACT_VOUTS = 1000; // qtum
//! -stakingminutxovalue default
static const CAmount DEFAULT_STAKING_MIN_UTXO_VALUE = 100 * COIN;

//! -forceinitialblocksdownloadmode default
static const bool DEFAULT_FORCE_INITIAL_BLOCKS_DOWNLOAD_MODE = false;

struct BlockHasher
{
// this used to call `GetCheapHash()` in uint256, which was later moved; the
Expand Down
Loading