mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Merge pull request #4220 from PastaPastaPasta/backport-triv-pr4
backport: 'trivial' pr4
This commit is contained in:
commit
e6d008d385
@ -101,6 +101,8 @@ At this stage one should expect comments and review from other contributors. You
|
||||
can add more commits to your pull request by committing them locally and pushing
|
||||
to your fork until you have satisfied all feedback.
|
||||
|
||||
Note: Code review is a burdensome but important part of the development process, and as such, certain types of pull requests are rejected. In general, if the **improvements** do not warrant the **review effort** required, the PR has a high chance of being rejected. It is up to the PR author to convince the reviewers that the changes warrant the review effort, and if reviewers are "Concept NAK'ing" the PR, the author may need to present arguments and/or do research backing their suggested changes.
|
||||
|
||||
Squashing Commits
|
||||
---------------------------
|
||||
If your pull request is accepted for merging, you may be asked by a maintainer
|
||||
|
@ -213,6 +213,7 @@ script: |
|
||||
rm -rf ${DISTNAME}/lib/pkgconfig
|
||||
find ${DISTNAME}/bin -type f -executable -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \;
|
||||
find ${DISTNAME}/lib -type f -exec ../contrib/devtools/split-debug.sh {} {} {}.dbg \;
|
||||
cp ../doc/README.md ${DISTNAME}/
|
||||
find ${DISTNAME} -not -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
|
||||
find ${DISTNAME} -name "*.dbg" | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}-debug.tar.gz
|
||||
cd ../../
|
||||
|
@ -5,7 +5,7 @@ suites:
|
||||
architectures:
|
||||
- "amd64"
|
||||
packages:
|
||||
- "libssl-dev"
|
||||
- "libssl-dev" # do not merge bitcoin#13782, see https://github.com/dashpay/dash/pull/3894
|
||||
- "autoconf"
|
||||
- "automake"
|
||||
- "libtool"
|
||||
|
@ -112,7 +112,7 @@ struct CDiskBlockPos
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos);
|
||||
return strprintf("CDiskBlockPos(nFile=%i, nPos=%i)", nFile, nPos);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -14,10 +14,10 @@
|
||||
|
||||
// GCC 4.8 is missing some C++11 type_traits,
|
||||
// https://www.gnu.org/software/gcc/gcc-5/changes.html
|
||||
#if defined(__GNUC__) && __GNUC__ < 5
|
||||
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivial
|
||||
#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
|
||||
#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor
|
||||
#else
|
||||
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_constructible
|
||||
#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -51,8 +51,8 @@ static void SetupCliArgs()
|
||||
gArgs.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", false, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-rpcwait", "Wait for RPC server to start", false, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-rpcwallet=<walletname>", "Send RPC for non-default wallet on RPC server (needs to exactly match corresponding -wallet option passed to bitcoind)", false, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-stdin", "Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). When combined with -stdinrpcpass, the first line from standard input is used for the RPC password.", false, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-stdinrpcpass", strprintf("Read RPC password from standard input as a single line. When combined with -stdin, the first line from standard input is used for the RPC password."), false, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-stdin", "Read extra arguments from standard input, one per line until EOF/Ctrl-D (recommended for sensitive information such as passphrases). When combined with -stdinrpcpass, the first line from standard input is used for the RPC password.", false, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-stdinrpcpass", "Read RPC password from standard input as a single line. When combined with -stdin, the first line from standard input is used for the RPC password.", false, OptionsCategory::OPTIONS);
|
||||
|
||||
SetupChainParamsBaseOptions();
|
||||
|
||||
|
@ -535,7 +535,7 @@ HTTPRequest::~HTTPRequest()
|
||||
// evhttpd cleans up the request, as long as a reply was sent.
|
||||
}
|
||||
|
||||
std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr)
|
||||
std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string& hdr) const
|
||||
{
|
||||
const struct evkeyvalq* headers = evhttp_request_get_input_headers(req);
|
||||
assert(headers);
|
||||
@ -608,7 +608,7 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
|
||||
req = nullptr; // transferred back to main thread
|
||||
}
|
||||
|
||||
CService HTTPRequest::GetPeer()
|
||||
CService HTTPRequest::GetPeer() const
|
||||
{
|
||||
evhttp_connection* con = evhttp_request_get_connection(req);
|
||||
CService peer;
|
||||
@ -622,12 +622,12 @@ CService HTTPRequest::GetPeer()
|
||||
return peer;
|
||||
}
|
||||
|
||||
std::string HTTPRequest::GetURI()
|
||||
std::string HTTPRequest::GetURI() const
|
||||
{
|
||||
return evhttp_request_get_uri(req);
|
||||
}
|
||||
|
||||
HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod()
|
||||
HTTPRequest::RequestMethod HTTPRequest::GetRequestMethod() const
|
||||
{
|
||||
switch (evhttp_request_get_command(req)) {
|
||||
case EVHTTP_REQ_GET:
|
||||
|
@ -74,21 +74,21 @@ public:
|
||||
|
||||
/** Get requested URI.
|
||||
*/
|
||||
std::string GetURI();
|
||||
std::string GetURI() const;
|
||||
|
||||
/** Get CService (address:ip) for the origin of the http request.
|
||||
*/
|
||||
CService GetPeer();
|
||||
CService GetPeer() const;
|
||||
|
||||
/** Get request method.
|
||||
*/
|
||||
RequestMethod GetRequestMethod();
|
||||
RequestMethod GetRequestMethod() const;
|
||||
|
||||
/**
|
||||
* Get the request header specified by hdr, or an empty string.
|
||||
* Return a pair (isPresent,string).
|
||||
*/
|
||||
std::pair<bool, std::string> GetHeader(const std::string& hdr);
|
||||
std::pair<bool, std::string> GetHeader(const std::string& hdr) const;
|
||||
|
||||
/**
|
||||
* Read request body.
|
||||
|
@ -104,7 +104,7 @@ WalletTxStatus MakeWalletTxStatus(const CWalletTx& wtx)
|
||||
WalletTxStatus result;
|
||||
auto mi = ::mapBlockIndex.find(wtx.hashBlock);
|
||||
CBlockIndex* block = mi != ::mapBlockIndex.end() ? mi->second : nullptr;
|
||||
result.block_height = (block ? block->nHeight : std::numeric_limits<int>::max()),
|
||||
result.block_height = (block ? block->nHeight : std::numeric_limits<int>::max());
|
||||
result.blocks_to_maturity = wtx.GetBlocksToMaturity();
|
||||
result.depth_in_main_chain = wtx.GetDepthInMainChain();
|
||||
result.time_received = wtx.nTimeReceived;
|
||||
|
@ -265,32 +265,32 @@ public:
|
||||
|
||||
prevector() : _size(0), _union{{}} {}
|
||||
|
||||
explicit prevector(size_type n) : _size(0) {
|
||||
explicit prevector(size_type n) : prevector() {
|
||||
resize(n);
|
||||
}
|
||||
|
||||
explicit prevector(size_type n, const T& val = T()) : _size(0) {
|
||||
explicit prevector(size_type n, const T& val) : prevector() {
|
||||
change_capacity(n);
|
||||
_size += n;
|
||||
fill(item_ptr(0), n, val);
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
prevector(InputIterator first, InputIterator last) : _size(0) {
|
||||
prevector(InputIterator first, InputIterator last) : prevector() {
|
||||
size_type n = last - first;
|
||||
change_capacity(n);
|
||||
_size += n;
|
||||
fill(item_ptr(0), first, last);
|
||||
}
|
||||
|
||||
prevector(const prevector<N, T, Size, Diff>& other) : _size(0) {
|
||||
prevector(const prevector<N, T, Size, Diff>& other) : prevector() {
|
||||
size_type n = other.size();
|
||||
change_capacity(n);
|
||||
_size += n;
|
||||
fill(item_ptr(0), other.begin(), other.end());
|
||||
}
|
||||
|
||||
prevector(prevector<N, T, Size, Diff>&& other) : _size(0) {
|
||||
prevector(prevector<N, T, Size, Diff>&& other) : prevector() {
|
||||
swap(other);
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,7 @@ class CBlockIndex;
|
||||
class UniValue;
|
||||
|
||||
/**
|
||||
* Get the difficulty of the net wrt to the given block index, or the chain tip if
|
||||
* not provided.
|
||||
* Get the difficulty of the net wrt to the given block index.
|
||||
*
|
||||
* @return A floating point number that is a multiple of the main net minimum
|
||||
* difficulty (4295032833 hashes).
|
||||
|
@ -138,11 +138,13 @@ BOOST_AUTO_TEST_CASE(singlethreadedscheduler_ordered)
|
||||
// the callbacks should run in exactly the order in which they were enqueued
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
queue1.AddToProcessQueue([i, &counter1]() {
|
||||
BOOST_CHECK_EQUAL(i, counter1++);
|
||||
bool expectation = i == counter1++;
|
||||
assert(expectation);
|
||||
});
|
||||
|
||||
queue2.AddToProcessQueue([i, &counter2]() {
|
||||
BOOST_CHECK_EQUAL(i, counter2++);
|
||||
bool expectation = i == counter2++;
|
||||
assert(expectation);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,8 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
|
||||
BOOST_ERROR("Read incorrect tx");
|
||||
}
|
||||
}
|
||||
|
||||
txindex.Stop(); // Stop thread before calling destructor
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
@ -12,7 +12,7 @@
|
||||
// TL;DR Add GUARDED_BY(mutex) to member variables. The others are
|
||||
// rarely necessary. Ex: int nFoo GUARDED_BY(cs_foo);
|
||||
//
|
||||
// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety
|
||||
// See https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
|
||||
// for documentation. The clang compiler can do advanced static analysis
|
||||
// of locking when given the -Wthread-safety option.
|
||||
#define LOCKABLE __attribute__((lockable))
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <boost/signals2/signal.hpp>
|
||||
|
||||
class CBlockIndex;
|
||||
extern CCriticalSection cs_main;
|
||||
|
||||
/** Fake height value used in Coin to signify they are only in the memory pool (since 0.8) */
|
||||
static const uint32_t MEMPOOL_HEIGHT = 0x7FFFFFFF;
|
||||
@ -580,7 +581,7 @@ public:
|
||||
bool removeSpentIndex(const uint256 txhash);
|
||||
|
||||
void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason = MemPoolRemovalReason::UNKNOWN);
|
||||
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
|
||||
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
||||
void removeProTxPubKeyConflicts(const CTransaction &tx, const CKeyID &keyId);
|
||||
void removeProTxPubKeyConflicts(const CTransaction &tx, const CBLSPublicKey &pubKey);
|
||||
|
@ -324,7 +324,11 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
|
||||
// Confirm ListCoins initially returns 1 coin grouped under coinbaseKey
|
||||
// address.
|
||||
auto list = wallet->ListCoins();
|
||||
std::map<CTxDestination, std::vector<COutput>> list;
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
list = wallet->ListCoins();
|
||||
}
|
||||
BOOST_CHECK_EQUAL(list.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
|
||||
BOOST_CHECK_EQUAL(list.begin()->second.size(), 1U);
|
||||
@ -337,7 +341,10 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
// coinbaseKey pubkey, even though the change address has a different
|
||||
// pubkey.
|
||||
AddTx(CRecipient{GetScriptForRawPubKey({}), 1 * COIN, false /* subtract fee */});
|
||||
list = wallet->ListCoins();
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
list = wallet->ListCoins();
|
||||
}
|
||||
BOOST_CHECK_EQUAL(list.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
|
||||
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
|
||||
@ -363,7 +370,10 @@ BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup)
|
||||
}
|
||||
// Confirm ListCoins still returns same result as before, despite coins
|
||||
// being locked.
|
||||
list = wallet->ListCoins();
|
||||
{
|
||||
LOCK2(cs_main, wallet->cs_wallet);
|
||||
list = wallet->ListCoins();
|
||||
}
|
||||
BOOST_CHECK_EQUAL(list.size(), 1U);
|
||||
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), coinbaseAddress);
|
||||
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U);
|
||||
|
@ -118,14 +118,25 @@ std::string COutput::ToString() const
|
||||
return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->tx->vout[i].nValue));
|
||||
}
|
||||
|
||||
/** A class to identify which pubkeys a script and a keystore have in common. */
|
||||
class CAffectedKeysVisitor : public boost::static_visitor<void> {
|
||||
private:
|
||||
const CKeyStore &keystore;
|
||||
std::vector<CKeyID> &vKeys;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @param[in] keystoreIn The CKeyStore that is queried for the presence of a pubkey.
|
||||
* @param[out] vKeysIn A vector to which a script's pubkey identifiers are appended if they are in the keystore.
|
||||
*/
|
||||
CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
|
||||
|
||||
/**
|
||||
* Apply the visitor to each destination in a script, recursively to the redeemscript
|
||||
* in the case of p2sh destinations.
|
||||
* @param[in] script The CScript from which destinations are extracted.
|
||||
* @post Any CKeyIDs that script and keystore have in common are appended to the visitor's vKeys.
|
||||
*/
|
||||
void Process(const CScript &script) {
|
||||
txnouttype type;
|
||||
std::vector<CTxDestination> vDest;
|
||||
@ -2989,20 +3000,12 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
|
||||
|
||||
std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const
|
||||
{
|
||||
// TODO: Add AssertLockHeld(cs_wallet) here.
|
||||
//
|
||||
// Because the return value from this function contains pointers to
|
||||
// CWalletTx objects, callers to this function really should acquire the
|
||||
// cs_wallet lock before calling it. However, the current caller doesn't
|
||||
// acquire this lock yet. There was an attempt to add the missing lock in
|
||||
// https://github.com/bitcoin/bitcoin/pull/10340, but that change has been
|
||||
// postponed until after https://github.com/bitcoin/bitcoin/pull/10244 to
|
||||
// avoid adding some extra complexity to the Qt code.
|
||||
AssertLockHeld(cs_main);
|
||||
AssertLockHeld(cs_wallet);
|
||||
|
||||
std::map<CTxDestination, std::vector<COutput>> result;
|
||||
std::vector<COutput> availableCoins;
|
||||
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
AvailableCoins(availableCoins);
|
||||
|
||||
for (auto& coin : availableCoins) {
|
||||
|
@ -83,6 +83,8 @@ class CWalletTx;
|
||||
struct FeeCalculation;
|
||||
enum class FeeEstimateMode;
|
||||
|
||||
extern CCriticalSection cs_main;
|
||||
|
||||
/** (client) version numbers for particular wallet features */
|
||||
enum WalletFeature
|
||||
{
|
||||
@ -877,7 +879,7 @@ public:
|
||||
/**
|
||||
* Return list of available coins and locked coins grouped by non-change output address.
|
||||
*/
|
||||
std::map<CTxDestination, std::vector<COutput>> ListCoins() const;
|
||||
std::map<CTxDestination, std::vector<COutput>> ListCoins() const EXCLUSIVE_LOCKS_REQUIRED(cs_main, cs_wallet);
|
||||
|
||||
/**
|
||||
* Find non-change parent output.
|
||||
|
@ -14,7 +14,7 @@ import re
|
||||
import sys
|
||||
|
||||
# Matches on the date format at the start of the log event
|
||||
TIMESTAMP_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z")
|
||||
TIMESTAMP_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{6})?Z")
|
||||
|
||||
LogEvent = namedtuple('LogEvent', ['timestamp', 'source', 'event'])
|
||||
|
||||
@ -84,11 +84,17 @@ def get_log_events(source, logfile):
|
||||
if time_match:
|
||||
if event:
|
||||
yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip())
|
||||
event = line
|
||||
timestamp = time_match.group()
|
||||
if time_match.group(1) is None:
|
||||
# timestamp does not have microseconds. Add zeroes.
|
||||
timestamp_micro = timestamp.replace("Z", ".000000Z")
|
||||
line = line.replace(timestamp, timestamp_micro)
|
||||
timestamp = timestamp_micro
|
||||
event = line
|
||||
# if it doesn't have a timestamp, it's a continuation line of the previous log.
|
||||
else:
|
||||
event += "\n" + line
|
||||
# Add the line. Prefix with space equivalent to the source + timestamp so log lines are aligned
|
||||
event += " " + line
|
||||
# Flush the final event
|
||||
yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip())
|
||||
except FileNotFoundError:
|
||||
@ -107,7 +113,11 @@ def print_logs(log_events, color=False, html=False):
|
||||
colors["reset"] = "\033[0m" # Reset font color
|
||||
|
||||
for event in log_events:
|
||||
print("{0} {1: <5} {2} {3}".format(colors[event.source.rstrip()], event.source, event.event, colors["reset"]))
|
||||
lines = event.event.splitlines()
|
||||
print("{0} {1: <5} {2} {3}".format(colors[event.source.rstrip()], event.source, lines[0], colors["reset"]))
|
||||
if len(lines) > 1:
|
||||
for line in lines[1:]:
|
||||
print("{0}{1}{2}".format(colors[event.source.rstrip()], line, colors["reset"]))
|
||||
|
||||
else:
|
||||
try:
|
||||
|
@ -22,7 +22,7 @@ class ReindexTest(BitcoinTestFramework):
|
||||
self.nodes[0].generate(3)
|
||||
blockcount = self.nodes[0].getblockcount()
|
||||
self.stop_nodes()
|
||||
extra_args = [["-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]]
|
||||
extra_args = [["-reindex-chainstate" if justchainstate else "-reindex"]]
|
||||
self.start_nodes(extra_args)
|
||||
wait_until(lambda: self.nodes[0].getblockcount() == blockcount)
|
||||
self.log.info("Success")
|
||||
|
@ -36,7 +36,6 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [[
|
||||
'-checkmempool',
|
||||
'-txindex',
|
||||
'-reindex', # Need reindex for txindex
|
||||
'-acceptnonstdtxn=0', # Try to mimic main-net
|
||||
|
@ -11,11 +11,10 @@ that spend (directly or indirectly) coinbase transactions.
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
|
||||
# Create one-input, one-output, no-fee transaction:
|
||||
|
||||
class MempoolCoinbaseTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [["-checkmempool"]] * 2
|
||||
|
||||
alert_filename = None # Set by setup_network
|
||||
|
||||
|
@ -7,11 +7,10 @@
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
|
||||
# Create one-input, one-output, no-fee transaction:
|
||||
|
||||
class MempoolCoinbaseTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-checkmempool"]]
|
||||
|
||||
def run_test(self):
|
||||
node0_address = self.nodes[0].getnewaddress()
|
||||
|
@ -15,11 +15,10 @@ but less mature coinbase spends are NOT.
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
|
||||
# Create one-input, one-output, no-fee transaction:
|
||||
|
||||
class MempoolSpendCoinbaseTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-checkmempool"]]
|
||||
|
||||
def run_test(self):
|
||||
chain_height = self.nodes[0].getblockcount()
|
||||
|
31
test/functional/rpc_help.py
Executable file
31
test/functional/rpc_help.py
Executable file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 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 RPC help output."""
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal, assert_raises_rpc_error
|
||||
|
||||
class HelpRpcTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
|
||||
def run_test(self):
|
||||
node = self.nodes[0]
|
||||
|
||||
# wrong argument count, note: Dash's help allows for two options since we utilize subcommands
|
||||
assert_raises_rpc_error(-1, 'help', node.help, 'foo', 'bar', 'foobar')
|
||||
|
||||
# invalid argument
|
||||
assert_raises_rpc_error(-1, 'JSON value is not a string as expected', node.help, 0)
|
||||
|
||||
# help of unknown command
|
||||
assert_equal(node.help('foo'), 'help: unknown command: foo')
|
||||
|
||||
# command titles
|
||||
titles = [line[3:-3] for line in node.help().splitlines() if line.startswith('==')]
|
||||
assert_equal(titles, ['Addressindex', 'Blockchain', 'Control', 'Dash', 'Evo', 'Generating', 'Mining', 'Network', 'Rawtransactions', 'Util', 'Wallet', 'Zmq'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
HelpRpcTest().main()
|
@ -107,7 +107,7 @@ def all_interfaces():
|
||||
max_possible *= 2
|
||||
else:
|
||||
break
|
||||
namestr = names.tostring()
|
||||
namestr = names.tobytes()
|
||||
return [(namestr[i:i+16].split(b'\0', 1)[0],
|
||||
socket.inet_ntoa(namestr[i+20:i+24]))
|
||||
for i in range(0, outbytes, struct_size)]
|
||||
|
@ -190,6 +190,7 @@ BASE_SCRIPTS = [
|
||||
'p2p_node_network_limited.py',
|
||||
'feature_blocksdir.py',
|
||||
'feature_config_args.py',
|
||||
'rpc_help.py',
|
||||
'feature_help.py',
|
||||
# Don't append tests at the end to avoid merge conflicts
|
||||
# Put them in a random line within the section that fits their approximate run-time
|
||||
|
23
test/lint/lint-assertions.sh
Executable file
23
test/lint/lint-assertions.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 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.
|
||||
#
|
||||
# Check for assertions with obvious side effects.
|
||||
|
||||
export LC_ALL=C
|
||||
|
||||
EXIT_CODE=0
|
||||
|
||||
# PRE31-C (SEI CERT C Coding Standard):
|
||||
# "Assertions should not contain assignments, increment, or decrement operators."
|
||||
OUTPUT=$(git grep -E '[^_]assert\(.*(\+\+|\-\-|[^=!<>]=[^=!<>]).*\);' -- "*.cpp" "*.h")
|
||||
if [[ ${OUTPUT} != "" ]]; then
|
||||
echo "Assertions should not have side effects:"
|
||||
echo
|
||||
echo "${OUTPUT}"
|
||||
EXIT_CODE=1
|
||||
fi
|
||||
|
||||
exit ${EXIT_CODE}
|
@ -131,6 +131,32 @@ def parse_function_call_and_arguments(function_name, function_call):
|
||||
['foo(', '123', ')']
|
||||
>>> parse_function_call_and_arguments("foo", 'foo("foo")')
|
||||
['foo(', '"foo"', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf), err);')
|
||||
['strprintf(', '"%s (%d)",', ' std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t>().to_bytes(buf),', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo<wchar_t>().to_bytes(buf), err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo<wchar_t>().to_bytes(buf),', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo().to_bytes(buf), err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo().to_bytes(buf),', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo << 1, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo << 1,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo<bar>() >> 1, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo<bar>() >> 1,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo < 1 ? bar : foobar, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo < 1 ? bar : foobar,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo < 1, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo < 1,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo > 1 ? bar : foobar, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo > 1 ? bar : foobar,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo > 1, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo > 1,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo <= 1, err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo <= 1,', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo <= bar<1, 2>(1, 2), err);')
|
||||
['strprintf(', '"%s (%d)",', ' foo <= bar<1, 2>(1, 2),', ' err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo>foo<1,2>(1,2)?bar:foobar,err)');
|
||||
['strprintf(', '"%s (%d)",', ' foo>foo<1,2>(1,2)?bar:foobar,', 'err', ')']
|
||||
>>> parse_function_call_and_arguments("strprintf", 'strprintf("%s (%d)", foo>foo<1,2>(1,2),err)');
|
||||
['strprintf(', '"%s (%d)",', ' foo>foo<1,2>(1,2),', 'err', ')']
|
||||
"""
|
||||
assert(type(function_name) is str and type(function_call) is str and function_name)
|
||||
remaining = normalize(escape(function_call))
|
||||
@ -139,9 +165,10 @@ def parse_function_call_and_arguments(function_name, function_call):
|
||||
parts = [expected_function_call]
|
||||
remaining = remaining[len(expected_function_call):]
|
||||
open_parentheses = 1
|
||||
open_template_arguments = 0
|
||||
in_string = False
|
||||
parts.append("")
|
||||
for char in remaining:
|
||||
for i, char in enumerate(remaining):
|
||||
parts.append(parts.pop() + char)
|
||||
if char == "\"":
|
||||
in_string = not in_string
|
||||
@ -159,6 +186,15 @@ def parse_function_call_and_arguments(function_name, function_call):
|
||||
parts.append(parts.pop()[:-1])
|
||||
parts.append(char)
|
||||
break
|
||||
prev_char = remaining[i - 1] if i - 1 >= 0 else None
|
||||
next_char = remaining[i + 1] if i + 1 <= len(remaining) - 1 else None
|
||||
if char == "<" and next_char not in [" ", "<", "="] and prev_char not in [" ", "<"]:
|
||||
open_template_arguments += 1
|
||||
continue
|
||||
if char == ">" and next_char not in [" ", ">", "="] and prev_char not in [" ", ">"] and open_template_arguments > 0:
|
||||
open_template_arguments -= 1
|
||||
if open_template_arguments > 0:
|
||||
continue
|
||||
if char == ",":
|
||||
parts.append("")
|
||||
return parts
|
||||
|
@ -28,7 +28,7 @@ import sys
|
||||
def main():
|
||||
config = configparser.ConfigParser()
|
||||
config.optionxform = str
|
||||
config.readfp(open(os.path.join(os.path.dirname(__file__), "../config.ini"), encoding="utf8"))
|
||||
config.read_file(open(os.path.join(os.path.dirname(__file__), "../config.ini"), encoding="utf8"))
|
||||
env_conf = dict(config.items('environment'))
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
|
Loading…
Reference in New Issue
Block a user