mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
Merge pull request #4638 from Munkybooty/backports-0.18-pr18
Backports 0.18 pr18
This commit is contained in:
commit
c67867582d
@ -644,7 +644,7 @@ case $host in
|
||||
AC_MSG_ERROR("windres not found")
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB"
|
||||
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601"
|
||||
if test "x$CXXFLAGS_overridden" = "xno"; then
|
||||
CXXFLAGS="$CXXFLAGS -w"
|
||||
fi
|
||||
|
@ -10,6 +10,7 @@ MANDIR=${MANDIR:-$TOPDIR/doc/man}
|
||||
BITCOIND=${BITCOIND:-$BINDIR/dashd}
|
||||
BITCOINCLI=${BITCOINCLI:-$BINDIR/dash-cli}
|
||||
BITCOINTX=${BITCOINTX:-$BINDIR/dash-tx}
|
||||
WALLET_TOOL=${WALLET_TOOL:-$BINDIR/dash-wallet}
|
||||
BITCOINQT=${BITCOINQT:-$BINDIR/qt/dash-qt}
|
||||
|
||||
[ ! -x $BITCOIND ] && echo "$BITCOIND not found or not executable." && exit 1
|
||||
@ -23,7 +24,7 @@ read -r -a BTCVER <<< "$($BITCOINCLI --version | head -n1 | awk -F'[ -]' '{ prin
|
||||
echo "[COPYRIGHT]" > footer.h2m
|
||||
$BITCOIND --version | sed -n '1!p' >> footer.h2m
|
||||
|
||||
for cmd in $BITCOIND $BITCOINCLI $BITCOINTX $BITCOINQT; do
|
||||
for cmd in $BITCOIND $BITCOINCLI $BITCOINTX $WALLET_TOOL $BITCOINQT; do
|
||||
cmdname="${cmd##*/}"
|
||||
help2man -N --version-string=${BTCVER[0]} --include=footer.h2m -o ${MANDIR}/${cmdname}.1 ${cmd}
|
||||
sed -i "s/\\\-${BTCVER[1]}//g" ${MANDIR}/${cmdname}.1
|
||||
|
@ -89,7 +89,7 @@ sign=SIGHASH\-FLAGS
|
||||
.IP
|
||||
Add zero or more signatures to transaction. This command requires JSON
|
||||
registers:prevtxs=JSON object, privatekeys=JSON object. See
|
||||
signrawtransaction docs for format of sighash flags, JSON
|
||||
signrawtransactionwithkey docs for format of sighash flags, JSON
|
||||
objects.
|
||||
.PP
|
||||
Register Commands:
|
||||
|
68
doc/man/dash-wallet.1
Normal file
68
doc/man/dash-wallet.1
Normal file
@ -0,0 +1,68 @@
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
|
||||
.TH DASH-WALLET "1" "February 2019" "dash-wallet v0.17.99.0" "User Commands"
|
||||
.SH NAME
|
||||
dash-wallet \- manual page for dash-wallet v0.17.99.0
|
||||
.SH DESCRIPTION
|
||||
DASH Core dash\-wallet version v0.17.99.0
|
||||
.PP
|
||||
wallet\-tool is an offline tool for creating and interacting with Dash Core wallet files.
|
||||
By default wallet\-tool will act on wallets in the default mainnet wallet directory in the datadir.
|
||||
To change the target wallet, use the \fB\-datadir\fR, \fB\-wallet\fR and \fB\-testnet\fR/\-regtest arguments.
|
||||
.SS "Usage:"
|
||||
.IP
|
||||
dash\-wallet [options] <command>
|
||||
.SH OPTIONS
|
||||
.HP
|
||||
\-?
|
||||
.IP
|
||||
This help message
|
||||
.HP
|
||||
\fB\-datadir=\fR<dir>
|
||||
.IP
|
||||
Specify data directory
|
||||
.HP
|
||||
\fB\-wallet=\fR<wallet\-name>
|
||||
.IP
|
||||
Specify wallet name
|
||||
.PP
|
||||
Debugging/Testing options:
|
||||
.HP
|
||||
\fB\-debug=\fR<category>
|
||||
.IP
|
||||
Output debugging information (default: 0).
|
||||
.HP
|
||||
\fB\-printtoconsole\fR
|
||||
.IP
|
||||
Send trace/debug info to console (default: 1 when no \fB\-debug\fR is true, 0
|
||||
otherwise.
|
||||
.PP
|
||||
Chain selection options:
|
||||
.HP
|
||||
\fB\-testnet\fR
|
||||
.IP
|
||||
Use the test chain
|
||||
.PP
|
||||
Commands:
|
||||
.IP
|
||||
create
|
||||
.IP
|
||||
Create new wallet file
|
||||
.IP
|
||||
info
|
||||
.IP
|
||||
Get wallet info
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 2014-2021 The Dash Core developers
|
||||
Copyright (C) 2009-2019 The Bitcoin Core developers
|
||||
|
||||
Please contribute if you find Bitcoin Core useful. Visit
|
||||
<https://bitcoincore.org> for further information about the software.
|
||||
The source code is available from <https://github.com/bitcoin/bitcoin>.
|
||||
|
||||
This is experimental software.
|
||||
Distributed under the MIT software license, see the accompanying file COPYING
|
||||
or <https://opensource.org/licenses/MIT>
|
||||
|
||||
This product includes software developed by the OpenSSL Project for use in the
|
||||
OpenSSL Toolkit <https://www.openssl.org> and cryptographic software written by
|
||||
Eric Young and UPnP software written by Thomas Bernard.
|
@ -57,7 +57,7 @@ Specify data directory
|
||||
.HP
|
||||
\fB\-dbcache=\fR<n>
|
||||
.IP
|
||||
Set database cache size in megabytes (4 to 16384, default: 300)
|
||||
Set database cache size in MiB (4 to 16384, default: 300)
|
||||
.HP
|
||||
\fB\-debuglogfile=\fR<file>
|
||||
.IP
|
||||
@ -741,7 +741,7 @@ relaying, mining and transaction creation (default: 0.00001)
|
||||
\fB\-whitelistforcerelay\fR
|
||||
.IP
|
||||
Force relay of transactions from whitelisted peers even if they violate
|
||||
local relay policy (default: 1)
|
||||
local relay policy (default: 0)
|
||||
.HP
|
||||
\fB\-whitelistrelay\fR
|
||||
.IP
|
||||
|
@ -11,10 +11,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
|
11
src/init.cpp
11
src/init.cpp
@ -1231,16 +1231,7 @@ bool AppInitBasicSetup()
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
// Enable Data Execution Prevention (DEP)
|
||||
// Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008
|
||||
// A failure is non-critical and needs no further attention!
|
||||
#ifndef PROCESS_DEP_ENABLE
|
||||
// We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7),
|
||||
// which is not correct. Can be removed, when GCCs winbase.h is fixed!
|
||||
#define PROCESS_DEP_ENABLE 0x00000001
|
||||
#endif
|
||||
typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
|
||||
PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
|
||||
if (setProcDEPPol != nullptr) setProcDEPPol(PROCESS_DEP_ENABLE);
|
||||
SetProcessDEPPolicy(PROCESS_DEP_ENABLE);
|
||||
#endif
|
||||
|
||||
if (!SetupNetworking())
|
||||
|
@ -10,16 +10,16 @@
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <timedata.h>
|
||||
#include <util/system.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/system.h>
|
||||
#include <util/validation.h>
|
||||
|
||||
#include <evo/specialtx.h>
|
||||
@ -33,14 +33,6 @@
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
// Unconfirmed transactions in the memory pool often depend on other
|
||||
// transactions in the memory pool. When we select transactions from the
|
||||
// pool, we select by highest fee rate of a transaction combined with all
|
||||
// its ancestors.
|
||||
|
||||
uint64_t nLastBlockTx = 0;
|
||||
uint64_t nLastBlockSize = 0;
|
||||
|
||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
||||
{
|
||||
int64_t nOldTime = pblock->nTime;
|
||||
@ -100,6 +92,9 @@ void BlockAssembler::resetBlock()
|
||||
nFees = 0;
|
||||
}
|
||||
|
||||
Optional<int64_t> BlockAssembler::m_last_block_num_txs{nullopt};
|
||||
Optional<int64_t> BlockAssembler::m_last_block_size{nullopt};
|
||||
|
||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||
{
|
||||
int64_t nTimeStart = GetTimeMicros();
|
||||
@ -160,8 +155,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||
|
||||
int64_t nTime1 = GetTimeMicros();
|
||||
|
||||
nLastBlockTx = nBlockTx;
|
||||
nLastBlockSize = nBlockSize;
|
||||
m_last_block_num_txs = nBlockTx;
|
||||
m_last_block_size = nBlockSize;
|
||||
LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps);
|
||||
|
||||
// Create coinbase transaction.
|
||||
|
@ -1,17 +1,19 @@
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_MINER_H
|
||||
#define BITCOIN_MINER_H
|
||||
|
||||
#include <optional.h>
|
||||
#include <primitives/block.h>
|
||||
#include <txmempool.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
|
||||
@ -159,6 +161,9 @@ public:
|
||||
/** Construct a new block template with coinbase to scriptPubKeyIn */
|
||||
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn);
|
||||
|
||||
static Optional<int64_t> m_last_block_num_txs;
|
||||
static Optional<int64_t> m_last_block_size;
|
||||
|
||||
private:
|
||||
// utility functions
|
||||
/** Clear the block's state and prepare for assembling a new block */
|
||||
|
11
src/net.cpp
11
src/net.cpp
@ -71,17 +71,6 @@ static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
|
||||
#define MSG_DONTWAIT 0
|
||||
#endif
|
||||
|
||||
// Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
|
||||
// Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
|
||||
#ifdef WIN32
|
||||
#ifndef PROTECTION_LEVEL_UNRESTRICTED
|
||||
#define PROTECTION_LEVEL_UNRESTRICTED 10
|
||||
#endif
|
||||
#ifndef IPV6_PROTECTION_LEVEL
|
||||
#define IPV6_PROTECTION_LEVEL 23
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Used to pass flags to the Bind() function */
|
||||
enum BindFlags {
|
||||
BF_NONE = 0,
|
||||
|
@ -86,9 +86,6 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
|
||||
aiHint.ai_protocol = IPPROTO_TCP;
|
||||
// We don't care which address family (IPv4 or IPv6) is returned
|
||||
aiHint.ai_family = AF_UNSPEC;
|
||||
#ifdef WIN32
|
||||
aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST;
|
||||
#else
|
||||
// If we allow lookups of hostnames, use the AI_ADDRCONFIG flag to only
|
||||
// return addresses whose family we have an address configured for.
|
||||
//
|
||||
@ -96,7 +93,6 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
|
||||
// getaddrinfo to only decode numerical network addresses and suppress
|
||||
// hostname lookups.
|
||||
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
|
||||
#endif
|
||||
struct addrinfo *aiRes = nullptr;
|
||||
int nErr = getaddrinfo(pszName, nullptr, &aiHint, &aiRes);
|
||||
if (nErr)
|
||||
|
@ -26,10 +26,6 @@
|
||||
#include <util/system.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#ifdef _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#endif
|
||||
|
@ -199,36 +199,36 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
|
||||
|
||||
static UniValue getmininginfo(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() != 0)
|
||||
if (request.fHelp || request.params.size() != 0) {
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"getmininginfo",
|
||||
"\nReturns a json object containing mining-related information.",
|
||||
{},
|
||||
RPCResult{
|
||||
"{\n"
|
||||
" \"blocks\": nnn, (numeric) The current block\n"
|
||||
" \"currentblocksize\": nnn, (numeric) The last block size\n"
|
||||
" \"currentblocktx\": nnn, (numeric) The last block transaction\n"
|
||||
" \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
|
||||
" \"networkhashps\": nnn, (numeric) The network hashes per second\n"
|
||||
" \"pooledtx\": n (numeric) The size of the mempool\n"
|
||||
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
|
||||
" \"warnings\": \"...\" (string) any network and blockchain warnings\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
" \"blocks\": nnn, (numeric) The current block\n"
|
||||
" \"currentblocksize\": nnn, (numeric, optional) The block size of the last assembled block (only present if a block was ever assembled)\n"
|
||||
" \"currentblocktx\": nnn, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled)\n"
|
||||
" \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n"
|
||||
" \"networkhashps\": nnn, (numeric) The network hashes per second\n"
|
||||
" \"pooledtx\": n (numeric) The size of the mempool\n"
|
||||
" \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n"
|
||||
" \"warnings\": \"...\" (string) any network and blockchain warnings\n"
|
||||
"}\n"
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("getmininginfo", "")
|
||||
+ HelpExampleRpc("getmininginfo", "")
|
||||
},
|
||||
}.ToString());
|
||||
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("blocks", (int)::ChainActive().Height());
|
||||
obj.pushKV("currentblocksize", (uint64_t)nLastBlockSize);
|
||||
obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx);
|
||||
if (BlockAssembler::m_last_block_size) obj.pushKV("currentblocksize", *BlockAssembler::m_last_block_size);
|
||||
if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
|
||||
obj.pushKV("difficulty", (double)GetDifficulty(::ChainActive().Tip()));
|
||||
obj.pushKV("networkhashps", getnetworkhashps(request));
|
||||
obj.pushKV("pooledtx", (uint64_t)mempool.size());
|
||||
|
@ -113,13 +113,17 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
|
||||
throw std::runtime_error(
|
||||
RPCHelpMan{"getrawtransaction",
|
||||
RPCHelpMan{
|
||||
"getrawtransaction",
|
||||
"\nReturn the raw transaction data.\n"
|
||||
|
||||
"\nBy default this function only works for mempool transactions. When called with a blockhash\n"
|
||||
"argument, getrawtransaction will return the transaction if the specified block is available and\n"
|
||||
"the transaction is found in that block. When called without a blockhash argument, getrawtransaction\n"
|
||||
"will return the transaction if it is in the mempool, or if -txindex is enabled and the transaction\n"
|
||||
"is in a block in the blockchain.\n"
|
||||
"\nReturn the raw transaction data.\n"
|
||||
"\nHint: use getmempoolentry to fetch a specific transaction from the mempool.\n"
|
||||
"Or use gettransaction for wallet transactions.\n"
|
||||
"\nIf verbose is 'true', returns an Object with information about 'txid'.\n"
|
||||
"If verbose is 'false' or omitted, returns a string that is serialized, hex-encoded data for 'txid'.\n",
|
||||
{
|
||||
|
@ -10,10 +10,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
|
@ -46,11 +46,6 @@
|
||||
#pragma warning(disable:4717)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0501
|
||||
|
||||
#ifdef _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#endif
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <coins.h>
|
||||
#include <crypto/common.h> // for ReadLE64
|
||||
#include <fs.h>
|
||||
#include <protocol.h> // For CMessageHeader::MessageStartChars
|
||||
#include <policy/feerate.h>
|
||||
#include <protocol.h> // For CMessageHeader::MessageStartChars
|
||||
#include <script/script_error.h>
|
||||
#include <sync.h>
|
||||
#include <txdb.h>
|
||||
@ -123,8 +123,6 @@ extern CBlockPolicyEstimator feeEstimator;
|
||||
extern CTxMemPool mempool;
|
||||
typedef std::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap;
|
||||
typedef std::unordered_multimap<uint256, CBlockIndex*, BlockHasher> PrevBlockMap;
|
||||
extern uint64_t nLastBlockTx;
|
||||
extern uint64_t nLastBlockSize;
|
||||
extern Mutex g_best_block_mutex;
|
||||
extern std::condition_variable g_best_block_cv;
|
||||
extern uint256 g_best_block;
|
||||
|
@ -1173,7 +1173,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
|
||||
}
|
||||
}
|
||||
|
||||
static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data)
|
||||
static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)
|
||||
{
|
||||
UniValue warnings(UniValue::VARR);
|
||||
|
||||
@ -1236,6 +1236,7 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey \"" + str + "\" is not a valid public key");
|
||||
}
|
||||
pubkey_map.emplace(pubkey.GetID(), pubkey);
|
||||
ordered_pubkeys.push_back(pubkey.GetID());
|
||||
}
|
||||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
const auto& str = keys[i].get_str();
|
||||
@ -1307,7 +1308,7 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
|
||||
return warnings;
|
||||
}
|
||||
|
||||
static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data)
|
||||
static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)
|
||||
{
|
||||
UniValue warnings(UniValue::VARR);
|
||||
|
||||
@ -1334,22 +1335,25 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
|
||||
|
||||
const UniValue& priv_keys = data.exists("keys") ? data["keys"].get_array() : UniValue();
|
||||
|
||||
FlatSigningProvider out_keys;
|
||||
|
||||
// Expand all descriptors to get public keys and scripts.
|
||||
// TODO: get private keys from descriptors too
|
||||
for (int i = range_start; i <= range_end; ++i) {
|
||||
FlatSigningProvider out_keys;
|
||||
std::vector<CScript> scripts_temp;
|
||||
parsed_desc->Expand(i, keys, scripts_temp, out_keys);
|
||||
std::copy(scripts_temp.begin(), scripts_temp.end(), std::inserter(script_pub_keys, script_pub_keys.end()));
|
||||
for (const auto& key_pair: out_keys.pubkeys) {
|
||||
ordered_pubkeys.push_back(key_pair.first);
|
||||
}
|
||||
|
||||
for (const auto& x: out_keys.scripts) {
|
||||
import_data.import_scripts.emplace(x.second);
|
||||
}
|
||||
|
||||
std::copy(out_keys.pubkeys.begin(), out_keys.pubkeys.end(), std::inserter(pubkey_map, pubkey_map.end()));
|
||||
import_data.key_origins.insert(out_keys.origins.begin(), out_keys.origins.end());
|
||||
}
|
||||
|
||||
for (const auto& x : out_keys.scripts) {
|
||||
import_data.import_scripts.emplace(x.second);
|
||||
}
|
||||
|
||||
std::copy(out_keys.pubkeys.begin(), out_keys.pubkeys.end(), std::inserter(pubkey_map, pubkey_map.end()));
|
||||
import_data.key_origins.insert(out_keys.origins.begin(), out_keys.origins.end());
|
||||
for (size_t i = 0; i < priv_keys.size(); ++i) {
|
||||
const auto& str = priv_keys[i].get_str();
|
||||
CKey key = DecodeSecret(str);
|
||||
@ -1400,19 +1404,26 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Internal addresses should not have a label");
|
||||
}
|
||||
const std::string& label = data.exists("label") ? data["label"].get_str() : "";
|
||||
const bool add_keypool = data.exists("keypool") ? data["keypool"].get_bool() : false;
|
||||
|
||||
// Add to keypool only works with privkeys disabled
|
||||
if (add_keypool && !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Keys can only be imported to the keypool when private keys are disabled");
|
||||
}
|
||||
|
||||
ImportData import_data;
|
||||
std::map<CKeyID, CPubKey> pubkey_map;
|
||||
std::map<CKeyID, CKey> privkey_map;
|
||||
std::set<CScript> script_pub_keys;
|
||||
std::vector<CKeyID> ordered_pubkeys;
|
||||
bool have_solving_data;
|
||||
|
||||
if (data.exists("scriptPubKey") && data.exists("desc")) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Both a descriptor and a scriptPubKey should not be provided.");
|
||||
} else if (data.exists("scriptPubKey")) {
|
||||
warnings = ProcessImportLegacy(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data);
|
||||
warnings = ProcessImportLegacy(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys);
|
||||
} else if (data.exists("desc")) {
|
||||
warnings = ProcessImportDescriptor(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data);
|
||||
warnings = ProcessImportDescriptor(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys);
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Either a descriptor or scriptPubKey must be provided.");
|
||||
}
|
||||
@ -1437,7 +1448,7 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
|
||||
if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
||||
}
|
||||
if (!pwallet->ImportPubKeys(pubkey_map, timestamp, import_data.key_origins)) {
|
||||
if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.key_origins, add_keypool, internal, timestamp)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet");
|
||||
}
|
||||
if (!pwallet->ImportScriptPubKeys(label, script_pub_keys, have_solving_data, internal, timestamp)) {
|
||||
|
@ -168,11 +168,6 @@ UniValue getnewaddress(const JSONRPCRequest& request)
|
||||
},
|
||||
}.ToString());
|
||||
|
||||
// Belt and suspenders check for disabled private keys
|
||||
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet");
|
||||
}
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
if (!pwallet->CanGetAddresses()) {
|
||||
@ -224,11 +219,6 @@ static UniValue getrawchangeaddress(const JSONRPCRequest& request)
|
||||
},
|
||||
}.ToString());
|
||||
|
||||
// Belt and suspenders check for disabled private keys
|
||||
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet");
|
||||
}
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
if (!pwallet->CanGetAddresses(true)) {
|
||||
@ -2591,9 +2581,7 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
|
||||
obj.pushKV("timefirstkey", pwallet->GetTimeFirstKey());
|
||||
obj.pushKV("keypoololdest", pwallet->GetOldestKeyPoolTime());
|
||||
obj.pushKV("keypoolsize", (int64_t)pwallet->KeypoolCountExternalKeys());
|
||||
if (fHDEnabled) {
|
||||
obj.pushKV("keypoolsize_hd_internal", (int64_t)(pwallet->KeypoolCountInternalKeys()));
|
||||
}
|
||||
obj.pushKV("keypoolsize_hd_internal", (int64_t)(pwallet->KeypoolCountInternalKeys()));
|
||||
obj.pushKV("keys_left", pwallet->nKeysLeftSinceAutoBackup);
|
||||
if (pwallet->IsCrypted())
|
||||
obj.pushKV("unlocked_until", pwallet->nRelockTime);
|
||||
|
@ -2121,17 +2121,25 @@ bool CWallet::ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const in
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::ImportPubKeys(const std::map<CKeyID, CPubKey>& pubkey_map, const int64_t timestamp, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins)
|
||||
bool CWallet::ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp)
|
||||
{
|
||||
WalletBatch batch(*database);
|
||||
for (const auto& entry : pubkey_map) {
|
||||
const CKeyID& id = entry.first;
|
||||
const CPubKey& pubkey = entry.second;
|
||||
for (const CKeyID& id : ordered_pubkeys) {
|
||||
auto entry = pubkey_map.find(id);
|
||||
if (entry == pubkey_map.end()) {
|
||||
continue;
|
||||
}
|
||||
const CPubKey& pubkey = entry->second;
|
||||
CPubKey temp;
|
||||
if (!GetPubKey(id, temp) && !AddWatchOnlyWithDB(batch, GetScriptForRawPubKey(pubkey), timestamp)) {
|
||||
return false;
|
||||
}
|
||||
mapKeyMetadata[id].nCreateTime = timestamp;
|
||||
// Add to keypool only works with pubkeys
|
||||
if (add_keypool) {
|
||||
AddKeypoolPubkeyWithDB(pubkey, internal, batch);
|
||||
NotifyCanGetAddressesChanged();
|
||||
}
|
||||
}
|
||||
for (const auto& entry : key_origins) {
|
||||
AddKeyOrigin(entry.second.first, entry.second.second);
|
||||
@ -3659,8 +3667,8 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
// post-backup change.
|
||||
|
||||
// Reserve a new key pair from key pool
|
||||
if (IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
strFailReason = _("Can't generate a change-address key. Private keys are disabled for this wallet.");
|
||||
if (!CanGetAddresses(true)) {
|
||||
strFailReason = _("Can't generate a change-address key. No keys in the internal keypool and can't generate any keys.");
|
||||
return false;
|
||||
}
|
||||
CPubKey vchPubKey;
|
||||
@ -4314,29 +4322,17 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
||||
fInternal = true;
|
||||
}
|
||||
|
||||
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
|
||||
int64_t index = ++m_max_keypool_index;
|
||||
|
||||
// TODO: implement keypools for all accounts?
|
||||
CPubKey pubkey(GenerateNewKey(batch, 0, fInternal));
|
||||
if (!batch.WritePool(index, CKeyPool(pubkey, fInternal))) {
|
||||
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
|
||||
}
|
||||
AddKeypoolPubkeyWithDB(pubkey, fInternal, batch);
|
||||
|
||||
if (fInternal) {
|
||||
setInternalKeyPool.insert(index);
|
||||
} else {
|
||||
setExternalKeyPool.insert(index);
|
||||
}
|
||||
|
||||
m_pool_key_to_index[pubkey.GetID()] = index;
|
||||
if (missingInternal + missingExternal > 0) {
|
||||
WalletLogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n",
|
||||
missingInternal + missingExternal, missingInternal,
|
||||
setInternalKeyPool.size() + setExternalKeyPool.size(), setInternalKeyPool.size());
|
||||
}
|
||||
|
||||
double dProgress = 100.f * index / (nTargetSize + 1);
|
||||
double dProgress = 100.f * m_max_keypool_index / (nTargetSize + 1);
|
||||
std::string strMsg = strprintf(_("Loading wallet... (%3.2f %%)"), dProgress);
|
||||
uiInterface.InitMessage(strMsg);
|
||||
}
|
||||
@ -4345,6 +4341,29 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWallet::AddKeypoolPubkey(const CPubKey& pubkey, const bool internal)
|
||||
{
|
||||
WalletBatch batch(*database);
|
||||
AddKeypoolPubkeyWithDB(pubkey, internal, batch);
|
||||
NotifyCanGetAddressesChanged();
|
||||
}
|
||||
|
||||
void CWallet::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
|
||||
int64_t index = ++m_max_keypool_index;
|
||||
if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
|
||||
throw std::runtime_error(std::string(__func__) + ": writing imported pubkey failed");
|
||||
}
|
||||
if (internal) {
|
||||
setInternalKeyPool.insert(index);
|
||||
} else {
|
||||
setExternalKeyPool.insert(index);
|
||||
}
|
||||
m_pool_key_to_index[pubkey.GetID()] = index;
|
||||
}
|
||||
|
||||
bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal)
|
||||
{
|
||||
nIndex = -1;
|
||||
@ -4354,7 +4373,8 @@ bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
|
||||
|
||||
TopUpKeyPool();
|
||||
|
||||
bool fReturningInternal = IsHDEnabled() && fRequestedInternal;
|
||||
bool fReturningInternal = fRequestedInternal;
|
||||
fReturningInternal &= IsHDEnabled() || IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
|
||||
std::set<int64_t>& setKeyPool = fReturningInternal ? setInternalKeyPool : setExternalKeyPool;
|
||||
|
||||
// Get the oldest key
|
||||
@ -4369,7 +4389,8 @@ bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
|
||||
if (!batch.ReadPool(nIndex, keypool)) {
|
||||
throw std::runtime_error(std::string(__func__) + ": read failed");
|
||||
}
|
||||
if (!HaveKey(keypool.vchPubKey.GetID())) {
|
||||
CPubKey pk;
|
||||
if (!GetPubKey(keypool.vchPubKey.GetID(), pk)) {
|
||||
throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
|
||||
}
|
||||
if (keypool.fInternal != fReturningInternal) {
|
||||
@ -4426,10 +4447,9 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
int64_t nIndex;
|
||||
if (!ReserveKeyFromKeyPool(nIndex, keypool, internal)) {
|
||||
if (!ReserveKeyFromKeyPool(nIndex, keypool, internal) && !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
if (IsLocked(true)) return false;
|
||||
// TODO: implement keypool for all accouts?
|
||||
|
||||
WalletBatch batch(*database);
|
||||
result = GenerateNewKey(batch, 0, internal);
|
||||
return true;
|
||||
|
@ -1007,7 +1007,7 @@ public:
|
||||
|
||||
bool ImportScripts(const std::set<CScript> scripts) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool ImportPrivKeys(const std::map<CKeyID, CKey>& privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool ImportPubKeys(const std::map<CKeyID, CPubKey>& pubkey_map, const int64_t timestamp, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool ImportPubKeys(const std::vector<CKeyID>& ordered_pubkeys, const std::map<CKeyID, CPubKey>& pubkey_map, const std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool ImportScriptPubKeys(const std::string& label, const std::set<CScript>& script_pub_keys, const bool have_solving_data, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
CFeeRate m_pay_tx_fee{DEFAULT_PAY_TX_FEE};
|
||||
@ -1029,6 +1029,8 @@ public:
|
||||
size_t KeypoolCountExternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
size_t KeypoolCountInternalKeys() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
bool TopUpKeyPool(unsigned int kpSize = 0);
|
||||
void AddKeypoolPubkey(const CPubKey& pubkey, const bool internal);
|
||||
void AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch);
|
||||
|
||||
/**
|
||||
* Reserves a key from the keypool and sets nIndex to its index
|
||||
|
@ -46,7 +46,7 @@ from decimal import Decimal
|
||||
from itertools import product
|
||||
from io import BytesIO
|
||||
|
||||
from test_framework.blocktools import create_coinbase, create_block, create_transaction
|
||||
from test_framework.blocktools import create_coinbase, create_block, create_transaction, TIME_GENESIS_BLOCK
|
||||
from test_framework.messages import ToHex, CTransaction
|
||||
from test_framework.mininode import P2PDataStore
|
||||
from test_framework.script import (
|
||||
@ -54,7 +54,7 @@ from test_framework.script import (
|
||||
OP_CHECKSEQUENCEVERIFY,
|
||||
OP_DROP,
|
||||
)
|
||||
from test_framework.test_framework import (BitcoinTestFramework, GENESISTIME)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
get_bip9_status,
|
||||
@ -186,9 +186,9 @@ class BIP68_112_113Test(BitcoinTestFramework):
|
||||
self.coinbase_blocks = self.nodes[0].generate(1 + 16 + 2 * 32 + 1) # 82 blocks generated for inputs
|
||||
# set time so that there was enough time to build up to 1000 blocks 10 minutes apart on top of the last one
|
||||
# without worrying about getting into the future
|
||||
self.nodes[0].setmocktime(GENESISTIME + 600 * 1000 + 100)
|
||||
self.nodes[0].setmocktime(TIME_GENESIS_BLOCK + 600 * 1000 + 100)
|
||||
self.tipheight = 82 # height of the next block to build
|
||||
self.last_block_time = GENESISTIME
|
||||
self.last_block_time = TIME_GENESIS_BLOCK
|
||||
self.tip = int(self.nodes[0].getbestblockhash(), 16)
|
||||
self.nodeaddress = self.nodes[0].getnewaddress()
|
||||
|
||||
@ -261,7 +261,7 @@ class BIP68_112_113Test(BitcoinTestFramework):
|
||||
|
||||
self.nodes[0].setmocktime(self.last_block_time + 600)
|
||||
inputblockhash = self.nodes[0].generate(1)[0] # 1 block generated for inputs to be in chain at height 572
|
||||
self.nodes[0].setmocktime(GENESISTIME + 600 * 1000 + 100)
|
||||
self.nodes[0].setmocktime(TIME_GENESIS_BLOCK + 600 * 1000 + 100)
|
||||
self.tip = int(inputblockhash, 16)
|
||||
self.tipheight += 1
|
||||
self.last_block_time += 600
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2014-2016 The Bitcoin Core developers
|
||||
# Copyright (c) 2014-2018 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test mining RPCs
|
||||
@ -11,7 +11,9 @@
|
||||
import copy
|
||||
from decimal import Decimal
|
||||
|
||||
from test_framework.blocktools import create_coinbase
|
||||
from test_framework.blocktools import (
|
||||
create_coinbase,
|
||||
)
|
||||
from test_framework.messages import (
|
||||
CBlock,
|
||||
CBlockHeader,
|
||||
@ -23,6 +25,7 @@ from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_raises_rpc_error,
|
||||
connect_nodes,
|
||||
)
|
||||
from test_framework.script import CScriptNum
|
||||
|
||||
@ -37,9 +40,23 @@ def assert_template(node, block, expect, rehash=True):
|
||||
class MiningTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.setup_clean_chain = False
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def mine_chain(self):
|
||||
self.log.info('Create some old blocks')
|
||||
for _ in range(0, 200):
|
||||
self.bump_mocktime(156)
|
||||
self.nodes[0].generate(1)
|
||||
mining_info = self.nodes[0].getmininginfo()
|
||||
assert_equal(mining_info['blocks'], 200)
|
||||
assert_equal(mining_info['currentblocktx'], 0)
|
||||
assert_equal(mining_info['currentblocksize'], 1000)
|
||||
self.restart_node(0)
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
|
||||
def run_test(self):
|
||||
self.mine_chain()
|
||||
node = self.nodes[0]
|
||||
|
||||
def assert_submitblock(block, result_str_1, result_str_2=None):
|
||||
@ -52,8 +69,8 @@ class MiningTest(BitcoinTestFramework):
|
||||
mining_info = node.getmininginfo()
|
||||
assert_equal(mining_info['blocks'], 200)
|
||||
assert_equal(mining_info['chain'], self.chain)
|
||||
assert_equal(mining_info['currentblocksize'], 0)
|
||||
assert_equal(mining_info['currentblocktx'], 0)
|
||||
assert 'currentblocksize' not in mining_info
|
||||
assert 'currentblocktx' not in mining_info
|
||||
assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10'))
|
||||
assert_equal(mining_info['networkhashps'], Decimal('0.01282051282051282'))
|
||||
assert_equal(mining_info['pooledtx'], 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2015-2016 The Bitcoin Core developers
|
||||
# Copyright (c) 2015-2018 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Utilities for manipulating blocks and transactions."""
|
||||
@ -19,6 +19,9 @@ from io import BytesIO
|
||||
|
||||
MAX_BLOCK_SIGOPS = 20000
|
||||
|
||||
# Genesis block time (regtest)
|
||||
TIME_GENESIS_BLOCK = 1417713337
|
||||
|
||||
def create_block(hashprev, coinbase, ntime=None):
|
||||
"""Create a block (with regtest difficulty)."""
|
||||
block = CBlock()
|
||||
|
@ -20,6 +20,7 @@ import time
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from .authproxy import JSONRPCException
|
||||
from test_framework.blocktools import TIME_GENESIS_BLOCK
|
||||
from . import coverage
|
||||
from .messages import (
|
||||
CTransaction,
|
||||
@ -63,7 +64,6 @@ TEST_EXIT_PASSED = 0
|
||||
TEST_EXIT_FAILED = 1
|
||||
TEST_EXIT_SKIPPED = 77
|
||||
|
||||
GENESISTIME = 1417713337
|
||||
TMPDIR_PREFIX = "dash_func_test_"
|
||||
|
||||
class SkipTest(Exception):
|
||||
@ -400,6 +400,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||
bitcoin_cli=self.options.bitcoincli,
|
||||
mocktime=self.mocktime,
|
||||
coverage_dir=self.options.coveragedir,
|
||||
cwd=self.options.tmpdir,
|
||||
extra_conf=extra_confs[i],
|
||||
extra_args=extra_args[i],
|
||||
use_cli=self.options.usecli,
|
||||
@ -506,12 +507,12 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||
# For backwared compatibility of the python scripts
|
||||
# with previous versions of the cache, set MOCKTIME
|
||||
# to regtest genesis time + (201 * 156)
|
||||
self.mocktime = GENESISTIME + (201 * 156)
|
||||
self.mocktime = TIME_GENESIS_BLOCK + (201 * 156)
|
||||
for node in self.nodes:
|
||||
node.mocktime = self.mocktime
|
||||
|
||||
def set_genesis_mocktime(self):
|
||||
self.mocktime = GENESISTIME
|
||||
self.mocktime = TIME_GENESIS_BLOCK
|
||||
for node in self.nodes:
|
||||
node.mocktime = self.mocktime
|
||||
|
||||
@ -570,7 +571,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||
self.set_genesis_mocktime()
|
||||
for i in range(MAX_NODES):
|
||||
datadir = initialize_datadir(self.options.cachedir, i, self.chain)
|
||||
args = [self.options.bitcoind, "-datadir=" + datadir, "-mocktime="+str(GENESISTIME), '-disablewallet']
|
||||
args = [self.options.bitcoind, "-datadir=" + datadir, "-mocktime="+str(TIME_GENESIS_BLOCK), '-disablewallet']
|
||||
if i > 0:
|
||||
args.append("-connect=127.0.0.1:" + str(p2p_port(0)))
|
||||
if extra_args is not None:
|
||||
@ -581,6 +582,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||
bitcoin_cli=self.options.bitcoincli,
|
||||
mocktime=self.mocktime,
|
||||
coverage_dir=None,
|
||||
cwd=self.options.tmpdir,
|
||||
))
|
||||
self.nodes[i].args = args
|
||||
self.start_node(i)
|
||||
@ -596,7 +598,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||
#
|
||||
# blocks are created with timestamps 10 minutes apart
|
||||
# starting from 2010 minutes in the past
|
||||
block_time = GENESISTIME
|
||||
block_time = TIME_GENESIS_BLOCK
|
||||
for i in range(2):
|
||||
for peer in range(4):
|
||||
for j in range(25):
|
||||
|
@ -60,7 +60,7 @@ class TestNode():
|
||||
To make things easier for the test writer, any unrecognised messages will
|
||||
be dispatched to the RPC connection."""
|
||||
|
||||
def __init__(self, i, datadir, extra_args_from_options, *, chain, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False, start_perf=False):
|
||||
def __init__(self, i, datadir, extra_args_from_options, *, chain, rpchost, timewait, bitcoind, bitcoin_cli, mocktime, coverage_dir, cwd, extra_conf=None, extra_args=None, use_cli=False, start_perf=False):
|
||||
"""
|
||||
Kwargs:
|
||||
start_perf (bool): If True, begin profiling the node with `perf` as soon as
|
||||
@ -78,6 +78,7 @@ class TestNode():
|
||||
self.rpc_timeout *= Options.timeout_scale
|
||||
self.binary = bitcoind
|
||||
self.coverage_dir = coverage_dir
|
||||
self.cwd = cwd
|
||||
self.mocktime = mocktime
|
||||
if extra_conf is not None:
|
||||
append_config(datadir, extra_conf)
|
||||
@ -185,7 +186,7 @@ class TestNode():
|
||||
assert self.rpc_connected and self.rpc is not None, self._node_msg("Error: no RPC connection")
|
||||
return getattr(self.rpc, name)
|
||||
|
||||
def start(self, extra_args=None, *, stdout=None, stderr=None, **kwargs):
|
||||
def start(self, extra_args=None, *, cwd=None, stdout=None, stderr=None, **kwargs):
|
||||
"""Start the node."""
|
||||
if extra_args is None:
|
||||
extra_args = self.extra_args
|
||||
@ -198,6 +199,9 @@ class TestNode():
|
||||
self.stderr = stderr
|
||||
self.stdout = stdout
|
||||
|
||||
if cwd is None:
|
||||
cwd = self.cwd
|
||||
|
||||
all_args = self.args + self.extra_args_from_options + extra_args
|
||||
if self.mocktime != 0:
|
||||
all_args = all_args + ["-mocktime=%d" % self.mocktime]
|
||||
@ -210,7 +214,7 @@ class TestNode():
|
||||
# add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal
|
||||
subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1")
|
||||
|
||||
self.process = subprocess.Popen(all_args, env=subp_env, stdout=stdout, stderr=stderr, **kwargs)
|
||||
self.process = subprocess.Popen(all_args, env=subp_env, stdout=stdout, stderr=stderr, cwd=cwd, **kwargs)
|
||||
|
||||
self.running = True
|
||||
self.log.debug("dashd started, waiting for RPC to come up")
|
||||
|
@ -31,8 +31,8 @@ class CreateWalletTest(BitcoinTestFramework):
|
||||
self.log.info("Test disableprivatekeys creation.")
|
||||
self.nodes[0].createwallet(wallet_name='w1', disable_private_keys=True)
|
||||
w1 = node.get_wallet_rpc('w1')
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w1.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w1.getrawchangeaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w1.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w1.getrawchangeaddress)
|
||||
w1.importpubkey(w0.getaddressinfo(address1)['pubkey'])
|
||||
|
||||
self.log.info('Test that private keys cannot be imported')
|
||||
@ -48,8 +48,8 @@ class CreateWalletTest(BitcoinTestFramework):
|
||||
self.log.info("Test blank creation with private keys disabled.")
|
||||
self.nodes[0].createwallet(wallet_name='w2', disable_private_keys=True, blank=True)
|
||||
w2 = node.get_wallet_rpc('w2')
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w2.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w2.getrawchangeaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w2.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w2.getrawchangeaddress)
|
||||
w2.importpubkey(w0.getaddressinfo(address1)['pubkey'])
|
||||
|
||||
self.log.info("Test blank creation with private keys enabled.")
|
||||
@ -89,12 +89,12 @@ class CreateWalletTest(BitcoinTestFramework):
|
||||
self.nodes[0].createwallet(wallet_name='w5', disable_private_keys=True, blank=True)
|
||||
w5 = node.get_wallet_rpc('w5')
|
||||
assert_equal(w5.getwalletinfo()['keypoolsize'], 0)
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w5.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w5.getrawchangeaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w5.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w5.getrawchangeaddress)
|
||||
# Encrypt the wallet
|
||||
assert_raises_rpc_error(-16, "Error: wallet does not contain private keys, nothing to encrypt.", w5.encryptwallet, 'pass')
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w5.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", w5.getrawchangeaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w5.getnewaddress)
|
||||
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w5.getrawchangeaddress)
|
||||
|
||||
self.log.info('New blank and encrypted wallets can be created')
|
||||
self.nodes[0].createwallet(wallet_name='wblank', disable_private_keys=False, blank=True, passphrase='thisisapassphrase')
|
||||
|
@ -78,7 +78,6 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old):
|
||||
|
||||
class WalletDumpTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-keypool=90", "-usehd=1"]]
|
||||
self.rpc_timeout = 120
|
||||
@ -87,12 +86,6 @@ class WalletDumpTest(BitcoinTestFramework):
|
||||
self.skip_if_no_wallet()
|
||||
|
||||
def setup_network(self):
|
||||
# TODO remove this when usehd=1 becomes the default
|
||||
# use our own cache and -usehd=1 as extra arg as the default cache is run with -usehd=0
|
||||
self.options.tmpdir = os.path.join(self.options.tmpdir, 'hd')
|
||||
self.options.cachedir = os.path.join(self.options.cachedir, 'hd')
|
||||
self._initialize_chain(extra_args=self.extra_args[0])
|
||||
self.set_cache_mocktime()
|
||||
self.add_nodes(self.num_nodes, extra_args=self.extra_args)
|
||||
self.start_nodes()
|
||||
|
||||
|
@ -633,5 +633,118 @@ class ImportMultiTest(BitcoinTestFramework):
|
||||
assert 'hdmasterfingerprint' not in pub_import_info
|
||||
assert 'hdkeypath' not in pub_import_info
|
||||
|
||||
# Import some public keys to the keypool of a no privkey wallet
|
||||
self.log.info("Adding pubkey to keypool of disableprivkey wallet")
|
||||
self.nodes[1].createwallet(wallet_name="noprivkeys", disable_private_keys=True)
|
||||
wrpc = self.nodes[1].get_wallet_rpc("noprivkeys")
|
||||
|
||||
addr1 = self.nodes[0].getnewaddress()
|
||||
addr2 = self.nodes[0].getnewaddress()
|
||||
pub1 = self.nodes[0].getaddressinfo(addr1)['pubkey']
|
||||
pub2 = self.nodes[0].getaddressinfo(addr2)['pubkey']
|
||||
result = wrpc.importmulti(
|
||||
[{
|
||||
'desc': descsum_create('pkh(' + pub1 + ')'),
|
||||
'keypool': True,
|
||||
"timestamp": "now",
|
||||
},
|
||||
{
|
||||
'desc': descsum_create('pkh(' + pub2 + ')'),
|
||||
'keypool': True,
|
||||
"timestamp": "now",
|
||||
}]
|
||||
)
|
||||
assert result[0]['success']
|
||||
assert result[1]['success']
|
||||
assert_equal(wrpc.getwalletinfo()["keypoolsize"], 2)
|
||||
newaddr1 = wrpc.getnewaddress()
|
||||
assert_equal(addr1, newaddr1)
|
||||
newaddr2 = wrpc.getnewaddress()
|
||||
assert_equal(addr2, newaddr2)
|
||||
|
||||
# Import some public keys to the internal keypool of a no privkey wallet
|
||||
self.log.info("Adding pubkey to internal keypool of disableprivkey wallet")
|
||||
addr1 = self.nodes[0].getnewaddress()
|
||||
addr2 = self.nodes[0].getnewaddress()
|
||||
pub1 = self.nodes[0].getaddressinfo(addr1)['pubkey']
|
||||
pub2 = self.nodes[0].getaddressinfo(addr2)['pubkey']
|
||||
result = wrpc.importmulti(
|
||||
[{
|
||||
'desc': descsum_create('pkh(' + pub1 + ')'),
|
||||
'keypool': True,
|
||||
'internal': True,
|
||||
"timestamp": "now",
|
||||
},
|
||||
{
|
||||
'desc': descsum_create('pkh(' + pub2 + ')'),
|
||||
'keypool': True,
|
||||
'internal': True,
|
||||
"timestamp": "now",
|
||||
}]
|
||||
)
|
||||
assert result[0]['success']
|
||||
assert result[1]['success']
|
||||
assert_equal(wrpc.getwalletinfo()["keypoolsize_hd_internal"], 2)
|
||||
newaddr1 = wrpc.getrawchangeaddress()
|
||||
assert_equal(addr1, newaddr1)
|
||||
newaddr2 = wrpc.getrawchangeaddress()
|
||||
assert_equal(addr2, newaddr2)
|
||||
|
||||
# Import a multisig and make sure the keys don't go into the keypool
|
||||
self.log.info('Imported scripts with pubkeys shoud not have their pubkeys go into the keypool')
|
||||
addr1 = self.nodes[0].getnewaddress()
|
||||
addr2 = self.nodes[0].getnewaddress()
|
||||
pub1 = self.nodes[0].getaddressinfo(addr1)['pubkey']
|
||||
pub2 = self.nodes[0].getaddressinfo(addr2)['pubkey']
|
||||
result = wrpc.importmulti(
|
||||
[{
|
||||
'desc': descsum_create('sh(multi(2,' + pub1 + ',' + pub2 + '))'),
|
||||
'keypool': True,
|
||||
"timestamp": "now",
|
||||
}]
|
||||
)
|
||||
assert result[0]['success']
|
||||
assert_equal(wrpc.getwalletinfo()["keypoolsize"], 0)
|
||||
|
||||
# Cannot import those pubkeys to keypool of wallet with privkeys
|
||||
self.log.info("Pubkeys cannot be added to the keypool of a wallet with private keys")
|
||||
wrpc = self.nodes[1].get_wallet_rpc("")
|
||||
assert wrpc.getwalletinfo()['private_keys_enabled']
|
||||
result = wrpc.importmulti(
|
||||
[{
|
||||
'desc': descsum_create('pkh(' + pub1 + ')'),
|
||||
'keypool': True,
|
||||
"timestamp": "now",
|
||||
}]
|
||||
)
|
||||
assert_equal(result[0]['error']['code'], -8)
|
||||
assert_equal(result[0]['error']['message'], "Keys can only be imported to the keypool when private keys are disabled")
|
||||
|
||||
# Make sure ranged imports import keys in order
|
||||
self.log.info('Key ranges should be imported in order')
|
||||
wrpc = self.nodes[1].get_wallet_rpc("noprivkeys")
|
||||
assert_equal(wrpc.getwalletinfo()["keypoolsize"], 0)
|
||||
assert_equal(wrpc.getwalletinfo()["private_keys_enabled"], False)
|
||||
xpub = "tpubDAXcJ7s7ZwicqjprRaEWdPoHKrCS215qxGYxpusRLLmJuT69ZSicuGdSfyvyKpvUNYBW1s2U3NSrT6vrCYB9e6nZUEvrqnwXPF8ArTCRXMY"
|
||||
addresses = [
|
||||
'yUxX4qnzWntXhEGrYB92v7ez4EZBnUjB1y', # m/0'/0'/0
|
||||
'yRhTPsPd2qYgYbFFCqY2nuPHJQBjTnMQxg', # m/0'/0'/1
|
||||
'yUyn3UV9rBdWfw6yJJ6eAoKuzDJ8RVLP1o', # m/0'/0'/2
|
||||
'yi8GEkfLBgK85wGmBFsMFdSbEvPPNCSnVx', # m/0'/0'/3
|
||||
'yYB4whdY8APWoCez6ryNdMBrrDjwzFbqMi', # m/0'/0'/4
|
||||
]
|
||||
result = wrpc.importmulti(
|
||||
[{
|
||||
'desc': descsum_create('pkh([80002067/0h/0h]' + xpub + '/*)'),
|
||||
'keypool': True,
|
||||
'timestamp': 'now',
|
||||
'range' : [0, 4],
|
||||
}]
|
||||
)
|
||||
for i in range(0, 5):
|
||||
addr = wrpc.getnewaddress('')
|
||||
assert_equal(addr, addresses[i])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ImportMultiTest().main()
|
||||
|
Loading…
Reference in New Issue
Block a user