mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #4225 from PastaPastaPasta/backport-triv-pr5
backport: 'trivial' pr5
This commit is contained in:
commit
bc09637998
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
Pull requests without a rationale and clear improvement may be closed
|
||||
immediately.
|
||||
|
||||
Please provide clear motivation for your patch and explain how it improves
|
||||
Dash Core user experience or Dash Core developer experience
|
||||
significantly.
|
||||
|
||||
* Any test improvements or new tests that improve coverage are always welcome.
|
||||
* All other changes should have accompanying unit tests (see `src/test/`) or
|
||||
functional tests (see `test/`). Contributors should note which tests cover
|
||||
modified code. If no tests exist for a region of modified code, new tests
|
||||
should accompany the change.
|
||||
* Bug fixes are most welcome when they come with steps to reproduce or an
|
||||
explanation of the potential issue as well as reasoning for the way the bug
|
||||
was fixed.
|
||||
* Features are welcome, but might be rejected due to design or scope issues.
|
||||
If a feature is based on a lot of dependencies, contributors should first
|
||||
consider building the system outside of Dash Core, if possible.
|
@ -49,6 +49,8 @@ If a particular commit references another issue, please add the reference. For
|
||||
example: `refs #1234` or `fixes #4321`. Using the `fixes` or `closes` keywords
|
||||
will cause the corresponding issue to be closed when the pull request is merged.
|
||||
|
||||
Commit messages should never contain any `@` mentions.
|
||||
|
||||
Please refer to the [Git manual](https://git-scm.com/doc) for more information
|
||||
about Git.
|
||||
|
||||
@ -117,6 +119,10 @@ before it will be merged. The basic squashing workflow is shown below.
|
||||
# Save and quit.
|
||||
git push -f # (force push to GitHub)
|
||||
|
||||
Please update the resulting commit message if needed, it should read as a
|
||||
coherent message. In most cases this means that you should not just list the
|
||||
interim commits.
|
||||
|
||||
If you have problems with squashing (or other workflows with `git`), you can
|
||||
alternatively enable "Allow edits from maintainers" in the right GitHub
|
||||
sidebar and ask for help in the pull request.
|
||||
|
@ -168,7 +168,7 @@ $(BITCOIN_CLI_BIN): FORCE
|
||||
$(MAKE) -C src $(@F)
|
||||
|
||||
if USE_LCOV
|
||||
LCOV_FILTER_PATTERN=-p "/usr/include/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1"
|
||||
LCOV_FILTER_PATTERN=-p "/usr/include/" -p "/usr/lib/" -p "src/leveldb/" -p "src/bench/" -p "src/univalue" -p "src/crypto/ctaes" -p "src/secp256k1"
|
||||
|
||||
baseline.info:
|
||||
$(LCOV) -c -i -d $(abs_builddir)/src -o $@
|
||||
|
@ -819,6 +819,10 @@ fi
|
||||
|
||||
AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
||||
|
||||
AC_CHECK_DECLS([getifaddrs, freeifaddrs],,,
|
||||
[#include <sys/types.h>
|
||||
#include <ifaddrs.h>]
|
||||
)
|
||||
AC_CHECK_DECLS([strnlen])
|
||||
|
||||
# Check for daemon(3), unrelated to --with-daemon (although used by it)
|
||||
|
@ -1,23 +0,0 @@
|
||||
package=libICE
|
||||
$(package)_version=1.0.9
|
||||
$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=8f7032f2c1c64352b5423f6b48a8ebdc339cc63064af34d66a6c9aa79759e202
|
||||
$(package)_dependencies=xtrans xproto
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--disable-static --disable-docs --disable-specs --without-xsltproc
|
||||
$(package)_config_opts_linux=--with-pic
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
$($(package)_autoconf)
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE)
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
@ -1,23 +0,0 @@
|
||||
package=libSM
|
||||
$(package)_version=1.2.2
|
||||
$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=0baca8c9f5d934450a70896c4ad38d06475521255ca63b717a6510fdb6e287bd
|
||||
$(package)_dependencies=xtrans xproto libICE
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--without-libuuid --without-xsltproc --disable-docs --disable-static
|
||||
$(package)_config_opts_linux=--with-pic
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
$($(package)_autoconf)
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE)
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install
|
||||
endef
|
36
doc/JSON-RPC-interface.md
Normal file
36
doc/JSON-RPC-interface.md
Normal file
@ -0,0 +1,36 @@
|
||||
# JSON-RPC Interface
|
||||
|
||||
The headless daemon `dashd` has the JSON-RPC API enabled by default, the GUI
|
||||
`dash-qt` has it disabled by default. This can be changed with the `-server`
|
||||
option. In the GUI it is possible to execute RPC methods in the Debug Console
|
||||
Dialog.
|
||||
|
||||
## RPC consistency guarantees
|
||||
|
||||
State that can be queried via RPCs is guaranteed to be at least up-to-date with
|
||||
the chain state immediately prior to the call's execution. However, the state
|
||||
returned by RPCs that reflect the mempool may not be up-to-date with the
|
||||
current mempool state.
|
||||
|
||||
### Transaction Pool
|
||||
|
||||
The mempool state returned via an RPC is consistent with itself and with the
|
||||
chain state at the time of the call. Thus, the mempool state only encompasses
|
||||
transactions that are considered mine-able by the node at the time of the RPC.
|
||||
|
||||
The mempool state returned via an RPC reflects all effects of mempool and chain
|
||||
state related RPCs that returned prior to this call.
|
||||
|
||||
### Wallet
|
||||
|
||||
The wallet state returned via an RPC is consistent with itself and with the
|
||||
chain state at the time of the call.
|
||||
|
||||
Wallet RPCs will return the latest chain state consistent with prior non-wallet
|
||||
RPCs. The effects of all blocks (and transactions in blocks) at the time of the
|
||||
call is reflected in the state of all wallet transactions. For example, if a
|
||||
block contains transactions that conflicted with mempool transactions, the
|
||||
wallet would reflect the removal of these mempool transactions in the state.
|
||||
|
||||
However, the wallet may not be up-to-date with the current state of the mempool
|
||||
or the state of the mempool by an RPC that returned before this RPC.
|
@ -54,6 +54,7 @@ The Dash Core repo's [root README](/README.md) contains relevant information on
|
||||
- [Translation Process](translation_process.md)
|
||||
- [Translation Strings Policy](translation_strings_policy.md)
|
||||
- [Travis CI](travis-ci.md)
|
||||
- [JSON-RPC Interface](JSON-RPC-interface.md)
|
||||
- [Unauthenticated REST Interface](REST-interface.md)
|
||||
- [Shared Libraries](shared-libraries.md)
|
||||
- [BIPS](bips.md)
|
||||
@ -66,6 +67,7 @@ The Dash Core repo's [root README](/README.md) contains relevant information on
|
||||
|
||||
### Miscellaneous
|
||||
- [Assets Attribution](assets-attribution.md)
|
||||
- [dash.conf Configuration File](dash-conf.md)
|
||||
- [Files](files.md)
|
||||
- [Fuzz-testing](fuzzing.md)
|
||||
- [Reduce Traffic](reduce-traffic.md)
|
||||
|
@ -5,6 +5,12 @@ The REST API can be enabled with the `-rest` option.
|
||||
|
||||
The interface runs on the same port as the JSON-RPC interface, by default port 9998 for mainnet and port 19998 for testnet.
|
||||
|
||||
REST Interface consistency guarantees
|
||||
-------------------------------------
|
||||
|
||||
The [same guarantees as for the RPC Interface](/doc/JSON-RPC-interface.md#rpc-consistency-guarantees)
|
||||
apply.
|
||||
|
||||
Supported API
|
||||
-------------
|
||||
|
||||
|
37
doc/dash-conf.md
Normal file
37
doc/dash-conf.md
Normal file
@ -0,0 +1,37 @@
|
||||
# `dash.conf` Configuration File
|
||||
|
||||
The configuration file is used by `dashd`, `dash-qt` and `dash-cli`.
|
||||
|
||||
All command-line options (except for `-?`, `-help`, `-version` and `-conf`) may be specified in a configuration file, and all configuration file options (except for `includeconf`) may also be specified on the command line. Command-line options override values set in the configuration file and configuration file options override values set in the GUI.
|
||||
|
||||
## Configuration File Format
|
||||
|
||||
The configuration file is a plain text file and consists of `option=value` entries, one per line. Leading and trailing whitespaces are removed.
|
||||
|
||||
In contrast to the command-line usage:
|
||||
- an option must be specified without leading `-`;
|
||||
- a value of the given option is mandatory; e.g., `testnet=1` (for chain selection options), `noconnect=1` (for negated options).
|
||||
|
||||
### Blank lines
|
||||
|
||||
Blank lines are allowed and ignored by the parser.
|
||||
|
||||
### Comments
|
||||
|
||||
A comment starts with a number sign (`#`) and extends to the end of the line. All comments are ignored by the parser.
|
||||
|
||||
Comments may appear in two ways:
|
||||
- on their own on an otherwise empty line (_preferable_);
|
||||
- after an `option=value` entry.
|
||||
|
||||
### Network specific options
|
||||
|
||||
Network specific options can be:
|
||||
- placed into sections with headers `[main]` (not `[mainnet]`), `[test]` (not `[testnet]`) or `[regtest]`;
|
||||
- prefixed with a chain name; e.g., `regtest.maxmempool=100`.
|
||||
|
||||
## Configuration File Path
|
||||
|
||||
The configuration file is not automatically created; you can create it using your favorite text editor. By default, the configuration file name is `dash.conf` and it is located in the Dash data directory, but both the dash data directory and the configuration file path may be changed using the `-datadir` and `-conf` command-line options.
|
||||
|
||||
The `includeconf=<file>` option in the `dash.conf` file can be used to include additional configuration files.
|
@ -70,7 +70,7 @@ tool to clean up patches automatically before submission.
|
||||
- **Symbol naming conventions**. These are preferred in new code, but are not
|
||||
required when doing so would need changes to significant pieces of existing
|
||||
code.
|
||||
- Variable and namespace names are all lowercase, and may use `_` to
|
||||
- Variable (including function arguments) and namespace names are all lowercase, and may use `_` to
|
||||
separate words (snake_case).
|
||||
- Class member variables have a `m_` prefix.
|
||||
- Global variables have a `g_` prefix.
|
||||
@ -546,7 +546,7 @@ Strings and formatting
|
||||
- *Rationale*: These functions do overflow checking, and avoid pesky locale issues.
|
||||
|
||||
- Avoid using locale dependent functions if possible. You can use the provided
|
||||
[`lint-locale-dependence.sh`](/contrib/devtools/lint-locale-dependence.sh)
|
||||
[`lint-locale-dependence.sh`](/test/lint/lint-locale-dependence.sh)
|
||||
to check for accidental use of locale dependent functions.
|
||||
|
||||
- *Rationale*: Unnecessary locale dependence can cause bugs that are very tricky to isolate and fix.
|
||||
|
@ -332,6 +332,8 @@ libdash_server_a_SOURCES = \
|
||||
httpserver.cpp \
|
||||
index/base.cpp \
|
||||
index/txindex.cpp \
|
||||
interfaces/handler.cpp \
|
||||
interfaces/node.cpp \
|
||||
init.cpp \
|
||||
dbwrapper.cpp \
|
||||
governance/governance.cpp \
|
||||
@ -594,8 +596,6 @@ libdash_util_a_SOURCES = \
|
||||
compat/glibcxx_sanity.cpp \
|
||||
compat/strnlen.cpp \
|
||||
fs.cpp \
|
||||
interfaces/handler.cpp \
|
||||
interfaces/node.cpp \
|
||||
logging.cpp \
|
||||
random.cpp \
|
||||
rpc/protocol.cpp \
|
||||
|
@ -12,7 +12,6 @@
|
||||
typedef int64_t CAmount;
|
||||
|
||||
static const CAmount COIN = 100000000;
|
||||
static const CAmount CENT = 1000000;
|
||||
|
||||
/** No amount larger than this (in satoshi) is valid.
|
||||
*
|
||||
|
@ -176,7 +176,7 @@ unsigned int base_uint<BITS>::bits() const
|
||||
for (int pos = WIDTH - 1; pos >= 0; pos--) {
|
||||
if (pn[pos]) {
|
||||
for (int nbits = 31; nbits > 0; nbits--) {
|
||||
if (pn[pos] & 1 << nbits)
|
||||
if (pn[pos] & 1U << nbits)
|
||||
return 32 * pos + nbits + 1;
|
||||
}
|
||||
return 32 * pos + 1;
|
||||
|
@ -12,8 +12,8 @@
|
||||
// FIXME: Dedup with SetupDummyInputs in test/transaction_tests.cpp.
|
||||
//
|
||||
// Helper: create two dummy transactions, each with
|
||||
// two outputs. The first has 11 and 50 CENT outputs
|
||||
// paid to a TX_PUBKEY, the second 21 and 22 CENT outputs
|
||||
// two outputs. The first has 11 and 50 COIN outputs
|
||||
// paid to a TX_PUBKEY, the second 21 and 22 COIN outputs
|
||||
// paid to a TX_PUBKEYHASH.
|
||||
//
|
||||
static std::vector<CMutableTransaction>
|
||||
@ -31,16 +31,16 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet)
|
||||
|
||||
// Create some dummy input transactions
|
||||
dummyTransactions[0].vout.resize(2);
|
||||
dummyTransactions[0].vout[0].nValue = 11 * CENT;
|
||||
dummyTransactions[0].vout[0].nValue = 11 * COIN;
|
||||
dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
|
||||
dummyTransactions[0].vout[1].nValue = 50 * CENT;
|
||||
dummyTransactions[0].vout[1].nValue = 50 * COIN;
|
||||
dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
|
||||
AddCoins(coinsRet, dummyTransactions[0], 0);
|
||||
|
||||
dummyTransactions[1].vout.resize(2);
|
||||
dummyTransactions[1].vout[0].nValue = 21 * CENT;
|
||||
dummyTransactions[1].vout[0].nValue = 21 * COIN;
|
||||
dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID());
|
||||
dummyTransactions[1].vout[1].nValue = 22 * CENT;
|
||||
dummyTransactions[1].vout[1].nValue = 22 * COIN;
|
||||
dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID());
|
||||
AddCoins(coinsRet, dummyTransactions[1], 0);
|
||||
|
||||
@ -72,7 +72,7 @@ static void CCoinsCaching(benchmark::State& state)
|
||||
t1.vin[2].prevout.n = 1;
|
||||
t1.vin[2].scriptSig << std::vector<unsigned char>(65, 0) << std::vector<unsigned char>(33, 4);
|
||||
t1.vout.resize(2);
|
||||
t1.vout[0].nValue = 90 * CENT;
|
||||
t1.vout[0].nValue = 90 * COIN;
|
||||
t1.vout[0].scriptPubKey << OP_1;
|
||||
|
||||
// Benchmark.
|
||||
@ -80,7 +80,7 @@ static void CCoinsCaching(benchmark::State& state)
|
||||
bool success = AreInputsStandard(t1, coins);
|
||||
assert(success);
|
||||
CAmount value = coins.GetValueIn(t1);
|
||||
assert(value == (50 + 21 + 22) * CENT);
|
||||
assert(value == (50 + 21 + 22) * COIN);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ static void MutateTxAddOutMultiSig(CMutableTransaction& tx, const std::string& s
|
||||
if (vStrInputParts.size() < numkeys + 3)
|
||||
throw std::runtime_error("incorrect number of multisig pubkeys");
|
||||
|
||||
if (required < 1 || required > 20 || numkeys < 1 || numkeys > 20 || numkeys < required)
|
||||
if (required < 1 || required > MAX_PUBKEYS_PER_MULTISIG || numkeys < 1 || numkeys > MAX_PUBKEYS_PER_MULTISIG || numkeys < required)
|
||||
throw std::runtime_error("multisig parameter mismatch. Required " \
|
||||
+ std::to_string(required) + " of " + std::to_string(numkeys) + "signatures.");
|
||||
|
||||
|
@ -230,21 +230,25 @@ static void http_request_cb(struct evhttp_request* req, void* arg)
|
||||
}
|
||||
std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
|
||||
|
||||
LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
|
||||
RequestMethodString(hreq->GetRequestMethod()), hreq->GetURI(), hreq->GetPeer().ToString());
|
||||
|
||||
// Early address-based allow check
|
||||
if (!ClientAllowed(hreq->GetPeer())) {
|
||||
LogPrint(BCLog::HTTP, "HTTP request from %s rejected: Client network is not allowed RPC access\n",
|
||||
hreq->GetPeer().ToString());
|
||||
hreq->WriteReply(HTTP_FORBIDDEN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Early reject unknown HTTP methods
|
||||
if (hreq->GetRequestMethod() == HTTPRequest::UNKNOWN) {
|
||||
LogPrint(BCLog::HTTP, "HTTP request from %s rejected: Unknown HTTP request method\n",
|
||||
hreq->GetPeer().ToString());
|
||||
hreq->WriteReply(HTTP_BADMETHOD);
|
||||
return;
|
||||
}
|
||||
|
||||
LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
|
||||
RequestMethodString(hreq->GetRequestMethod()), SanitizeString(hreq->GetURI(), SAFE_CHARS_URI).substr(0, 100), hreq->GetPeer().ToString());
|
||||
|
||||
// Find registered handler for prefix
|
||||
std::string strURI = hreq->GetURI();
|
||||
std::string path;
|
||||
|
14
src/init.cpp
14
src/init.cpp
@ -1755,7 +1755,19 @@ bool AppInitMain()
|
||||
LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
|
||||
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
|
||||
LogPrintf("Using data directory %s\n", GetDataDir().string());
|
||||
LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)).string());
|
||||
|
||||
// Only log conf file usage message if conf file actually exists.
|
||||
fs::path config_file_path = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
||||
if (fs::exists(config_file_path)) {
|
||||
LogPrintf("Config file: %s\n", config_file_path.string());
|
||||
} else if (gArgs.IsArgSet("-conf")) {
|
||||
// Warn if no conf file exists at path provided by user
|
||||
InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string()));
|
||||
} else {
|
||||
// Not categorizing as "Warning" because it's the default behavior
|
||||
LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string());
|
||||
}
|
||||
|
||||
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
||||
|
||||
// Warn about relative -datadir path.
|
||||
|
@ -89,7 +89,7 @@ static int ec_privkey_import_der(const secp256k1_context* ctx, unsigned char *ou
|
||||
* will be set to the number of bytes used in the buffer.
|
||||
* key32 must point to a 32-byte raw private key.
|
||||
*/
|
||||
static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
|
||||
static int ec_privkey_export_der(const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, bool compressed) {
|
||||
assert(*privkeylen >= CKey::PRIVATE_KEY_SIZE);
|
||||
secp256k1_pubkey pubkey;
|
||||
size_t pubkeylen = 0;
|
||||
@ -170,7 +170,7 @@ CPrivKey CKey::GetPrivKey() const {
|
||||
size_t privkeylen;
|
||||
privkey.resize(PRIVATE_KEY_SIZE);
|
||||
privkeylen = PRIVATE_KEY_SIZE;
|
||||
ret = ec_privkey_export_der(secp256k1_context_sign, privkey.data(), &privkeylen, begin(), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
|
||||
ret = ec_privkey_export_der(secp256k1_context_sign, privkey.data(), &privkeylen, begin(), fCompressed);
|
||||
assert(ret);
|
||||
privkey.resize(privkeylen);
|
||||
return privkey;
|
||||
|
@ -2986,7 +2986,7 @@ void Discover()
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
|
||||
// Get local host ip
|
||||
struct ifaddrs* myaddrs;
|
||||
if (getifaddrs(&myaddrs) == 0)
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#ifndef WIN32
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <codecvt>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
|
||||
@ -671,13 +673,13 @@ bool LookupSubNet(const char* pszName, CSubNet& ret)
|
||||
#ifdef WIN32
|
||||
std::string NetworkErrorString(int err)
|
||||
{
|
||||
char buf[256];
|
||||
wchar_t buf[256];
|
||||
buf[0] = 0;
|
||||
if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
buf, sizeof(buf), nullptr))
|
||||
buf, ARRAYSIZE(buf), nullptr))
|
||||
{
|
||||
return strprintf("%s (%d)", buf, err);
|
||||
return strprintf("%s (%d)", std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf), err);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
/* Below flags apply in the context of BIP 68*/
|
||||
/* If this flag set, CTxIn::nSequence is NOT interpreted as a
|
||||
* relative lock-time. */
|
||||
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31);
|
||||
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
|
||||
|
||||
/* If CTxIn::nSequence encodes a relative lock-time and this flag
|
||||
* is set, the relative lock-time has units of 512 seconds,
|
||||
|
@ -572,8 +572,8 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
|
||||
case Qt::Key_Enter:
|
||||
// forward these events to lineEdit
|
||||
if(obj == autoCompleter->popup()) {
|
||||
autoCompleter->popup()->hide();
|
||||
QApplication::postEvent(ui->lineEdit, new QKeyEvent(*keyevt));
|
||||
autoCompleter->popup()->hide();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <key_io.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QMessageBox>
|
||||
|
||||
@ -136,5 +137,16 @@ void TestAddAddressesToSendBook()
|
||||
|
||||
void AddressBookTests::addressBookTests()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
if (QApplication::platformName() == "minimal") {
|
||||
// Disable for mac on "minimal" platform to avoid crashes inside the Qt
|
||||
// framework when it tries to look up unimplemented cocoa functions,
|
||||
// and fails to handle returned nulls
|
||||
// (https://bugreports.qt.io/browse/QTBUG-49686).
|
||||
QWARN("Skipping AddressBookTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
|
||||
"with 'test_dash-qt -platform cocoa' on mac, or else use a linux or windows build.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
TestAddAddressesToSendBook();
|
||||
}
|
||||
|
@ -209,5 +209,16 @@ void TestGUI()
|
||||
|
||||
void WalletTests::walletTests()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
if (QApplication::platformName() == "minimal") {
|
||||
// Disable for mac on "minimal" platform to avoid crashes inside the Qt
|
||||
// framework when it tries to look up unimplemented cocoa functions,
|
||||
// and fails to handle returned nulls
|
||||
// (https://bugreports.qt.io/browse/QTBUG-49686).
|
||||
QWARN("Skipping WalletTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
|
||||
"with 'test_dash-qt -platform cocoa' on mac, or else use a linux or windows build.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
TestGUI();
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ static inline uint64_t InsecureRandBits(int bits) { return insecure_rand_ctx.ran
|
||||
static inline uint64_t InsecureRandRange(uint64_t range) { return insecure_rand_ctx.randrange(range); }
|
||||
static inline bool InsecureRandBool() { return insecure_rand_ctx.randbool(); }
|
||||
|
||||
static constexpr CAmount CENT{1000000};
|
||||
|
||||
/** Basic testing setup.
|
||||
* This just configures logging and chain parameters.
|
||||
*/
|
||||
|
@ -48,7 +48,7 @@ bool ParseMoney(const char* pszIn, CAmount& nRet)
|
||||
if (*p == '.')
|
||||
{
|
||||
p++;
|
||||
int64_t nMult = CENT*10;
|
||||
int64_t nMult = COIN / 10;
|
||||
while (isdigit(*p) && (nMult > 0))
|
||||
{
|
||||
nUnits += nMult * (*p++ - '0');
|
||||
|
@ -20,6 +20,7 @@ static const std::string SAFE_CHARS[] =
|
||||
CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
|
||||
CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT
|
||||
CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME
|
||||
CHARS_ALPHA_NUM + "!*'();:@&=+$,/?#[]-_.~%", // SAFE_CHARS_URI
|
||||
};
|
||||
|
||||
std::string SanitizeString(const std::string& str, int rule)
|
||||
|
@ -28,6 +28,7 @@ enum SafeChars
|
||||
SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
|
||||
SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset
|
||||
SAFE_CHARS_FILENAME, //!< Chars allowed in filenames
|
||||
SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -62,6 +62,7 @@
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <codecvt>
|
||||
|
||||
#include <io.h> /* for _commit */
|
||||
#include <shlobj.h>
|
||||
@ -1045,7 +1046,7 @@ void CreatePidFile(const fs::path &path, pid_t pid)
|
||||
bool RenameOver(fs::path src, fs::path dest)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return MoveFileExA(src.string().c_str(), dest.string().c_str(),
|
||||
return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
|
||||
MOVEFILE_REPLACE_EXISTING) != 0;
|
||||
#else
|
||||
int rc = std::rename(src.string().c_str(), dest.string().c_str());
|
||||
@ -1202,7 +1203,11 @@ fs::path GetSpecialFolderPath(int nFolder, bool fCreate)
|
||||
void runCommand(const std::string& strCommand)
|
||||
{
|
||||
if (strCommand.empty()) return;
|
||||
#ifndef WIN32
|
||||
int nErr = ::system(strCommand.c_str());
|
||||
#else
|
||||
int nErr = ::_wsystem(std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().from_bytes(strCommand).c_str());
|
||||
#endif
|
||||
if (nErr)
|
||||
LogPrintf("runCommand error: system(%s) returned %d\n", strCommand, nErr);
|
||||
}
|
||||
|
@ -4677,6 +4677,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params, CCoinsView* view)
|
||||
for (int nHeight = nForkHeight + 1; nHeight <= pindexNew->nHeight; ++nHeight) {
|
||||
const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight);
|
||||
LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight);
|
||||
uiInterface.ShowProgress(_("Replaying blocks..."), (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false);
|
||||
if (!RollforwardBlock(pindex, cache, params)) return false;
|
||||
}
|
||||
|
||||
@ -5238,6 +5239,9 @@ bool DumpMempool(void)
|
||||
std::map<uint256, CAmount> mapDeltas;
|
||||
std::vector<TxMempoolInfo> vinfo;
|
||||
|
||||
static Mutex dump_mutex;
|
||||
LOCK(dump_mutex);
|
||||
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
for (const auto &i : mempool.mapDeltas) {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <random.h>
|
||||
|
||||
//! target minimum change amount
|
||||
static const CAmount MIN_CHANGE = CENT;
|
||||
static constexpr CAmount MIN_CHANGE{COIN / 100};
|
||||
//! final minimum change amount after paying for fees
|
||||
static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
|
||||
|
||||
|
@ -1036,6 +1036,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
|
||||
std::vector<unsigned char> vData(ParseHex(output));
|
||||
script = CScript(vData.begin(), vData.end());
|
||||
if (!ExtractDestination(script, dest) && !internal) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set to true for nonstandard scriptPubKey imports.");
|
||||
}
|
||||
}
|
||||
|
||||
// Watchonly and private keys
|
||||
@ -1048,11 +1051,6 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Incompatibility found between internal and label");
|
||||
}
|
||||
|
||||
// Not having Internal + Script
|
||||
if (!internal && isScript) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal must be set for hex scriptPubKey");
|
||||
}
|
||||
|
||||
// Keys / PubKeys size check.
|
||||
if (!isP2SH && (keys.size() > 1 || pubKeys.size() > 1)) { // Address / scriptPubKey
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "More than private key given for one address");
|
||||
@ -1156,21 +1154,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
CTxDestination pubkey_dest = pubKey.GetID();
|
||||
|
||||
// Consistency check.
|
||||
if (!isScript && !(pubkey_dest == dest)) {
|
||||
if (!(pubkey_dest == dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
|
||||
}
|
||||
|
||||
// Consistency check.
|
||||
if (isScript) {
|
||||
CTxDestination destination;
|
||||
|
||||
if (ExtractDestination(script, destination)) {
|
||||
if (!(destination == pubkey_dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CScript pubKeyScript = GetScriptForDestination(pubkey_dest);
|
||||
|
||||
if (::IsMine(*pwallet, pubKeyScript) == ISMINE_SPENDABLE) {
|
||||
@ -1221,21 +1208,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
CTxDestination pubkey_dest = pubKey.GetID();
|
||||
|
||||
// Consistency check.
|
||||
if (!isScript && !(pubkey_dest == dest)) {
|
||||
if (!(pubkey_dest == dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
|
||||
}
|
||||
|
||||
// Consistency check.
|
||||
if (isScript) {
|
||||
CTxDestination destination;
|
||||
|
||||
if (ExtractDestination(script, destination)) {
|
||||
if (!(destination == pubkey_dest)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Consistency check failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CKeyID vchAddress = pubKey.GetID();
|
||||
pwallet->MarkDirty();
|
||||
pwallet->SetAddressBook(vchAddress, label, "receive");
|
||||
@ -1267,11 +1243,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
|
||||
}
|
||||
|
||||
if (scriptPubKey.getType() == UniValue::VOBJ) {
|
||||
// add to address book or update label
|
||||
if (IsValidDestination(dest)) {
|
||||
pwallet->SetAddressBook(dest, label, "receive");
|
||||
}
|
||||
// add to address book or update label
|
||||
if (IsValidDestination(dest)) {
|
||||
pwallet->SetAddressBook(dest, label, "receive");
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
@ -2498,13 +2498,6 @@ static UniValue keypoolrefill(const JSONRPCRequest& request)
|
||||
}
|
||||
|
||||
|
||||
static void LockWallet(CWallet* pWallet)
|
||||
{
|
||||
LOCK(pWallet->cs_wallet);
|
||||
pWallet->nRelockTime = 0;
|
||||
pWallet->Lock();
|
||||
}
|
||||
|
||||
static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||
{
|
||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||
@ -2580,7 +2573,18 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||
pwallet->TopUpKeyPool();
|
||||
|
||||
pwallet->nRelockTime = GetTime() + nSleepTime;
|
||||
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), std::bind(LockWallet, pwallet), nSleepTime);
|
||||
|
||||
// Keep a weak pointer to the wallet so that it is possible to unload the
|
||||
// wallet before the following callback is called. If a valid shared pointer
|
||||
// is acquired in the callback then the wallet is still loaded.
|
||||
std::weak_ptr<CWallet> weak_wallet = wallet;
|
||||
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet] {
|
||||
if (auto shared_wallet = weak_wallet.lock()) {
|
||||
LOCK(shared_wallet->cs_wallet);
|
||||
shared_wallet->Lock();
|
||||
shared_wallet->nRelockTime = 0;
|
||||
}
|
||||
}, nSleepTime);
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
@ -840,6 +840,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
{
|
||||
encrypted_batch->TxnAbort();
|
||||
delete encrypted_batch;
|
||||
encrypted_batch = nullptr;
|
||||
// We now probably have half of our keys encrypted in memory, and half not...
|
||||
// die and let the user reload the unencrypted wallet.
|
||||
assert(false);
|
||||
@ -868,6 +869,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
|
||||
if (!encrypted_batch->TxnCommit()) {
|
||||
delete encrypted_batch;
|
||||
encrypted_batch = nullptr;
|
||||
// We now have keys encrypted in memory, but not on disk...
|
||||
// die to avoid confusion and let the user reload the unencrypted wallet.
|
||||
assert(false);
|
||||
|
@ -161,13 +161,13 @@ class ExampleTest(BitcoinTestFramework):
|
||||
self.tip = int(self.nodes[0].getbestblockhash(), 16)
|
||||
self.block_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time'] + 1
|
||||
|
||||
height = 1
|
||||
height = self.nodes[0].getblockcount()
|
||||
|
||||
for i in range(10):
|
||||
# Use the mininode and blocktools functionality to manually build a block
|
||||
# Calling the generate() rpc is easier, but this allows us to exactly
|
||||
# control the blocks and transactions.
|
||||
block = create_block(self.tip, create_coinbase(height), self.block_time)
|
||||
block = create_block(self.tip, create_coinbase(height+1), self.block_time)
|
||||
block.solve()
|
||||
block_message = msg_block(block)
|
||||
# Send message is used to send a P2P message to the node over our P2PInterface
|
||||
|
@ -43,12 +43,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
|
||||
tx = self.nodes[0].gettransaction(txid)
|
||||
assert(tx["confirmations"] > 0)
|
||||
|
||||
# Use invalidateblock to re-org back; all transactions should
|
||||
# end up unconfirmed and back in the mempool
|
||||
# Use invalidateblock to re-org back
|
||||
for node in self.nodes:
|
||||
node.invalidateblock(blocks[0])
|
||||
|
||||
# mempool should be empty, all txns confirmed
|
||||
# All txns should be back in mempool with 0 confirmations
|
||||
assert_equal(set(self.nodes[0].getrawmempool()), set(spends1_id+spends2_id))
|
||||
for txid in spends1_id+spends2_id:
|
||||
tx = self.nodes[0].gettransaction(txid)
|
||||
|
@ -223,7 +223,7 @@ def main():
|
||||
epilog='''
|
||||
Help text and arguments for individual test script:''',
|
||||
formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument('--combinedlogslen', '-c', type=int, default=0, help='print a combined log (of length n lines) from all test nodes and test framework to the console on failure.')
|
||||
parser.add_argument('--combinedlogslen', '-c', type=int, default=0, metavar='n', help='On failure, print a log (of length n lines) to the console, combined from the test framework and all test nodes.')
|
||||
parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface')
|
||||
parser.add_argument('--ci', action='store_true', help='Run checks and code that are usually only enabled in a continuous integration environment')
|
||||
parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude.')
|
||||
|
@ -26,7 +26,7 @@ import collections
|
||||
import enum
|
||||
import itertools
|
||||
|
||||
Call = enum.Enum("Call", "single multi")
|
||||
Call = enum.Enum("Call", "single multiaddress multiscript")
|
||||
Data = enum.Enum("Data", "address pub priv")
|
||||
Rescan = enum.Enum("Rescan", "no yes late_timestamp")
|
||||
|
||||
@ -53,11 +53,11 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")):
|
||||
response = self.try_rpc(self.node.importprivkey, privkey=self.key, label=self.label, rescan=rescan)
|
||||
assert_equal(response, None)
|
||||
|
||||
elif self.call == Call.multi:
|
||||
elif self.call in (Call.multiaddress, Call.multiscript):
|
||||
response = self.node.importmulti([{
|
||||
"scriptPubKey": {
|
||||
"address": self.address["address"]
|
||||
},
|
||||
} if self.call == Call.multiaddress else self.address["scriptPubKey"],
|
||||
"timestamp": timestamp + TIMESTAMP_WINDOW + (1 if self.rescan == Rescan.late_timestamp else 0),
|
||||
"pubkeys": [self.address["pubkey"]] if self.data == Data.pub else [],
|
||||
"keys": [self.key] if self.data == Data.priv else [],
|
||||
@ -142,7 +142,7 @@ class ImportRescanTest(BitcoinTestFramework):
|
||||
variant.label = "label {} {}".format(i, variant)
|
||||
variant.address = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress(variant.label))
|
||||
variant.key = self.nodes[1].dumpprivkey(variant.address["address"])
|
||||
variant.initial_amount = 10 - (i + 1) / 4.0
|
||||
variant.initial_amount = 1 - (i + 1) / 64
|
||||
variant.initial_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.initial_amount)
|
||||
|
||||
# Generate a block containing the initial transactions, then another
|
||||
@ -172,7 +172,7 @@ class ImportRescanTest(BitcoinTestFramework):
|
||||
|
||||
# Create new transactions sending to each address.
|
||||
for i, variant in enumerate(IMPORT_VARIANTS):
|
||||
variant.sent_amount = 10 - (2 * i + 1) / 8.0
|
||||
variant.sent_amount = 1 - (2 * i + 1) / 128
|
||||
variant.sent_txid = self.nodes[0].sendtoaddress(variant.address["address"], variant.sent_amount)
|
||||
|
||||
# Generate a block containing the new transactions.
|
||||
|
@ -3,6 +3,8 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test the importmulti RPC."""
|
||||
|
||||
from test_framework import script
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
|
||||
@ -78,16 +80,17 @@ class ImportMultiTest (BitcoinTestFramework):
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
# ScriptPubKey + !internal
|
||||
self.log.info("Should not import a scriptPubKey without internal flag")
|
||||
# Nonstandard scriptPubKey + !internal
|
||||
self.log.info("Should not import a nonstandard scriptPubKey without internal flag")
|
||||
nonstandardScriptPubKey = address['scriptPubKey'] + bytes_to_hex_str(script.CScript([script.OP_NOP]))
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"scriptPubKey": nonstandardScriptPubKey,
|
||||
"timestamp": "now",
|
||||
}])
|
||||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.')
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
@ -127,18 +130,18 @@ class ImportMultiTest (BitcoinTestFramework):
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
# ScriptPubKey + Public key + !internal
|
||||
self.log.info("Should not import a scriptPubKey without internal and with public key")
|
||||
# Nonstandard scriptPubKey + Public key + !internal
|
||||
self.log.info("Should not import a nonstandard scriptPubKey without internal and with public key")
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
request = [{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"scriptPubKey": nonstandardScriptPubKey,
|
||||
"timestamp": "now",
|
||||
"pubkeys": [ address['pubkey'] ]
|
||||
}]
|
||||
result = self.nodes[1].importmulti(request)
|
||||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.')
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
@ -206,17 +209,17 @@ class ImportMultiTest (BitcoinTestFramework):
|
||||
assert_equal(address_assert['ismine'], True)
|
||||
assert_equal(address_assert['timestamp'], timestamp)
|
||||
|
||||
# ScriptPubKey + Private key + !internal
|
||||
self.log.info("Should not import a scriptPubKey without internal and with private key")
|
||||
# Nonstandard scriptPubKey + Private key + !internal
|
||||
self.log.info("Should not import a nonstandard scriptPubKey without internal and with private key")
|
||||
address = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())
|
||||
result = self.nodes[1].importmulti([{
|
||||
"scriptPubKey": address['scriptPubKey'],
|
||||
"scriptPubKey": nonstandardScriptPubKey,
|
||||
"timestamp": "now",
|
||||
"keys": [ self.nodes[0].dumpprivkey(address['address']) ]
|
||||
}])
|
||||
assert_equal(result[0]['success'], False)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set for hex scriptPubKey')
|
||||
assert_equal(result[0]['error']['message'], 'Internal must be set to true for nonstandard scriptPubKey imports.')
|
||||
address_assert = self.nodes[1].getaddressinfo(address['address'])
|
||||
assert_equal(address_assert['iswatchonly'], False)
|
||||
assert_equal(address_assert['ismine'], False)
|
||||
|
@ -8,6 +8,7 @@ Verify that a dashd node can load multiple wallet files
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
import time
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.test_node import ErrorMatch
|
||||
@ -266,7 +267,11 @@ class MultiWalletTest(BitcoinTestFramework):
|
||||
assert 'w1' not in self.nodes[0].listwallets()
|
||||
|
||||
# Successfully unload the wallet referenced by the request endpoint
|
||||
# Also ensure unload works during walletpassphrase timeout
|
||||
w2.encryptwallet('test')
|
||||
w2.walletpassphrase('test', 1)
|
||||
w2.unloadwallet()
|
||||
time.sleep(1.1)
|
||||
assert 'w2' not in self.nodes[0].listwallets()
|
||||
|
||||
# Successfully unload all wallets
|
||||
|
Loading…
Reference in New Issue
Block a user