diff --git a/src/Makefile.am b/src/Makefile.am index e8da8e9136..6e41d3693c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -344,6 +344,9 @@ BITCOIN_CORE_H = \ util/ui_change_type.h \ util/vector.h \ util/convert.h \ + util/signstr.h \ + util/contractabi.h \ + util/tokenstr.h \ validation.h \ validationinterface.h \ versionbits.h \ @@ -361,6 +364,7 @@ BITCOIN_CORE_H = \ wallet/receive.h \ wallet/rpc/util.h \ wallet/rpc/wallet.h \ + wallet/rpc/addresses.h \ wallet/salvage.h \ wallet/scriptpubkeyman.h \ wallet/spend.h \ @@ -377,7 +381,13 @@ BITCOIN_CORE_H = \ zmq/zmqnotificationinterface.h \ zmq/zmqpublishnotifier.h \ zmq/zmqrpc.h \ - zmq/zmqutil.h + zmq/zmqutil.h \ + qtum/posutils.h \ + qtum/qtumtransaction.h \ + qtum/qtumutils.h \ + qtum/qtumtoken.h \ + qtum/qtumledger.h \ + qtum/delegationutils.h obj/build.h: FORCE @@ -479,6 +489,7 @@ libbitcoin_node_a_SOURCES = \ validation.cpp \ validationinterface.cpp \ versionbits.cpp \ + qtum/qtumledger.cpp \ $(BITCOIN_CORE_H) if ENABLE_WALLET @@ -721,6 +732,10 @@ libbitcoin_common_a_SOURCES = \ script/signingprovider.cpp \ script/solver.cpp \ warnings.cpp \ + qtum/qtumutils.cpp \ + qtum/qtumtoken.cpp \ + qtum/delegationutils.cpp \ + util/contractabi.cpp \ libff/libff/algebra/curves/public_params.hpp \ libff/libff/algebra/curves/curve_utils.hpp \ evmone/include/evmone/evmone.h \ @@ -960,6 +975,7 @@ libqtum_util_a_SOURCES = \ util/string.cpp \ util/time.cpp \ util/tokenpipe.cpp \ + util/tokenstr.cpp \ $(BITCOIN_CORE_H) # diff --git a/src/bench/.gitignore b/src/bench/.gitignore index e231fe4cab..2a294d9457 100644 --- a/src/bench/.gitignore +++ b/src/bench/.gitignore @@ -1 +1 @@ -bench_bitcoin +bench_qtum diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 8c421c3fec..60eb89a7ee 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -69,12 +69,12 @@ int main(int argc, char** argv) } if (HelpRequested(argsman)) { - std::cout << "Usage: bench_bitcoin [options]\n" + std::cout << "Usage: bench_qtum [options]\n" "\n" << argsman.GetHelpMessage() << "Description:\n" "\n" - " bench_bitcoin executes microbenchmarks. The quality of the benchmark results\n" + " bench_qtum executes microbenchmarks. The quality of the benchmark results\n" " highly depend on the stability of the machine. It can sometimes be difficult\n" " to get stable, repeatable results, so here are a few tips:\n" "\n" @@ -88,7 +88,7 @@ int main(int argc, char** argv) " * If results are still not reliable, increase runtime with e.g.\n" " -min-time=5000 to let a benchmark run for at least 5 seconds.\n" "\n" - " * bench_bitcoin uses nanobench [3] for which there is extensive\n" + " * bench_qtum uses nanobench [3] for which there is extensive\n" " documentation available online.\n" "\n" "Environment Variables:\n" @@ -96,12 +96,12 @@ int main(int argc, char** argv) " To attach a profiler you can run a benchmark in endless mode. This can be\n" " done with the environment variable NANOBENCH_ENDLESS. E.g. like so:\n" "\n" - " NANOBENCH_ENDLESS=MuHash ./bench_bitcoin -filter=MuHash\n" + " NANOBENCH_ENDLESS=MuHash ./bench_qtum -filter=MuHash\n" "\n" " In rare cases it can be useful to suppress stability warnings. This can be\n" " done with the environment variable NANOBENCH_SUPPRESS_WARNINGS, e.g:\n" "\n" - " NANOBENCH_SUPPRESS_WARNINGS=1 ./bench_bitcoin\n" + " NANOBENCH_SUPPRESS_WARNINGS=1 ./bench_qtum\n" "\n" "Notes:\n" "\n" diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp index ba8ec16119..681c26181c 100644 --- a/src/bench/block_assemble.cpp +++ b/src/bench/block_assemble.cpp @@ -24,14 +24,15 @@ static void AssembleBlock(benchmark::Bench& bench) witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE); // Collect some loose transactions that spend the coinbases of our mined blocks - constexpr size_t NUM_BLOCKS{200}; - std::array txs; + constexpr size_t NUM_BLOCKS{2100}; + constexpr size_t coinbaseMaturity = 2000; + std::array txs; for (size_t b{0}; b < NUM_BLOCKS; ++b) { CMutableTransaction tx; tx.vin.emplace_back(MineBlock(test_setup->m_node, P2WSH_OP_TRUE)); tx.vin.back().scriptWitness = witness; - tx.vout.emplace_back(1337, P2WSH_OP_TRUE); - if (NUM_BLOCKS - b >= COINBASE_MATURITY) + tx.vout.emplace_back(101337, P2WSH_OP_TRUE); + if (NUM_BLOCKS - b >= coinbaseMaturity) txs.at(b) = MakeTransactionRef(tx); } { diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index 14b8a275f0..0b1fa8fd64 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -11,6 +11,7 @@ #include #include #include +#include // These are the two major time-sinks which happen after we have fully received // a block off the wire, but before we can relay the block on to peers using @@ -38,6 +39,8 @@ static void DeserializeAndCheckBlockTest(benchmark::Bench& bench) ArgsManager bench_args; const auto chainParams = CreateChainParams(bench_args, ChainType::MAIN); + const auto testing_setup = MakeNoLogFileContext(ChainType::MAIN); + Chainstate& chainstate = testing_setup->m_node.chainman->ActiveChainstate(); bench.unit("block").run([&] { CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp index a1c8d4d942..0d4d0a7d49 100644 --- a/src/bench/duplicate_inputs.cpp +++ b/src/bench/duplicate_inputs.cpp @@ -31,6 +31,7 @@ static void DuplicateInputs(benchmark::Bench& bench) block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus()); block.nNonce = 0; auto nHeight = pindexPrev->nHeight + 1; + Chainstate& chainstate = testing_setup->m_node.chainman->ActiveChainstate(); // Make a coinbase TX coinbaseTx.vin.resize(1); @@ -45,7 +46,7 @@ static void DuplicateInputs(benchmark::Bench& bench) naughtyTx.vout[0].nValue = 0; naughtyTx.vout[0].scriptPubKey = SCRIPT_PUB; - uint64_t n_inputs = (((MAX_BLOCK_SERIALIZED_SIZE / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).GetTotalSize() + CTransaction(naughtyTx).GetTotalSize())) / 41) - 100; + uint64_t n_inputs = (((dgpMaxBlockSerSize / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).GetTotalSize() + CTransaction(naughtyTx).GetTotalSize())) / 41) - 100; for (uint64_t x = 0; x < (n_inputs - 1); ++x) { naughtyTx.vin.emplace_back(GetRandHash(), 0, CScript(), 0); } diff --git a/src/bench/logging.cpp b/src/bench/logging.cpp index c97c4e151b..d8d61f13a8 100644 --- a/src/bench/logging.cpp +++ b/src/bench/logging.cpp @@ -19,7 +19,7 @@ static void Logging(benchmark::Bench& bench, const std::vector& ext LogInstance().DisableCategory(BCLog::LogFlags::ALL); TestingSetup test_setup{ - ChainType::REGTEST, + ChainType::UNITTEST, extra_args, }; diff --git a/src/bench/mempool_stress.cpp b/src/bench/mempool_stress.cpp index 993db66653..3eac936222 100644 --- a/src/bench/mempool_stress.cpp +++ b/src/bench/mempool_stress.cpp @@ -106,7 +106,7 @@ static void ComplexMemPool(benchmark::Bench& bench) static void MempoolCheck(benchmark::Bench& bench) { FastRandomContext det_rand{true}; - auto testing_setup = MakeNoLogFileContext(ChainType::REGTEST, {"-checkmempool=1"}); + auto testing_setup = MakeNoLogFileContext(ChainType::UNITTEST, {"-checkmempool=1"}); CTxMemPool& pool = *testing_setup.get()->m_node.mempool; LOCK2(cs_main, pool.cs); testing_setup->PopulateMempool(det_rand, 400, true); @@ -114,7 +114,7 @@ static void MempoolCheck(benchmark::Bench& bench) bench.run([&]() NO_THREAD_SAFETY_ANALYSIS { // Bump up the spendheight so we don't hit premature coinbase spend errors. - pool.check(coins_tip, /*spendheight=*/300); + pool.check(coins_tip, /*spendheight=*/4100); }); } diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index bf2195293e..eed34599e6 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -35,7 +36,8 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b const std::optional address_mine{add_mine ? std::optional{getnewaddress(wallet)} : std::nullopt}; - for (int i = 0; i < 100; ++i) { + int blockCount = Params().GetConsensus().CoinbaseMaturity(0) + 100; + for (int i = 0; i < blockCount; ++i) { generatetoaddress(test_setup->m_node, address_mine.value_or(ADDRESS_WATCHONLY)); generatetoaddress(test_setup->m_node, ADDRESS_WATCHONLY); } diff --git a/src/bench/wallet_create_tx.cpp b/src/bench/wallet_create_tx.cpp index 632918c0ca..b02317da58 100644 --- a/src/bench/wallet_create_tx.cpp +++ b/src/bench/wallet_create_tx.cpp @@ -47,7 +47,7 @@ void generateFakeBlock(const CChainParams& params, coinbase_tx.vin[0].prevout.SetNull(); coinbase_tx.vout.resize(2); coinbase_tx.vout[0].scriptPubKey = coinbase_out_script; - coinbase_tx.vout[0].nValue = 49 * COIN; + coinbase_tx.vout[0].nValue = 19999 * COIN; coinbase_tx.vin[0].scriptSig = CScript() << ++tip.tip_height << OP_0; coinbase_tx.vout[1].scriptPubKey = coinbase_out_script; // extra output coinbase_tx.vout[1].nValue = 1 * COIN; @@ -106,7 +106,8 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type // Check available balance auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache - assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY)); + constexpr size_t coinbaseMaturity = 2000; + assert(bal == 20000 * COIN * (chain_size - coinbaseMaturity)); wallet::CCoinControl coin_control; coin_control.m_allow_other_inputs = allow_other_inputs; @@ -126,7 +127,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type } // If automatic coin selection is enabled, add the value of another UTXO to the target - if (coin_control.m_allow_other_inputs) target += 50 * COIN; + if (coin_control.m_allow_other_inputs) target += 20000 * COIN; std::vector recipients = {{dest, target, true}}; bench.epochIterations(5).run([&] { @@ -158,7 +159,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vectorm_node, wallet, dest); @@ -167,12 +168,13 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector #include -const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; +const char * const BITCOIN_CONF_FILENAME = "qtum.conf"; const char * const BITCOIN_SETTINGS_FILENAME = "settings.json"; ArgsManager gArgs; @@ -685,12 +685,12 @@ std::string HelpMessageOpt(const std::string &option, const std::string &message fs::path GetDefaultDataDir() { - // Windows: C:\Users\Username\AppData\Roaming\Bitcoin - // macOS: ~/Library/Application Support/Bitcoin - // Unix-like: ~/.bitcoin + // Windows: C:\Users\Username\AppData\Roaming\Qtum + // macOS: ~/Library/Application Support/Qtum + // Unix-like: ~/.qtum #ifdef WIN32 // Windows - return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin"; + return GetSpecialFolderPath(CSIDL_APPDATA) / "Qtum"; #else fs::path pathRet; char* pszHome = getenv("HOME"); @@ -700,10 +700,10 @@ fs::path GetDefaultDataDir() pathRet = fs::path(pszHome); #ifdef MAC_OSX // macOS - return pathRet / "Library/Application Support/Bitcoin"; + return pathRet / "Library/Application Support/Qtum"; #else // Unix-like - return pathRet / ".bitcoin"; + return pathRet / ".qtum"; #endif #endif } @@ -812,6 +812,40 @@ void ArgsManager::LogArgs() const logArgsPrefix("Command-line arg:", "", m_settings.command_line_options); } +std::map> ArgsManager::getArgsList(const std::vector& paramListType) const +{ + LOCK(cs_args); + // Get argument list + std::map args; + for (const auto& arg : m_settings.forced_settings) { + args[arg.first] = true; + } + for (const auto& arg : m_settings.command_line_options) { + args[arg.first] = true; + } + for (const auto& arg : m_settings.ro_config) { + for(const auto& confArg : arg.second) + args[confArg.first] = true; + } + + // Fill argument list with values + std::map> ret; + for (const auto& arg : args) { + std::string paramName = '-' + arg.first; + std::vector paramValue; + bool isList = std::find(std::begin(paramListType), std::end(paramListType), paramName) != std::end(paramListType); + if(isList) { + paramValue = GetArgs(paramName); + } + else { + paramValue.push_back(GetArg(paramName, "")); + } + ret[arg.first] = paramValue; + } + + return ret; +} + namespace common { #ifdef WIN32 WinCmdLineArgs::WinCmdLineArgs() diff --git a/src/common/args.h b/src/common/args.h index ae3ed02bc7..0ac4108baf 100644 --- a/src/common/args.h +++ b/src/common/args.h @@ -412,6 +412,11 @@ class ArgsManager */ void LogArgs() const; + /** + * Return config arguments + */ + std::map> getArgsList(const std::vector& paramListType) const; + private: /** * Get data directory path diff --git a/src/common/system.cpp b/src/common/system.cpp index 1d1c5fa56a..d3361def8c 100644 --- a/src/common/system.cpp +++ b/src/common/system.cpp @@ -14,6 +14,7 @@ #else #include #endif +#include #ifdef HAVE_MALLOPT_ARENA_MAX #include @@ -100,6 +101,14 @@ int GetNumCores() return std::thread::hardware_concurrency(); } +bool CheckHex(const std::string& str) { + size_t data=0; + if(str.size() > 2 && (str.compare(0, 2, "0x") == 0 || str.compare(0, 2, "0X") == 0)){ + data=2; + } + return str.size() > data && str.find_first_not_of("0123456789abcdefABCDEF", data) == std::string::npos; +} + // Obtain the application startup time (used for uptime calculation) int64_t GetStartupTime() { diff --git a/src/common/system.h b/src/common/system.h index 40206aaa01..e14bca7073 100644 --- a/src/common/system.h +++ b/src/common/system.h @@ -17,6 +17,12 @@ #include #include +#ifndef WIN32 +#include +#include +#include +#endif + // Application startup time (used for uptime calculation) int64_t GetStartupTime(); @@ -35,4 +41,30 @@ void runCommand(const std::string& strCommand); */ int GetNumCores(); +#ifdef WIN32 +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else + +#define THREAD_PRIORITY_LOWEST PRIO_MAX +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // It's unclear if it's even possible to change thread priorities on Linux, + // but we really and truly need it for the generation threads. +#ifdef PRIO_THREAD + setpriority(PRIO_THREAD, 0, nPriority); +#else + setpriority(PRIO_PROCESS, 0, nPriority); +#endif +} +#endif + +bool CheckHex(const std::string& str); + #endif // BITCOIN_COMMON_SYSTEM_H diff --git a/src/init/common.cpp b/src/init/common.cpp index f3f7c696c5..9933953472 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,7 @@ void AddLoggingArgs(ArgsManager& argsman) void SetLoggingOptions(const ArgsManager& args) { LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile"); + LogInstance().m_file_pathVM = AbsPathForConfigVal(args, args.GetPathArg("-debugvmlogfile", DEFAULT_DEBUGVMLOGFILE)); LogInstance().m_file_path = AbsPathForConfigVal(args, args.GetPathArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false)); LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); @@ -55,6 +57,8 @@ void SetLoggingOptions(const ArgsManager& args) LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); #endif LogInstance().m_log_sourcelocations = args.GetBoolArg("-logsourcelocations", DEFAULT_LOGSOURCELOCATIONS); + LogInstance().m_show_evm_logs = args.GetBoolArg("-showevmlogs", DEFAULT_SHOWEVMLOGS); + dev::g_logPost = [&](std::string const& s, char const* c){ LogInstance().LogPrintStr(s + '\n', c ? c : "", "", 0, BCLog::ALL, BCLog::Level::Debug, true); }; fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS); } @@ -119,6 +123,10 @@ bool StartLogging(const ArgsManager& args) fs::PathToString(LogInstance().m_file_path))); } +////////////////////////////////////////////////////////////////////// // qtum + dev::g_logPost(std::string("\n\n\n\n\n\n\n\n\n\n"), NULL); +////////////////////////////////////////////////////////////////////// + if (!LogInstance().m_log_timestamps) LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime())); LogPrintf("Default data directory %s\n", fs::PathToString(GetDefaultDataDir())); diff --git a/src/logging.cpp b/src/logging.cpp index 08bfa1f7a4..0ca4eb336a 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -15,6 +15,7 @@ #include const char * const DEFAULT_DEBUGLOGFILE = "debug.log"; +const char * const DEFAULT_DEBUGVMLOGFILE = "vm.log"; constexpr auto MAX_USER_SETABLE_SEVERITY_LEVEL{BCLog::Level::Info}; BCLog::Logger& LogInstance() @@ -51,15 +52,19 @@ bool BCLog::Logger::StartLogging() assert(m_buffering); assert(m_fileout == nullptr); + assert(m_fileoutVM == nullptr); // qtum if (m_print_to_file) { assert(!m_file_path.empty()); + assert(!m_file_pathVM.empty()); // qtum m_fileout = fsbridge::fopen(m_file_path, "a"); - if (!m_fileout) { + m_fileoutVM = fsbridge::fopen(m_file_pathVM, "a"); + if (!m_fileout || !m_fileoutVM) { return false; } setbuf(m_fileout, nullptr); // unbuffered + setbuf(m_fileoutVM, nullptr); // unbuffered // Add newlines to the logfile to distinguish this execution from the // last one. @@ -69,12 +74,15 @@ bool BCLog::Logger::StartLogging() // dump buffered messages from before we opened the log m_buffering = false; while (!m_msgs_before_open.empty()) { - const std::string& s = m_msgs_before_open.front(); + LogMsg logmsg= m_msgs_before_open.front(); - if (m_print_to_file) FileWriteStr(s, m_fileout); - if (m_print_to_console) fwrite(s.data(), 1, s.size(), stdout); + FILE* file = logmsg.useVMLog ? m_fileoutVM : m_fileout; + if (file && m_print_to_file) FileWriteStr(logmsg.msg, file); + bool print_to_console = m_print_to_console; + if(print_to_console && logmsg.useVMLog && !m_show_evm_logs) print_to_console = false; + if (print_to_console) fwrite(logmsg.msg.data(), 1, logmsg.msg.size(), stdout); for (const auto& cb : m_print_callbacks) { - cb(s); + cb(logmsg.msg); } m_msgs_before_open.pop_front(); @@ -90,6 +98,8 @@ void BCLog::Logger::DisconnectTestLogger() m_buffering = true; if (m_fileout != nullptr) fclose(m_fileout); m_fileout = nullptr; + if (m_fileoutVM != nullptr) fclose(m_fileoutVM); + m_fileoutVM = nullptr; m_print_callbacks.clear(); } @@ -183,6 +193,9 @@ const CLogCategoryDesc LogCategories[] = {BCLog::TXRECONCILIATION, "txreconciliation"}, {BCLog::SCAN, "scan"}, {BCLog::TXPACKAGES, "txpackages"}, + {BCLog::COINSTAKE, "coinstake"}, + {BCLog::HTTPPOLL, "http-poll"}, + {BCLog::INDEX, "index"}, {BCLog::ALL, "1"}, {BCLog::ALL, "all"}, }; @@ -289,6 +302,12 @@ std::string LogCategoryToStr(BCLog::LogFlags category) return "scan"; case BCLog::LogFlags::TXPACKAGES: return "txpackages"; + case BCLog::LogFlags::COINSTAKE: + return "coinstake"; + case BCLog::LogFlags::HTTPPOLL: + return "http-poll"; + case BCLog::LogFlags::INDEX: + return "index"; case BCLog::LogFlags::ALL: return "all"; } @@ -392,7 +411,7 @@ namespace BCLog { } } // namespace BCLog -void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) +void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level, bool useVMLog) { StdLockGuard scoped_lock(m_cs); std::string str_prefixed = LogEscapeMessage(str); @@ -418,7 +437,12 @@ void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& loggi } if (m_log_sourcelocations && m_started_new_line) { - str_prefixed.insert(0, "[" + RemovePrefix(source_file, "./") + ":" + ToString(source_line) + "] [" + logging_function + "] "); + if(useVMLog) { + str_prefixed.insert(0, "[" + logging_function + "] "); + } + else { + str_prefixed.insert(0, "[" + RemovePrefix(source_file, "./") + ":" + ToString(source_line) + "] [" + logging_function + "] "); + } } if (m_log_threadnames && m_started_new_line) { @@ -432,11 +456,15 @@ void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& loggi if (m_buffering) { // buffer if we haven't started logging yet - m_msgs_before_open.push_back(str_prefixed); + LogMsg logmsg(str_prefixed, useVMLog); + m_msgs_before_open.push_back(logmsg); return; } - if (m_print_to_console) { + bool print_to_console = m_print_to_console; + if(print_to_console && useVMLog && !m_show_evm_logs) print_to_console = false; + + if (print_to_console) { // print to console fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout); fflush(stdout); @@ -446,6 +474,7 @@ void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& loggi } if (m_print_to_file) { assert(m_fileout != nullptr); + assert(m_fileoutVM != nullptr); // reopen the log file, if requested if (m_reopen_file) { @@ -456,8 +485,22 @@ void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& loggi fclose(m_fileout); m_fileout = new_fileout; } + FILE* new_fileoutVM = fsbridge::fopen(m_file_pathVM, "a"); + if (new_fileoutVM) { + setbuf(new_fileoutVM, nullptr); // unbuffered + fclose(m_fileoutVM); + m_fileoutVM = new_fileoutVM; + } } - FileWriteStr(str_prefixed, m_fileout); + + //////////////////////////////// // qtum + FILE* file = m_fileout; + if(useVMLog){ + file = m_fileoutVM; + } + //////////////////////////////// + + FileWriteStr(str_prefixed, file); } } diff --git a/src/logging.h b/src/logging.h index f7380d8928..8c2d3d39c8 100644 --- a/src/logging.h +++ b/src/logging.h @@ -25,7 +25,9 @@ static const bool DEFAULT_LOGIPS = false; static const bool DEFAULT_LOGTIMESTAMPS = true; static const bool DEFAULT_LOGTHREADNAMES = false; static const bool DEFAULT_LOGSOURCELOCATIONS = false; +static const bool DEFAULT_SHOWEVMLOGS = false; extern const char * const DEFAULT_DEBUGLOGFILE; +extern const char * const DEFAULT_DEBUGVMLOGFILE; extern bool fLogIPs; @@ -35,7 +37,7 @@ struct LogCategory { }; namespace BCLog { - enum LogFlags : uint32_t { + enum LogFlags : uint64_t { NONE = 0, NET = (1 << 0), TOR = (1 << 1), @@ -69,7 +71,10 @@ namespace BCLog { TXRECONCILIATION = (1 << 27), SCAN = (1 << 28), TXPACKAGES = (1 << 29), - ALL = ~(uint32_t)0, + COINSTAKE = (1 << 30), + HTTPPOLL = ((uint64_t)1 << 31), + INDEX = ((uint64_t)1 << 32), + ALL = ~(uint64_t)0, }; enum class Level { Trace = 0, // High-volume or detailed logging for development/debugging @@ -81,13 +86,25 @@ namespace BCLog { }; constexpr auto DEFAULT_LOG_LEVEL{Level::Debug}; + struct LogMsg + { + LogMsg(const std::string& _msg, bool _useVMLog) : + msg(_msg), + useVMLog(_useVMLog) + {} + + std::string msg; + bool useVMLog; + }; + class Logger { private: mutable StdMutex m_cs; // Can not use Mutex from sync.h because in debug mode it would cause a deadlock when a potential deadlock was detected FILE* m_fileout GUARDED_BY(m_cs) = nullptr; - std::list m_msgs_before_open GUARDED_BY(m_cs); + FILE* m_fileoutVM GUARDED_BY(m_cs) = nullptr; + std::list m_msgs_before_open GUARDED_BY(m_cs); bool m_buffering GUARDED_BY(m_cs) = true; //!< Buffer messages before logging can be started. /** @@ -120,12 +137,14 @@ namespace BCLog { bool m_log_time_micros = DEFAULT_LOGTIMEMICROS; bool m_log_threadnames = DEFAULT_LOGTHREADNAMES; bool m_log_sourcelocations = DEFAULT_LOGSOURCELOCATIONS; + bool m_show_evm_logs = DEFAULT_SHOWEVMLOGS; fs::path m_file_path; + fs::path m_file_pathVM; std::atomic m_reopen_file{false}; /** Send a string to the log output */ - void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level); + void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level, bool useVMLog = false); /** Returns whether logs will be written to any output */ bool Enabled() const diff --git a/src/merkleblock.cpp b/src/merkleblock.cpp index 3ffe1465da..11f52155e1 100644 --- a/src/merkleblock.cpp +++ b/src/merkleblock.cpp @@ -152,7 +152,7 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector &vMatch, std::ve if (nTransactions == 0) return uint256(); // check for excessively high numbers of transactions - if (nTransactions > MAX_BLOCK_WEIGHT / MIN_TRANSACTION_WEIGHT) + if (nTransactions > dgpMaxBlockSize * WITNESS_SCALE_FACTOR / MIN_TRANSACTION_WEIGHT) return uint256(); // there can never be more hashes provided than one for every txid if (vHash.size() > nTransactions) diff --git a/src/netbase.cpp b/src/netbase.cpp index 5e1e121bfe..09dd49e8b5 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -523,6 +523,11 @@ bool ConnectSocketDirectly(const CService &addrConnect, const Sock& sock, int nT // Connect to the addrConnect service on the hSocket socket. if (sock.Connect(reinterpret_cast(&sockaddr), len) == SOCKET_ERROR) { + if (!sock.IsSelectable()) { + LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); + return false; + } + int nErr = WSAGetLastError(); // WSAEINVAL is here because some legacy version of winsock uses it if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) diff --git a/src/outputtype.cpp b/src/outputtype.cpp index 566e5ec55a..4f841064f4 100644 --- a/src/outputtype.cpp +++ b/src/outputtype.cpp @@ -42,6 +42,7 @@ const std::string& FormatOutputType(OutputType type) case OutputType::P2SH_SEGWIT: return OUTPUT_TYPE_STRING_P2SH_SEGWIT; case OutputType::BECH32: return OUTPUT_TYPE_STRING_BECH32; case OutputType::BECH32M: return OUTPUT_TYPE_STRING_BECH32M; + case OutputType::P2PK: return OUTPUT_TYPE_STRING_LEGACY; case OutputType::UNKNOWN: return OUTPUT_TYPE_STRING_UNKNOWN; } // no default case, so the compiler can warn about missing cases assert(false); @@ -50,7 +51,8 @@ const std::string& FormatOutputType(OutputType type) CTxDestination GetDestinationForKey(const CPubKey& key, OutputType type) { switch (type) { - case OutputType::LEGACY: return PKHash(key); + case OutputType::LEGACY: + case OutputType::P2PK: return PKHash(key); case OutputType::P2SH_SEGWIT: case OutputType::BECH32: { if (!key.IsCompressed()) return PKHash(key); @@ -88,6 +90,7 @@ CTxDestination AddAndGetDestinationForScript(FillableSigningProvider& keystore, // Note that scripts over 520 bytes are not yet supported. switch (type) { case OutputType::LEGACY: + case OutputType::P2PK: return ScriptHash(script); case OutputType::P2SH_SEGWIT: case OutputType::BECH32: { diff --git a/src/outputtype.h b/src/outputtype.h index a2d5942320..775f798d33 100644 --- a/src/outputtype.h +++ b/src/outputtype.h @@ -19,6 +19,7 @@ enum class OutputType { P2SH_SEGWIT, BECH32, BECH32M, + P2PK, UNKNOWN, }; @@ -27,6 +28,7 @@ static constexpr auto OUTPUT_TYPES = std::array{ OutputType::P2SH_SEGWIT, OutputType::BECH32, OutputType::BECH32M, + OutputType::P2PK, }; std::optional ParseOutputType(const std::string& str); diff --git a/src/qtum/qtumledger.cpp b/src/qtum/qtumledger.cpp index 394cffb13f..a8a0777e88 100644 --- a/src/qtum/qtumledger.cpp +++ b/src/qtum/qtumledger.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -19,6 +19,7 @@ #include #endif #include +#include RecursiveMutex cs_ledger; @@ -214,12 +215,12 @@ class QtumLedgerPriv toolExists = boost::filesystem::exists(toolPath); initToolPath(); - if(gArgs.GetChainName() != CBaseChainParams::MAIN) + if(gArgs.GetChainType() != ChainType::MAIN) { ledgerMainPath = false; } - arguments << "--chain" << gArgs.GetChainName(); + arguments << "--chain" << gArgs.GetChainTypeString(); if(!toolExists) { diff --git a/src/qtum/qtumutils.cpp b/src/qtum/qtumutils.cpp index be52ece18c..405581b9e6 100644 --- a/src/qtum/qtumutils.cpp +++ b/src/qtum/qtumutils.cpp @@ -47,12 +47,12 @@ struct EthChainIdCache int afterShanghaiChainId = 0; }; -int qtumutils::eth_getChainId(int blockHeight, int shanghaiHeight, const std::string& chain) +int qtumutils::eth_getChainId(int blockHeight, int shanghaiHeight, const ChainType& chain) { - if (chain == CBaseChainParams::MAIN || blockHeight < shanghaiHeight) + if (chain == ChainType::MAIN || blockHeight < shanghaiHeight) return ChainIdType::MAIN; - if (chain == CBaseChainParams::REGTEST || chain == CBaseChainParams::UNITTEST) + if (chain == ChainType::REGTEST || chain == ChainType::UNITTEST) return ChainIdType::REGTEST; return ChainIdType::TESTNET; @@ -66,7 +66,7 @@ int qtumutils::eth_getChainId(int blockHeight) static EthChainIdCache idCache; if(idCache.nDefaultPort != nDefaultPort) { - std::string chain = params.NetworkIDString(); + ChainType chain = params.GetChainType(); idCache.nDefaultPort = nDefaultPort; idCache.beforeShanghaiChainId = eth_getChainId(0, shanghaiHeight, chain); idCache.afterShanghaiChainId = eth_getChainId(shanghaiHeight, shanghaiHeight, chain); diff --git a/src/qtum/qtumutils.h b/src/qtum/qtumutils.h index ddc92b617b..df79ffc626 100644 --- a/src/qtum/qtumutils.h +++ b/src/qtum/qtumutils.h @@ -3,6 +3,7 @@ #include #include +#include /** * qtumutils Provides utility functions to EVM for functionalities that already exist in qtum @@ -32,7 +33,7 @@ enum ChainIdType * @param chain Network ID * @return chain id */ -int eth_getChainId(int blockHeight, int shanghaiHeight, const std::string& chain); +int eth_getChainId(int blockHeight, int shanghaiHeight, const ChainType& chain); /** * @brief eth_getChainId Get eth chain id and cache it diff --git a/src/util/fs_helpers.cpp b/src/util/fs_helpers.cpp index 2a9eb3502e..3bf778c940 100644 --- a/src/util/fs_helpers.cpp +++ b/src/util/fs_helpers.cpp @@ -54,7 +54,7 @@ static GlobalMutex cs_dir_locks; */ static std::map> dir_locks GUARDED_BY(cs_dir_locks); -bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only) +bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only, bool try_lock) { LOCK(cs_dir_locks); fs::path pathLockFile = directory / lockfile_name; @@ -68,7 +68,7 @@ bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, boo FILE* file = fsbridge::fopen(pathLockFile, "a"); if (file) fclose(file); auto lock = std::make_unique(pathLockFile); - if (!lock->TryLock()) { + if (try_lock && !lock->TryLock()) { return error("Error while attempting to lock directory %s: %s", fs::PathToString(directory), lock->GetReason()); } if (!probe_only) { diff --git a/src/util/fs_helpers.h b/src/util/fs_helpers.h index e7db01a89b..fabd3cefe0 100644 --- a/src/util/fs_helpers.h +++ b/src/util/fs_helpers.h @@ -35,7 +35,7 @@ void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length); */ [[nodiscard]] bool RenameOver(fs::path src, fs::path dest); -bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false); +bool LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false, bool try_lock = true); void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name); bool DirIsWritable(const fs::path& directory); bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0); diff --git a/src/util/message.cpp b/src/util/message.cpp index 1afb28cc10..be31520365 100644 --- a/src/util/message.cpp +++ b/src/util/message.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -21,7 +22,7 @@ * Text used to signify that a signed message follows and to prevent * inadvertently signing a transaction. */ -const std::string MESSAGE_MAGIC = "Bitcoin Signed Message:\n"; +const std::string MESSAGE_MAGIC = SignStr::strMessageMagic; MessageVerificationResult MessageVerify( const std::string& address, diff --git a/src/util/signstr.h b/src/util/signstr.h index 7fd3651c4b..e8b4d36183 100644 --- a/src/util/signstr.h +++ b/src/util/signstr.h @@ -15,7 +15,7 @@ const std::string strMessageMagic = "Qtum Signed Message:\n"; inline bool SignMessage(const CKey& key, const std::string& strMessage, std::vector& vchSig) { - CHashWriter ss(SER_GETHASH, 0); + CHashWriter ss(0); ss << strMessageMagic; ss << strMessage; @@ -24,7 +24,7 @@ inline bool SignMessage(const CKey& key, const std::string& strMessage, std::vec inline bool VerifyMessage(const CKeyID& keyID, const std::string& strMessage, const std::vector& vchSig) { - CHashWriter ss(SER_GETHASH, 0); + CHashWriter ss(0); ss << strMessageMagic; ss << strMessage; @@ -37,7 +37,7 @@ inline bool VerifyMessage(const CKeyID& keyID, const std::string& strMessage, co inline bool GetKeyIdMessage(const std::string& strMessage, const std::vector& vchSig, CKeyID& keyID) { - CHashWriter ss(SER_GETHASH, 0); + CHashWriter ss(0); ss << strMessageMagic; ss << strMessage; diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index a54f408496..3d063823f0 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -322,6 +323,20 @@ std::string FormatParagraph(std::string_view in, size_t width, size_t indent) return out.str(); } +std::string i64tostr(int64_t n) +{ + return strprintf("%d", n); +} + +int64_t atoi64(const std::string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), nullptr, 10); +#endif +} + /** Upper bound for mantissa. * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer. * Larger integers cannot consist of arbitrary combinations of 0-9: diff --git a/src/util/strencodings.h b/src/util/strencodings.h index d792562735..2124c4f4c0 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -144,6 +144,9 @@ T LocaleIndependentAtoi(std::string_view str) return result; } +std::string i64tostr(int64_t n); +int64_t atoi64(const std::string& str); + /** * Tests if the given character is a decimal digit. * @param[in] c character to test diff --git a/src/validation.h b/src/validation.h index 7ce60da634..d8967677e3 100644 --- a/src/validation.h +++ b/src/validation.h @@ -83,6 +83,19 @@ static constexpr int DEFAULT_CHECKLEVEL{3}; // Setting the target to >= 550 MiB will make it likely we can respect the target. static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; +static const uint64_t DEFAULT_GAS_LIMIT_OP_CREATE=2500000; +static const uint64_t DEFAULT_GAS_LIMIT_OP_SEND=250000; +static const CAmount DEFAULT_GAS_PRICE=0.00000040*COIN; +static const CAmount MAX_RPC_GAS_PRICE=0.00000100*COIN; + +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; + /** Current sync state passed to tip changed callbacks. */ enum class SynchronizationState { INIT_REINDEX, diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index e9b93afc30..8df1bedef3 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -478,7 +478,7 @@ class DescribeWalletAddressVisitor UniValue operator()(const WitnessUnknown& id) const { return UniValue(UniValue::VOBJ); } }; -static UniValue DescribeWalletAddress(const CWallet& wallet, const CTxDestination& dest) +UniValue DescribeWalletAddress(const CWallet& wallet, const CTxDestination& dest) { UniValue ret(UniValue::VOBJ); UniValue detail = DescribeAddress(dest); diff --git a/src/wallet/rpc/addresses.h b/src/wallet/rpc/addresses.h index 227d7073d0..a0369f3356 100644 --- a/src/wallet/rpc/addresses.h +++ b/src/wallet/rpc/addresses.h @@ -1,7 +1,7 @@ #ifndef QTUM_WALLET_RPC_ADDRESSES_H #define QTUM_WALLET_RPC_ADDRESSES_H -#include