Merge pull request #4215 from PastaPastaPasta/backports-0.18-triv

backport: 'trivial' pr1
This commit is contained in:
UdjinM6 2021-06-29 02:06:27 +03:00 committed by GitHub
commit d5e432a278
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 364 additions and 151 deletions

View File

@ -357,7 +357,14 @@ if test x$use_sanitizers != x; then
AX_CHECK_LINK_FLAG(
[[-fsanitize=$use_sanitizers]],
[[SANITIZER_LDFLAGS=-fsanitize=$use_sanitizers]],
[AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])])
[AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])],
[],
[AC_LANG_PROGRAM([[
#include <cstdint>
#include <cstddef>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; }
__attribute__((weak)) // allow for libFuzzer linking
]],[[]])])
fi
ERROR_CXXFLAGS=
@ -578,17 +585,6 @@ case $host in
LEVELDB_TARGET_FLAGS="-DOS_MACOSX"
if test x$cross_compiling != xyes; then
BUILD_OS=darwin
AC_CHECK_PROG([PORT],port, port)
if test x$PORT = xport; then
dnl add default macports paths
CPPFLAGS="$CPPFLAGS -isystem /opt/local/include"
LIBS="$LIBS -L/opt/local/lib"
if test -d /opt/local/include/db48; then
CPPFLAGS="$CPPFLAGS -I/opt/local/include/db48"
LIBS="$LIBS -L/opt/local/lib/db48"
fi
fi
AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert)
AC_CHECK_PROG([BREW],brew, brew)
if test x$BREW = xbrew; then

View File

@ -52,15 +52,22 @@ def applies_to_file(filename):
# obtain list of files in repo according to INCLUDE and EXCLUDE
################################################################################
GIT_LS_CMD = 'git ls-files'
GIT_LS_CMD = 'git ls-files --full-name'.split(' ')
GIT_TOPLEVEL_CMD = 'git rev-parse --show-toplevel'.split(' ')
def call_git_ls():
out = subprocess.check_output(GIT_LS_CMD.split(' '))
def call_git_ls(base_directory):
out = subprocess.check_output([*GIT_LS_CMD, base_directory])
return [f for f in out.decode("utf-8").split('\n') if f != '']
def get_filenames_to_examine():
filenames = call_git_ls()
return sorted([filename for filename in filenames if
def call_git_toplevel():
"Returns the absolute path to the project root"
return subprocess.check_output(GIT_TOPLEVEL_CMD).strip().decode("utf-8")
def get_filenames_to_examine(base_directory):
"Returns an array of absolute paths to any project files in the base_directory that pass the include/exclude filters"
root = call_git_toplevel()
filenames = call_git_ls(base_directory)
return sorted([os.path.join(root, filename) for filename in filenames if
applies_to_file(filename)])
################################################################################
@ -87,24 +94,12 @@ def compile_copyright_regex(copyright_style, year_style, name):
EXPECTED_HOLDER_NAMES = [
"Satoshi Nakamoto\n",
"The Bitcoin Core developers\n",
"The Bitcoin Core developers \n",
"Bitcoin Core Developers\n",
"the Bitcoin Core developers\n",
"The Bitcoin developers\n",
"The LevelDB Authors\. All rights reserved\.\n",
"BitPay Inc\.\n",
"BitPay, Inc\.\n",
"University of Illinois at Urbana-Champaign\.\n",
"MarcoFalke\n",
"Pieter Wuille\n",
"Pieter Wuille +\*\n",
"Pieter Wuille, Gregory Maxwell +\*\n",
"Pieter Wuille, Andrew Poelstra +\*\n",
"Andrew Poelstra +\*\n",
"Wladimir J. van der Laan\n",
"Jeff Garzik\n",
"Diederik Huys, Pieter Wuille +\*\n",
"Thomas Daede, Cory Fields +\*\n",
"Jan-Klaas Kollhof\n",
"Sam Rushing\n",
"ArtForz -- public domain half-a-node\n",
@ -148,7 +143,7 @@ def file_has_without_c_style_copyright_for_holder(contents, holder_name):
################################################################################
def read_file(filename):
return open(os.path.abspath(filename), 'r', encoding="utf8").read()
return open(filename, 'r', encoding="utf8").read()
def gather_file_info(filename):
info = {}
@ -262,12 +257,9 @@ def print_report(file_infos, verbose):
print(SEPARATOR)
def exec_report(base_directory, verbose):
original_cwd = os.getcwd()
os.chdir(base_directory)
filenames = get_filenames_to_examine()
filenames = get_filenames_to_examine(base_directory)
file_infos = [gather_file_info(f) for f in filenames]
print_report(file_infos, verbose)
os.chdir(original_cwd)
################################################################################
# report cmd
@ -327,13 +319,13 @@ def get_most_recent_git_change_year(filename):
################################################################################
def read_file_lines(filename):
f = open(os.path.abspath(filename), 'r', encoding="utf8")
f = open(filename, 'r', encoding="utf8")
file_lines = f.readlines()
f.close()
return file_lines
def write_file_lines(filename, file_lines):
f = open(os.path.abspath(filename), 'w', encoding="utf8")
f = open(filename, 'w', encoding="utf8")
f.write(''.join(file_lines))
f.close()
@ -401,11 +393,8 @@ def update_updatable_copyright(filename):
"Copyright updated! -> %s" % last_git_change_year)
def exec_update_header_year(base_directory):
original_cwd = os.getcwd()
os.chdir(base_directory)
for filename in get_filenames_to_examine():
for filename in get_filenames_to_examine(base_directory):
update_updatable_copyright(filename)
os.chdir(original_cwd)
################################################################################
# update cmd

View File

@ -172,12 +172,6 @@ class DeploymentInfo(object):
if os.path.exists(os.path.join(parentDir, "translations")):
# Classic layout, e.g. "/usr/local/Trolltech/Qt-4.x.x"
self.qtPath = parentDir
elif os.path.exists(os.path.join(parentDir, "share", "qt4", "translations")):
# MacPorts layout, e.g. "/opt/local/share/qt4"
self.qtPath = os.path.join(parentDir, "share", "qt4")
elif os.path.exists(os.path.join(os.path.dirname(parentDir), "share", "qt4", "translations")):
# Newer Macports layout
self.qtPath = os.path.join(os.path.dirname(parentDir), "share", "qt4")
else:
self.qtPath = os.getenv("QTDIR", None)

View File

@ -11,6 +11,7 @@ $(package)_config_opts_mingw32=--enable-mingw
$(package)_config_opts_linux=--with-pic
$(package)_cflags+=-Wno-error=implicit-function-declaration
$(package)_cxxflags=-std=c++11
$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
endef
define $(package)_preprocess_cmds

View File

@ -20,6 +20,7 @@ For full TX query capability, one must enable the transaction index via "txindex
`GET /rest/block/notxdetails/<BLOCK-HASH>.<bin|hex|json>`
Given a block hash: returns a block, in binary, hex-encoded binary or JSON formats.
Responds with 404 if the block doesn't exist.
The HTTP request and response are both handled entirely in-memory, thus making maximum memory usage at least 2.66MB (1 MB max block, plus hex encoding) per request.
@ -29,6 +30,12 @@ With the /notxdetails/ option JSON response will only contain the transaction ha
`GET /rest/headers/<COUNT>/<BLOCK-HASH>.<bin|hex|json>`
Given a block hash: returns <COUNT> amount of blockheaders in upward direction.
Returns empty if the block doesn't exist or it isn't in the active chain.
#### Blockhash by height
`GET /rest/blockhashbyheight/<HEIGHT>.<bin|hex|json>`
Given a height: returns hash of block in best-block-chain at height provided.
#### Chaininfos
`GET /rest/chaininfo.json`

View File

@ -7,8 +7,8 @@ Developer Notes
- [Developer Notes](#developer-notes)
- [Coding Style (General)](#coding-style-general)
- [Coding Style (C++)](#coding-style-c)
- [Doxygen comments](#doxygen-comments)
- [Coding Style (Python)](#coding-style-python)
- [Coding Style (Doxygen-compatible comments)](#coding-style-doxygen-compatible-comments)
- [Development tips and tricks](#development-tips-and-tricks)
- [Compiling for debugging](#compiling-for-debugging)
- [Compiling for gprof profiling](#compiling-for-gprof-profiling)
@ -119,10 +119,17 @@ public:
} // namespace foo
```
Doxygen comments
-----------------
Coding Style (Python)
---------------------
To facilitate the generation of documentation, use doxygen-compatible comment blocks for functions, methods and fields.
Refer to [/test/functional/README.md#style-guidelines](/test/functional/README.md#style-guidelines).
Coding Style (Doxygen-compatible comments)
------------------------------------------
Dash Core uses [Doxygen](http://www.doxygen.nl/) to generate its official documentation.
Use Doxygen-compatible comment blocks for functions, methods, and fields.
For example, to describe a function use:
```c++
@ -155,7 +162,7 @@ int var; //!< Detailed description after the member
```
or
```cpp
```c++
//! Description before the member
int var;
```
@ -175,15 +182,15 @@ Not OK (used plenty in the current source, but not picked up):
//
```
A full list of comment syntaxes picked up by doxygen can be found at http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
but if possible use one of the above styles.
A full list of comment syntaxes picked up by Doxygen can be found at https://www.stack.nl/~dimitri/doxygen/manual/docblocks.html,
but the above styles are favored.
Documentation can be generated with `make docs` and cleaned up with `make clean-docs`.
Documentation can be generated with `make docs` and cleaned up with `make clean-docs`. The resulting files are located in `doc/doxygen/html`; open `index.html` to view the homepage.
Coding Style (Python)
---------------------
Refer to [/test/functional/README.md#style-guidelines](/test/functional/README.md#style-guidelines).
Before running `make docs`, you will need to install dependencies `doxygen` and `dot`. For example, on MacOS via Homebrew:
```
brew install doxygen --with-graphviz
```
Development tips and tricks
---------------------------

View File

@ -3,10 +3,11 @@ Fuzz-testing Dash Core
A special test harness `test_dash_fuzzy` is provided to provide an easy
entry point for fuzzers and the like. In this document we'll describe how to
use it with AFL.
use it with AFL and libFuzzer.
Building AFL
-------------
## AFL
### Building AFL
It is recommended to always use the latest version of afl:
```
@ -17,8 +18,7 @@ make
export AFLPATH=$PWD
```
Instrumentation
----------------
### Instrumentation
To build Dash Core using AFL instrumentation (this assumes that the
`AFLPATH` was set as above):
@ -39,8 +39,7 @@ compiling using `afl-clang-fast`/`afl-clang-fast++` the resulting
features "persistent mode" and "deferred forkserver" can be used. See
https://github.com/mcarpenter/afl/tree/master/llvm_mode for details.
Preparing fuzzing
------------------
### Preparing fuzzing
AFL needs an input directory with examples, and an output directory where it
will place examples that it found. These can be anywhere in the file system,
@ -60,8 +59,7 @@ Example inputs are available from:
Extract these (or other starting inputs) into the `inputs` directory before starting fuzzing.
Fuzzing
--------
### Fuzzing
To start the actual fuzzing use:
```
@ -70,3 +68,21 @@ $AFLPATH/afl-fuzz -i ${AFLIN} -o ${AFLOUT} -m52 -- test/test_dash_fuzzy
You may have to change a few kernel parameters to test optimally - `afl-fuzz`
will print an error and suggestion if so.
## libFuzzer
A recent version of `clang`, the address sanitizer and libFuzzer is needed (all
found in the `compiler-rt` runtime libraries package).
To build the `test/test_dash_fuzzy` executable run
```
./configure --disable-ccache --with-sanitizers=fuzzer,address CC=clang CXX=clang++
make
```
The fuzzer needs some inputs to work on, but the inputs or seeds can be used
interchangeably between libFuzzer and AFL.
See https://llvm.org/docs/LibFuzzer.html#running on how to run the libFuzzer
instrumented executable.

View File

@ -1253,7 +1253,7 @@ bool AppInitParameterInteraction()
// also see: InitParameterInteraction()
if (!fs::is_directory(GetBlocksDir(false))) {
if (!fs::is_directory(GetBlocksDir())) {
return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist."), gArgs.GetArg("-blocksdir", "").c_str()));
}
@ -2420,8 +2420,14 @@ bool AppInitMain()
// ********************************************************* Step 11: import blocks
if (!CheckDiskSpace() && !CheckDiskSpace(0, true))
if (!CheckDiskSpace(/* additional_bytes */ 0, /* blocks_dir */ false)) {
InitError(strprintf(_("Error: Disk space is low for %s"), GetDataDir()));
return false;
}
if (!CheckDiskSpace(/* additional_bytes */ 0, /* blocks_dir */ true)) {
InitError(strprintf(_("Error: Disk space is low for %s"), GetBlocksDir()));
return false;
}
// Either install a handler to notify us when genesis activates, or set fHaveGenesis directly.
// No locking, as this happens before any background thread is started.

View File

@ -326,15 +326,13 @@ bool IsLocal(const CService& addr)
/** check whether a given network is one we can probably connect to */
bool IsReachable(enum Network net)
{
LOCK(cs_mapLocalHost);
return !vfLimited[net];
return !IsLimited(net);
}
/** check whether a given address is in a network we can probably connect to */
bool IsReachable(const CNetAddr& addr)
{
enum Network net = addr.GetNetwork();
return IsReachable(net);
return IsReachable(addr.GetNetwork());
}

View File

@ -81,6 +81,11 @@ public:
#endif // ENABLE_WALLET
bool enableWallet;
/** Get the tray icon status.
Some systems have not "system tray" or "notification area" available.
*/
bool hasTrayIcon() const { return trayIcon; }
protected:
void changeEvent(QEvent *e) override;
void closeEvent(QCloseEvent *event) override;

View File

@ -497,14 +497,13 @@ void BitcoinApplication::initializeResult(bool success)
}
#endif
// If -min option passed, start window minimized.
if(gArgs.GetBoolArg("-min", false))
{
window->showMinimized();
}
else
{
// If -min option passed, start window minimized (iconified) or minimized to tray
if (!gArgs.GetBoolArg("-min", false)) {
window->show();
} else if (clientModel->getOptionsModel()->getMinimizeToTray() && window->hasTrayIcon()) {
// do nothing as the window is managed by the tray icon
} else {
window->showMinimized();
}
Q_EMIT splashFinished(window);

View File

@ -945,7 +945,7 @@ https://www.transifex.com/projects/p/dash/</string>
<item>
<widget class="QLabel" name="overriddenByCommandLineInfoLabel">
<property name="text">
<string>Active command-line options that override above options:</string>
<string>Options set in this dialog are overridden by the command line or in the configuration file:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>

View File

@ -39,7 +39,7 @@ Notificator::Notificator(const QString &_programName, QSystemTrayIcon *_trayIcon
mode(None),
trayIcon(_trayIcon)
#ifdef USE_DBUS
,interface(0)
,interface(nullptr)
#endif
{
if(_trayIcon && _trayIcon->supportsMessages())
@ -154,14 +154,14 @@ QVariant FreedesktopImage::toVariant(const QImage &img)
void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
{
Q_UNUSED(cls);
// Arguments for DBus call:
// https://developer.gnome.org/notification-spec/
// Arguments for DBus "Notify" call:
QList<QVariant> args;
// Program Name:
args.append(programName);
// Unique ID of this notification type:
// Replaces ID; A value of 0 means that this notification won't replace any existing notifications:
args.append(0U);
// Application Icon, empty string
@ -209,9 +209,8 @@ void Notificator::notifyDBus(Class cls, const QString &title, const QString &tex
}
#endif
void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
void Notificator::notifySystray(Class cls, const QString &title, const QString &text, int millisTimeout)
{
Q_UNUSED(icon);
QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon;
switch(cls) // Set icon based on class
{
@ -222,13 +221,12 @@ void Notificator::notifySystray(Class cls, const QString &title, const QString &
trayIcon->showMessage(title, text, sicon, millisTimeout);
}
// Based on Qt's tray icon implementation
#ifdef Q_OS_MAC
void Notificator::notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon) {
void Notificator::notifyMacUserNotificationCenter(const QString &title, const QString &text)
{
// icon is not supported by the user notification center yet. OSX will use the app icon.
MacNotificationHandler::instance()->showNotification(title, text);
}
#endif
void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout)
@ -241,11 +239,11 @@ void Notificator::notify(Class cls, const QString &title, const QString &text, c
break;
#endif
case QSystemTray:
notifySystray(cls, title, text, icon, millisTimeout);
notifySystray(cls, title, text, millisTimeout);
break;
#ifdef Q_OS_MAC
case UserNotificationCenter:
notifyMacUserNotificationCenter(cls, title, text, icon);
notifyMacUserNotificationCenter(title, text);
break;
#endif
default:

View File

@ -57,7 +57,7 @@ private:
enum Mode {
None, /**< Ignore informational notifications, and show a modal pop-up dialog for Critical notifications. */
Freedesktop, /**< Use DBus org.freedesktop.Notifications */
QSystemTray, /**< Use QSystemTray::showMessage */
QSystemTray, /**< Use QSystemTrayIcon::showMessage() */
UserNotificationCenter /**< Use the 10.8+ User Notification Center (Mac only) */
};
QString programName;
@ -68,9 +68,9 @@ private:
void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
#endif
void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout);
void notifySystray(Class cls, const QString &title, const QString &text, int millisTimeout);
#ifdef Q_OS_MAC
void notifyMacUserNotificationCenter(Class cls, const QString &title, const QString &text, const QIcon &icon);
void notifyMacUserNotificationCenter(const QString &title, const QString &text);
#endif
};

View File

@ -400,13 +400,12 @@ void RPCExecutor::request(const QString &command, const QString &walletID)
std::string executableCommand = command.toStdString() + "\n";
// Catch the console-only-help command before RPC call is executed and reply with help text as-if a RPC reply.
if(executableCommand == "help-console\n")
{
if(executableCommand == "help-console\n") {
Q_EMIT reply(RPCConsole::CMD_REPLY, QString(("\n"
"This console accepts RPC commands using the standard syntax.\n"
" example: getblockhash 0\n\n"
"This console can also accept RPC commands using parenthesized syntax.\n"
"This console can also accept RPC commands using the parenthesized syntax.\n"
" example: getblockhash(0)\n\n"
"Commands may be nested when specified with the parenthesized syntax.\n"
@ -416,11 +415,11 @@ void RPCExecutor::request(const QString &command, const QString &walletID)
" example: getblockhash 0\n"
" getblockhash,0\n\n"
"Named results can be queried with a non-quoted key string in brackets.\n"
" example: getblock(getblockhash(0) true)[tx]\n\n"
"Named results can be queried with a non-quoted key string in brackets using the parenthesized syntax.\n"
" example: getblock(getblockhash(0) 1)[tx]\n\n"
"Results without keys can be queried using an integer in brackets.\n"
" example: getblock(getblockhash(0),true)[tx][0]\n\n")));
"Results without keys can be queried with an integer in brackets using the parenthesized syntax.\n"
" example: getblock(getblockhash(0),1)[tx][0]\n\n")));
return;
}
std::string wallet_id = walletID.toStdString();

View File

@ -573,6 +573,52 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
}
}
static bool rest_blockhash_by_height(HTTPRequest* req,
const std::string& str_uri_part)
{
if (!CheckWarmup(req)) return false;
std::string height_str;
const RetFormat rf = ParseDataFormat(height_str, str_uri_part);
int32_t blockheight;
if (!ParseInt32(height_str, &blockheight) || blockheight < 0) {
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid height: " + SanitizeString(height_str));
}
CBlockIndex* pblockindex = nullptr;
{
LOCK(cs_main);
if (blockheight > chainActive.Height()) {
return RESTERR(req, HTTP_NOT_FOUND, "Block height out of range");
}
pblockindex = chainActive[blockheight];
}
switch (rf) {
case RetFormat::BINARY: {
CDataStream ss_blockhash(SER_NETWORK, PROTOCOL_VERSION);
ss_blockhash << pblockindex->GetBlockHash();
req->WriteHeader("Content-Type", "application/octet-stream");
req->WriteReply(HTTP_OK, ss_blockhash.str());
return true;
}
case RetFormat::HEX: {
req->WriteHeader("Content-Type", "text/plain");
req->WriteReply(HTTP_OK, pblockindex->GetBlockHash().GetHex() + "\n");
return true;
}
case RetFormat::JSON: {
req->WriteHeader("Content-Type", "application/json");
UniValue resp = UniValue(UniValue::VOBJ);
resp.pushKV("blockhash", pblockindex->GetBlockHash().GetHex());
req->WriteReply(HTTP_OK, resp.write() + "\n");
return true;
}
default: {
return RESTERR(req, HTTP_NOT_FOUND, "output format not found (available: " + AvailableDataFormatsString() + ")");
}
}
}
static const struct {
const char* prefix;
bool (*handler)(HTTPRequest* req, const std::string& strReq);
@ -585,6 +631,7 @@ static const struct {
{"/rest/mempool/contents", rest_mempool_contents},
{"/rest/headers/", rest_headers},
{"/rest/getutxos", rest_getutxos},
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
};
bool StartREST()

View File

@ -41,7 +41,11 @@ struct secure_allocator : public std::allocator<T> {
T* allocate(std::size_t n, const void* hint = 0)
{
return static_cast<T*>(LockedPoolManager::Instance().alloc(sizeof(T) * n));
T* allocation = static_cast<T*>(LockedPoolManager::Instance().alloc(sizeof(T) * n));
if (!allocation) {
throw std::bad_alloc();
}
return allocation;
}
void deallocate(T* p, std::size_t n)

View File

@ -252,6 +252,9 @@ void *PosixLockedPageAllocator::AllocateLocked(size_t len, bool *lockingSuccess)
void *addr;
len = align_up(len, page_size);
addr = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (addr == MAP_FAILED) {
return nullptr;
}
if (addr) {
*lockingSuccess = mlock(addr, len) == 0;
}

View File

@ -22,7 +22,7 @@ public:
virtual ~LockedPageAllocator() {}
/** Allocate and lock memory pages.
* If len is not a multiple of the system page size, it is rounded up.
* Returns 0 in case of allocation failure.
* Returns nullptr in case of allocation failure.
*
* If locking the memory pages could not be accomplished it will still
* return the memory, however the lockingSuccess flag will be false.

View File

@ -81,7 +81,11 @@ struct LockData {
LockOrders lockorders;
InvLockOrders invlockorders;
std::mutex dd_mutex;
} static lockdata;
};
LockData& GetLockData() {
static LockData lockdata;
return lockdata;
}
static thread_local LockStack g_lockstack;
@ -122,6 +126,7 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
static void push_lock(void* c, const CLockLocation& locklocation)
{
LockData& lockdata = GetLockData();
std::lock_guard<std::mutex> lock(lockdata.dd_mutex);
g_lockstack.push_back(std::make_pair(c, locklocation));
@ -189,6 +194,7 @@ void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLi
void DeleteLock(void* cs)
{
LockData& lockdata = GetLockData();
if (!lockdata.available) {
// We're already shutting down.
return;

View File

@ -626,4 +626,93 @@ BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test)
BOOST_CHECK(1);
}
BOOST_AUTO_TEST_CASE(LimitedAndReachable_Network)
{
SetLimited(NET_IPV4, true);
SetLimited(NET_IPV6, true);
SetLimited(NET_ONION, true);
BOOST_CHECK_EQUAL(IsLimited(NET_IPV4), true);
BOOST_CHECK_EQUAL(IsLimited(NET_IPV6), true);
BOOST_CHECK_EQUAL(IsLimited(NET_ONION), true);
BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), false);
BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), false);
BOOST_CHECK_EQUAL(IsReachable(NET_ONION), false);
SetLimited(NET_IPV4, false);
SetLimited(NET_IPV6, false);
SetLimited(NET_ONION, false);
BOOST_CHECK_EQUAL(IsLimited(NET_IPV4), false);
BOOST_CHECK_EQUAL(IsLimited(NET_IPV6), false);
BOOST_CHECK_EQUAL(IsLimited(NET_ONION), false);
BOOST_CHECK_EQUAL(IsReachable(NET_IPV4), true);
BOOST_CHECK_EQUAL(IsReachable(NET_IPV6), true);
BOOST_CHECK_EQUAL(IsReachable(NET_ONION), true);
}
BOOST_AUTO_TEST_CASE(LimitedAndReachable_NetworkCaseUnroutableAndInternal)
{
BOOST_CHECK_EQUAL(IsLimited(NET_UNROUTABLE), false);
BOOST_CHECK_EQUAL(IsLimited(NET_INTERNAL), false);
BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true);
BOOST_CHECK_EQUAL(IsReachable(NET_INTERNAL), true);
SetLimited(NET_UNROUTABLE, true);
SetLimited(NET_INTERNAL, true);
BOOST_CHECK_EQUAL(IsLimited(NET_UNROUTABLE), false); // Ignored for both networks
BOOST_CHECK_EQUAL(IsLimited(NET_INTERNAL), false);
BOOST_CHECK_EQUAL(IsReachable(NET_UNROUTABLE), true);
BOOST_CHECK_EQUAL(IsReachable(NET_INTERNAL), true);
}
CNetAddr UtilBuildAddress(unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4)
{
unsigned char ip[] = {p1, p2, p3, p4};
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sockaddr_in)); // initialize the memory block
memcpy(&(sa.sin_addr), &ip, sizeof(ip));
return CNetAddr(sa.sin_addr);
}
BOOST_AUTO_TEST_CASE(LimitedAndReachable_CNetAddr)
{
CNetAddr addr = UtilBuildAddress(0x001, 0x001, 0x001, 0x001); // 1.1.1.1
SetLimited(NET_IPV4, false);
BOOST_CHECK_EQUAL(IsLimited(addr), false);
BOOST_CHECK_EQUAL(IsReachable(addr), true);
SetLimited(NET_IPV4, true);
BOOST_CHECK_EQUAL(IsLimited(addr), true);
BOOST_CHECK_EQUAL(IsReachable(addr), false);
SetLimited(NET_IPV4, false); // have to reset this, because this is stateful.
}
BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
{
CService addr = CService(UtilBuildAddress(0x002, 0x001, 0x001, 0x001), 1000); // 2.1.1.1:1000
SetLimited(NET_IPV4, false);
BOOST_CHECK_EQUAL(IsLocal(addr), false);
BOOST_CHECK_EQUAL(AddLocal(addr, 1000), true);
BOOST_CHECK_EQUAL(IsLocal(addr), true);
RemoveLocal(addr);
BOOST_CHECK_EQUAL(IsLocal(addr), false);
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -213,14 +213,22 @@ BOOST_AUTO_TEST_CASE(is)
BOOST_CHECK(p2sh.IsPayToScriptHash());
// Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes:
static const unsigned char direct[] = { OP_HASH160, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
BOOST_CHECK(CScript(direct, direct+sizeof(direct)).IsPayToScriptHash());
static const unsigned char pushdata1[] = { OP_HASH160, OP_PUSHDATA1, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
BOOST_CHECK(!CScript(pushdata1, pushdata1+sizeof(pushdata1)).IsPayToScriptHash());
static const unsigned char pushdata2[] = { OP_HASH160, OP_PUSHDATA2, 20,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
BOOST_CHECK(!CScript(pushdata2, pushdata2+sizeof(pushdata2)).IsPayToScriptHash());
static const unsigned char pushdata4[] = { OP_HASH160, OP_PUSHDATA4, 20,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL };
BOOST_CHECK(!CScript(pushdata4, pushdata4+sizeof(pushdata4)).IsPayToScriptHash());
std::vector<unsigned char> direct = {OP_HASH160, 20};
direct.insert(direct.end(), 20, 0);
direct.push_back(OP_EQUAL);
BOOST_CHECK(CScript(direct.begin(), direct.end()).IsPayToScriptHash());
std::vector<unsigned char> pushdata1 = {OP_HASH160, OP_PUSHDATA1, 20};
pushdata1.insert(pushdata1.end(), 20, 0);
pushdata1.push_back(OP_EQUAL);
BOOST_CHECK(!CScript(pushdata1.begin(), pushdata1.end()).IsPayToScriptHash());
std::vector<unsigned char> pushdata2 = {OP_HASH160, 20, 0};
pushdata2.insert(pushdata2.end(), 20, 0);
pushdata2.push_back(OP_EQUAL);
BOOST_CHECK(!CScript(pushdata2.begin(), pushdata2.end()).IsPayToScriptHash());
std::vector<unsigned char> pushdata4 = {OP_HASH160, 20, 0, 0, 0};
pushdata4.insert(pushdata4.end(), 20, 0);
pushdata4.push_back(OP_EQUAL);
BOOST_CHECK(!CScript(pushdata4.begin(), pushdata4.end()).IsPayToScriptHash());
CScript not_p2sh;
BOOST_CHECK(!not_p2sh.IsPayToScriptHash());

View File

@ -763,18 +763,17 @@ fs::path GetDefaultDataDir()
#endif
}
static fs::path g_blocks_path_cached;
static fs::path g_blocks_path_cache_net_specific;
static fs::path pathCached;
static fs::path pathCachedNetSpecific;
static CCriticalSection csPathCached;
const fs::path &GetBlocksDir(bool fNetSpecific)
const fs::path &GetBlocksDir()
{
LOCK(csPathCached);
fs::path &path = fNetSpecific ? g_blocks_path_cache_net_specific : g_blocks_path_cached;
fs::path &path = g_blocks_path_cache_net_specific;
// This can be called during exceptions by LogPrintf(), so we cache the
// value so we don't have to do memory allocations after that.
@ -790,9 +789,8 @@ const fs::path &GetBlocksDir(bool fNetSpecific)
} else {
path = GetDataDir(false);
}
if (fNetSpecific)
path /= BaseParams().DataDir();
path /= BaseParams().DataDir();
path /= "blocks";
fs::create_directories(path);
return path;
@ -844,7 +842,6 @@ void ClearDatadirCache()
pathCached = fs::path();
pathCachedNetSpecific = fs::path();
g_blocks_path_cached = fs::path();
g_blocks_path_cache_net_specific = fs::path();
}
@ -1281,7 +1278,7 @@ fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific)
int ScheduleBatchPriority(void)
{
#ifdef SCHED_BATCH
const static sched_param param{0};
const static sched_param param{};
if (int ret = pthread_setschedparam(pthread_self(), SCHED_BATCH, &param)) {
LogPrintf("Failed to pthread_setschedparam: %s\n", strerror(errno));
return ret;

View File

@ -108,7 +108,8 @@ void ReleaseDirectoryLocks();
bool TryCreateDirectories(const fs::path& p);
fs::path GetDefaultDataDir();
const fs::path &GetBlocksDir(bool fNetSpecific = true);
// The blocks directory is always net specific.
const fs::path &GetBlocksDir();
const fs::path &GetDataDir(bool fNetSpecific = true);
fs::path GetBackupsDir();
void ClearDatadirCache();

View File

@ -4508,7 +4508,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
LogPrintf("[0%%]..."); /* Continued */
for (pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
boost::this_thread::interruption_point();
int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
const int percentageDone = std::max(1, std::min(99, (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * (nCheckLevel >= 4 ? 50 : 100))));
if (reportDone < percentageDone/10) {
// report every 10% step
LogPrintf("[%d%%]...", percentageDone); /* Continued */
@ -4566,7 +4566,13 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
if (nCheckLevel >= 4) {
while (pindex != chainActive.Tip()) {
boost::this_thread::interruption_point();
uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50))), false);
const int percentageDone = std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)));
if (reportDone < percentageDone/10) {
// report every 10% step
LogPrintf("[%d%%]...", percentageDone); /* Continued */
reportDone = percentageDone/10;
}
uiInterface.ShowProgress(_("Verifying blocks..."), percentageDone, false);
pindex = chainActive.Next(pindex);
CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))

View File

@ -17,7 +17,8 @@ request is opened. Both sets of tests can also be run locally.
# Running tests locally
Build for your system first. Be sure to enable wallet, utils and daemon when you configure. Tests will not run otherwise.
Before tests can be run locally, Dash Core must be built. See the [building instructions](/doc#building) for help.
### Functional tests

View File

@ -20,9 +20,13 @@ don't have test cases for.
- Where possible, try to adhere to [PEP-8 guidelines](https://www.python.org/dev/peps/pep-0008/)
- Use a python linter like flake8 before submitting PRs to catch common style
nits (eg trailing whitespace, unused imports, etc)
- The oldest supported Python version is specified in [doc/dependencies.md](/doc/dependencies.md).
Consider using [pyenv](https://github.com/pyenv/pyenv), which checks [.python-version](/.python-version),
to prevent accidentally introducing modern syntax from an unsupported Python version.
The Travis linter also checks this, but [possibly not in all cases](https://github.com/bitcoin/bitcoin/pull/14884#discussion_r239585126).
- See [the python lint script](/test/lint/lint-python.sh) that checks for violations that
could lead to bugs and issues in the test code.
- Avoid wildcard imports where possible
- Avoid wildcard imports
- Use a module-level docstring to describe what the test is testing, and how it
is testing it.
- When subclassing the BitcoinTestFramwork, place overrides for the

View File

@ -13,7 +13,7 @@ is testing and *how* it's being tested
# libraries then local imports).
from collections import defaultdict
# Avoid wildcard * imports if possible
# Avoid wildcard * imports
from test_framework.blocktools import (create_block, create_coinbase)
from test_framework.messages import CInv
from test_framework.mininode import (

View File

@ -18,6 +18,8 @@ class BlocksdirTest(BitcoinTestFramework):
def run_test(self):
self.stop_node(0)
assert os.path.isdir(os.path.join(self.nodes[0].datadir, "regtest", "blocks"))
assert not os.path.isdir(os.path.join(self.nodes[0].datadir, "blocks"))
shutil.rmtree(self.nodes[0].datadir)
initialize_datadir(self.options.tmpdir, 0, self.chain)
self.log.info("Starting with non exiting blocksdir ...")

View File

@ -195,9 +195,19 @@ class RESTTest (BitcoinTestFramework):
self.nodes[0].generate(1) # generate block to not affect upcoming tests
self.sync_all()
self.log.info("Test the /block and /headers URIs")
self.log.info("Test the /block, /blockhashbyheight and /headers URIs")
bb_hash = self.nodes[0].getbestblockhash()
# Check result if block does not exists
assert_equal(self.test_rest_request('/headers/1/0000000000000000000000000000000000000000000000000000000000000000'), [])
self.test_rest_request('/block/0000000000000000000000000000000000000000000000000000000000000000', status=404, ret_type=RetType.OBJ)
# Check result if block is not in the active chain
self.nodes[0].invalidateblock(bb_hash)
assert_equal(self.test_rest_request('/headers/1/{}'.format(bb_hash)), [])
self.test_rest_request('/block/{}'.format(bb_hash))
self.nodes[0].reconsiderblock(bb_hash)
# Check binary format
response = self.test_rest_request("/block/{}".format(bb_hash), req_type=ReqType.BIN, ret_type=RetType.OBJ)
assert_greater_than(int(response.getheader('content-length')), 80)
@ -224,6 +234,23 @@ class RESTTest (BitcoinTestFramework):
# Check json format
block_json_obj = self.test_rest_request("/block/{}".format(bb_hash))
assert_equal(block_json_obj['hash'], bb_hash)
assert_equal(self.test_rest_request("/blockhashbyheight/{}".format(block_json_obj['height']))['blockhash'], bb_hash)
# Check hex/bin format
resp_hex = self.test_rest_request("/blockhashbyheight/{}".format(block_json_obj['height']), req_type=ReqType.HEX, ret_type=RetType.OBJ)
assert_equal(resp_hex.read().decode('utf-8').rstrip(), bb_hash)
resp_bytes = self.test_rest_request("/blockhashbyheight/{}".format(block_json_obj['height']), req_type=ReqType.BIN, ret_type=RetType.BYTES)
blockhash = binascii.hexlify(resp_bytes[::-1]).decode('utf-8')
assert_equal(blockhash, bb_hash)
# Check invalid blockhashbyheight requests
resp = self.test_rest_request("/blockhashbyheight/abc", ret_type=RetType.OBJ, status=400)
assert_equal(resp.read().decode('utf-8').rstrip(), "Invalid height: abc")
resp = self.test_rest_request("/blockhashbyheight/1000000", ret_type=RetType.OBJ, status=404)
assert_equal(resp.read().decode('utf-8').rstrip(), "Block height out of range")
resp = self.test_rest_request("/blockhashbyheight/-1", ret_type=RetType.OBJ, status=400)
assert_equal(resp.read().decode('utf-8').rstrip(), "Invalid height: -1")
self.test_rest_request("/blockhashbyheight/", ret_type=RetType.OBJ, status=400)
# Compare with json block header
json_obj = self.test_rest_request("/headers/1/{}".format(bb_hash))

View File

@ -70,7 +70,7 @@ class RPCBindTest(BitcoinTestFramework):
self.log.info("Check for ipv6")
have_ipv6 = test_ipv6_local()
if not have_ipv6 and not self.options.run_ipv4:
if not have_ipv6 and not (self.options.run_ipv4 or self.options.run_nonloopback):
raise SkipTest("This test requires ipv6 support.")
self.log.info("Check for non-loopback interface")

View File

@ -22,26 +22,29 @@ if ! command -v shellcheck > /dev/null; then
fi
# Disabled warnings:
# SC1087: Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet).
# SC1117: Backslash is literal in "\.". Prefer explicit escaping: "\\.".
# SC2001: See if you can use ${variable//search/replace} instead.
# SC2004: $/${} is unnecessary on arithmetic variables.
# SC2005: Useless echo? Instead of 'echo $(cmd)', just use 'cmd'.
# SC2006: Use $(..) instead of legacy `..`.
# SC2016: Expressions don't expand in single quotes, use double quotes for that.
# SC2028: echo won't expand escape sequences. Consider printf.
# SC2046: Quote this to prevent word splitting.
# SC2048: Use "$@" (with quotes) to prevent whitespace problems.
# SC2066: Since you double quoted this, it will not word split, and the loop will only run once.
# SC2086: Double quote to prevent globbing and word splitting.
# SC2116: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.
# SC2148: Tips depend on target shell and yours is unknown. Add a shebang.
# SC2162: read without -r will mangle backslashes.
# SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.
# SC2166: Prefer [ p ] || [ q ] as [ p -o q ] is not well defined.
# SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
# SC2206: Quote to prevent word splitting, or split robustly with mapfile or read -a.
# SC2207: Prefer mapfile or read -a to split command output (or quote to avoid splitting).
# SC2230: which is non-standard. Use builtin 'command -v' instead.
shellcheck -e SC1087,SC1117,SC2001,SC2004,SC2005,SC2006,SC2016,SC2028,SC2046,SC2048,SC2066,SC2086,SC2116,SC2148,SC2162,SC2166,SC2181,SC2206,SC2207,SC2230 \
disabled=(
SC1087 # Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet).
SC1117 # Backslash is literal in "\.". Prefer explicit escaping: "\\.".
SC2001 # See if you can use ${variable//search/replace} instead.
SC2004 # $/${} is unnecessary on arithmetic variables.
SC2005 # Useless echo? Instead of 'echo $(cmd)', just use 'cmd'.
SC2006 # Use $(..) instead of legacy `..`.
SC2016 # Expressions don't expand in single quotes, use double quotes for that.
SC2028 # echo won't expand escape sequences. Consider printf.
SC2046 # Quote this to prevent word splitting.
SC2048 # Use "$@" (with quotes) to prevent whitespace problems.
SC2066 # Since you double quoted this, it will not word split, and the loop will only run once.
SC2086 # Double quote to prevent globbing and word splitting.
SC2116 # Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.
SC2148 # Tips depend on target shell and yours is unknown. Add a shebang.
SC2162 # read without -r will mangle backslashes.
SC2166 # Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.
SC2166 # Prefer [ p ] || [ q ] as [ p -o q ] is not well defined.
SC2181 # Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
SC2206 # Quote to prevent word splitting, or split robustly with mapfile or read -a.
SC2207 # Prefer mapfile or read -a to split command output (or quote to avoid splitting).
SC2230 # which is non-standard. Use builtin 'command -v' instead.
SC2236 # Don't force -n instead of ! -z.
)
shellcheck -e "$(IFS=","; echo "${disabled[*]}")" \
$(git ls-files -- "*.sh" | grep -vE 'src/(secp256k1|univalue)/')