From 4daf942e3a242606bb6cf88a435b1c0002141cca Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Mon, 14 Dec 2020 15:04:01 +0100 Subject: [PATCH 01/10] =?UTF-8?q?Remove=20Qmix=20link=20from=20the=20Qt=20?= =?UTF-8?q?wallet=20since=20it=E2=80=99s=20not=20working=20anymore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/qt/createcontract.cpp | 7 ------- src/qt/createcontract.h | 1 - src/qt/forms/createcontract.ui | 13 ------------- 3 files changed, 21 deletions(-) diff --git a/src/qt/createcontract.cpp b/src/qt/createcontract.cpp index 86dfcb07ce..2c4666ad50 100644 --- a/src/qt/createcontract.cpp +++ b/src/qt/createcontract.cpp @@ -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")); @@ -107,12 +106,6 @@ CreateContract::~CreateContract() delete ui; } -void CreateContract::setLinkLabels() -{ - ui->labelSolidity->setOpenExternalLinks(true); - ui->labelSolidity->setText("Solidity compiler"); -} - void CreateContract::setModel(WalletModel *_model) { m_model = _model; diff --git a/src/qt/createcontract.h b/src/qt/createcontract.h index c225bd3347..b625f813e5 100644 --- a/src/qt/createcontract.h +++ b/src/qt/createcontract.h @@ -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(); diff --git a/src/qt/forms/createcontract.ui b/src/qt/forms/createcontract.ui index b4df3e0959..a55db54ab2 100644 --- a/src/qt/forms/createcontract.ui +++ b/src/qt/forms/createcontract.ui @@ -81,19 +81,6 @@ - - - - - 80 - 0 - - - - Solidity - - - From 01da1f8ff9f882ec43fe5ab692b6bc6b1a05565d Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Mon, 14 Dec 2020 15:35:06 +0100 Subject: [PATCH 02/10] Fix for issue: set focus in amount textbox --- src/qt/forms/sendcoinsentry.ui | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 18d8c699d6..c51578cded 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -60,9 +60,9 @@ - - The amount to send in the selected unit - + + The amount to send in the selected unit + @@ -93,6 +93,9 @@ + + Qt::NoFocus + Use available balance From 428c7df5a3567a21e9e5d06f8ee914fc20686f78 Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Mon, 14 Dec 2020 17:41:46 +0100 Subject: [PATCH 03/10] Add more logs to AttemptToAddContractToBlock --- src/miner.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index e2043a0ae2..6e8ca8c4bc 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -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; } @@ -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 qtumTransactions = resultConverter.first; @@ -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; } } @@ -517,6 +524,7 @@ 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; } @@ -524,13 +532,17 @@ bool BlockAssembler::AttemptToAddContractToBlock(CTxMemPool::txiter iter, uint64 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; } From 6a5c258ccba691d6e939315bbc45ae8ddbdd27fe Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Tue, 15 Dec 2020 11:11:56 +0100 Subject: [PATCH 04/10] Add erase block index --- src/net_processing.cpp | 10 ++++++++++ src/txdb.cpp | 8 ++++++++ src/txdb.h | 2 ++ 3 files changed, 20 insertions(+) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 2f24fe931f..f03f60efb0 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4579,6 +4579,7 @@ void CleanBlockIndex() SyncWithValidationInterfaceQueue(); LOCK(cs_main); + std::vector indexEraseDB; for(uint256 blockHash : indexNeedErase) { BlockMap::iterator it=::BlockIndex().find(blockHash); @@ -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"); + } + } } } diff --git a/src/txdb.cpp b/src/txdb.cpp index f6afcf48a3..a1b310ad1e 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -841,3 +841,11 @@ bool CCoinsViewDB::Upgrade() { LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE"); return !ShutdownRequested(); } + +bool CBlockTreeDB::EraseBlockIndex(const std::vector &vect) +{ + CDBBatch batch(*this); + for (std::vector::const_iterator it=vect.begin(); it!=vect.end(); it++) + batch.Erase(std::make_pair(DB_BLOCK_INDEX, *it)); + return WriteBatch(batch); +} diff --git a/src/txdb.h b/src/txdb.h index a341e511a8..5c18ef3ee1 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -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&vect); + // Block explorer database functions bool WriteAddressIndex(const std::vector > &vect); bool EraseAddressIndex(const std::vector > &vect); From 148176bbae12fcea5594cca69637bed28a026ff0 Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Tue, 15 Dec 2020 13:53:58 +0100 Subject: [PATCH 05/10] Add wallet lock when check stake --- src/miner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/miner.cpp b/src/miner.cpp index 6e8ca8c4bc..7943b82d7e 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -1197,6 +1197,7 @@ bool CheckStake(const std::shared_ptr 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"); From 70ff33c9ed0f5a2f4aeb48b266067622ca6c82e9 Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Tue, 15 Dec 2020 16:44:13 +0100 Subject: [PATCH 06/10] Add forceinitialblocksdownloadmode command line parameter --- src/init.cpp | 1 + src/validation.cpp | 4 ++++ src/validation.h | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 97c2b38cdb..bcba3bfdb3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -433,6 +433,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=", "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=", 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); diff --git a/src/validation.cpp b/src/validation.cpp index 76d3fac282..5cd928fd8e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -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; diff --git a/src/validation.h b/src/validation.h index 7c1a053f93..a09f911bdd 100644 --- a/src/validation.h +++ b/src/validation.h @@ -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 From 9dca83f88956a6c5490550873f1030d9519e092e Mon Sep 17 00:00:00 2001 From: Toni Markov Date: Wed, 16 Dec 2020 09:58:45 +0100 Subject: [PATCH 07/10] Add GUI for force initial blocks download mode --- src/qt/forms/restoredialog.ui | 9 ++++++++- src/qt/restoredialog.cpp | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/qt/forms/restoredialog.ui b/src/qt/forms/restoredialog.ui index 5a5847e98a..72e0c11c35 100644 --- a/src/qt/forms/restoredialog.ui +++ b/src/qt/forms/restoredialog.ui @@ -7,7 +7,7 @@ 0 0 580 - 400 + 429 @@ -123,6 +123,13 @@ + + + + Force initial blocks download mode - fix the blockchain data. + + + diff --git a/src/qt/restoredialog.cpp b/src/qt/restoredialog.cpp index 2d506adac0..aa4b6e9d05 100644 --- a/src/qt/restoredialog.cpp +++ b/src/qt/restoredialog.cpp @@ -38,6 +38,10 @@ QString RestoreDialog::getParam() { param = "-deleteblockchaindata"; } + else if(ui->rbInitialBlocksDownload->isChecked()) + { + param = "-forceinitialblocksdownloadmode"; + } return param; } From e8b451c5cff397107f423ef8763b8bace6e68aaf Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Wed, 16 Dec 2020 10:11:27 +0100 Subject: [PATCH 08/10] Force stop the stakers before other threads --- src/init.cpp | 8 ++++++++ src/wallet/wallet.cpp | 3 --- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index bcba3bfdb3..f22c18563a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -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& pwallet : GetWallets()) { + pwallet->StopStake(); + } +#endif + mempool.AddTransactionsUpdated(1); StopHTTPRPC(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c8192789d7..673210da71 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5915,9 +5915,6 @@ void CWallet::StopStake() } else { - auto locked_chain = chain().lock(); - LOCK(cs_wallet); - m_stop_staking_thread = true; m_enabled_staking = false; StakeQtums(false, 0); From 82259c8dc72dfba6cd6dd2452409311bfca03e60 Mon Sep 17 00:00:00 2001 From: timemarkovqtum Date: Fri, 18 Dec 2020 10:43:27 +0100 Subject: [PATCH 09/10] Fix PoS bnTarget overflow --- src/pos.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pos.cpp b/src/pos.cpp index 61d45e007f..1700068727 100644 --- a/src/pos.cpp +++ b/src/pos.cpp @@ -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: @@ -65,6 +67,10 @@ 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); @@ -72,7 +78,8 @@ bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t // Weighted target int64_t nValueIn = prevoutValue; arith_uint256 bnWeight = arith_uint256(nValueIn); - bnTarget *= bnWeight; + if(!fNoBNOverflow) + bnTarget *= bnWeight; targetProofOfStake = ArithToUint256(bnTarget); @@ -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) From cfcd82090b5d4a247c5a1e3f572b3e63869a720f Mon Sep 17 00:00:00 2001 From: Toni Markov Date: Fri, 18 Dec 2020 16:57:48 +0100 Subject: [PATCH 10/10] Add listconf RPC call --- src/rpc/misc.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/util/system.cpp | 5 +++++ src/util/system.h | 5 +++++ 3 files changed, 51 insertions(+) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index b2b7e63fbb..94fe1b4d0d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -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 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) @@ -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 diff --git a/src/util/system.cpp b/src/util/system.cpp index 98a9e28934..1d0f7079bd 100644 --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -890,6 +890,11 @@ void ArgsManager::LogArgs() const logArgsPrefix("Command-line arg:", "", m_settings.command_line_options); } +std::map> ArgsManager::getCmdArgsList() const +{ + return m_settings.command_line_options; +} + bool RenameOver(fs::path src, fs::path dest) { #ifdef WIN32 diff --git a/src/util/system.h b/src/util/system.h index b7ea267ede..bc82904a36 100644 --- a/src/util/system.h +++ b/src/util/system.h @@ -336,6 +336,11 @@ class ArgsManager */ void LogArgs() const; + /** + * Return command line arguments + */ + std::map> getCmdArgsList() const; + private: // Helper function for LogArgs(). void logArgsPrefix(