Merge pull request #3029 from PastaPastaPasta/backports-0.15-pr21

Backports 0.15 pr21
This commit is contained in:
UdjinM6 2019-07-23 12:19:41 +03:00 committed by GitHub
commit 8231255dd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 362 additions and 325 deletions

View File

@ -19,6 +19,12 @@ BITCOIN_GUI_NAME=dash-qt
BITCOIN_CLI_NAME=dash-cli
BITCOIN_TX_NAME=dash-tx
dnl Unless the user specified ARFLAGS, force it to be cr
AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to <cr> if not set])
if test "x${ARFLAGS+set}" != "xset"; then
ARFLAGS="cr"
fi
AC_CANONICAL_HOST
AH_TOP([#ifndef DASH_CONFIG_H])
@ -290,9 +296,32 @@ if test "x$CXXFLAGS_overridden" = "xno"; then
# Check for optional instruction set support. Enabling these does _not_ imply that all code will
# be compiled with them, rather that specific objects/libs may use them after checking for runtime
# compatibility.
AX_CHECK_COMPILE_FLAG([-msse4.2],[[enable_sse42=yes; SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-msse4.2],[[SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]])
fi
TEMP_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS"
AC_MSG_CHECKING(for assembler crc32 support)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdint.h>
#if defined(_MSC_VER)
#include <intrin.h>
#elif defined(__GNUC__) && defined(__SSE4_2__)
#include <nmmintrin.h>
#endif
]],[[
uint64_t l = 0;
l = _mm_crc32_u8(l, 0);
l = _mm_crc32_u32(l, 0);
l = _mm_crc32_u64(l, 0);
return l;
]])],
[ AC_MSG_RESULT(yes); enable_hwcrc32=yes],
[ AC_MSG_RESULT(no)]
)
CXXFLAGS="$TEMP_CXXFLAGS"
CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
AC_ARG_WITH([utils],
@ -1188,7 +1217,7 @@ AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes])
AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes])
AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes])
AM_CONDITIONAL([ENABLE_SSE42],[test x$enable_sse42 = xyes])
AM_CONDITIONAL([ENABLE_HWCRC32],[test x$enable_hwcrc32 = xyes])
AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
@ -1321,4 +1350,5 @@ echo " CPPFLAGS = $CPPFLAGS"
echo " CXX = $CXX"
echo " CXXFLAGS = $CXXFLAGS"
echo " LDFLAGS = $LDFLAGS"
echo " ARFLAGS = $ARFLAGS"
echo

View File

@ -175,6 +175,7 @@ def main():
if info is None:
exit(1)
title = info['title'].strip()
body = info['body'].strip()
# precedence order for destination branch argument:
# - command line argument
# - githubmerge.branch setting
@ -229,6 +230,7 @@ def main():
firstline = 'Merge #%s' % (pull,)
message = firstline + '\n\n'
message += subprocess.check_output([GIT,'log','--no-merges','--topo-order','--pretty=format:%h %s (%an)',base_branch+'..'+head_branch]).decode('utf-8')
message += '\n\nPull request description:\n\n ' + body.replace('\n', '\n ') + '\n'
try:
subprocess.check_call([GIT,'merge','-q','--commit','--no-edit','--no-ff','-m',message.encode('utf-8'),head_branch])
except subprocess.CalledProcessError as e:

View File

@ -3,7 +3,8 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
### This script attempts to download the signature file SHA256SUMS.asc from bitcoin.org
### This script attempts to download the signature file SHA256SUMS.asc from
### bitcoincore.org and bitcoin.org and compares them.
### It first checks if the signature passes, and then downloads the files specified in
### the file, and checks if the hashes of these files match those that are specified
### in the signature file.
@ -22,7 +23,9 @@ TMPFILE="hashes.tmp"
SIGNATUREFILENAME="SHA256SUMS.asc"
RCSUBDIR="test"
BASEDIR="https://bitcoin.org/bin/"
HOST1="https://bitcoincore.org"
HOST2="https://bitcoin.org"
BASEDIR="/bin/"
VERSIONPREFIX="bitcoin-core-"
RCVERSIONSTRING="rc"
@ -81,7 +84,7 @@ else
fi
#first we fetch the file containing the signature
WGETOUT=$(wget -N "$BASEDIR$SIGNATUREFILENAME" 2>&1)
WGETOUT=$(wget -N "$HOST1$BASEDIR$SIGNATUREFILENAME" 2>&1)
#and then see if wget completed successfully
if [ $? -ne 0 ]; then
@ -92,6 +95,22 @@ if [ $? -ne 0 ]; then
exit 2
fi
WGETOUT=$(wget -N -O "$SIGNATUREFILENAME.2" "$HOST2$BASEDIR$SIGNATUREFILENAME" 2>&1)
if [ $? -ne 0 ]; then
echo "bitcoin.org failed to provide signature file, but bitcoincore.org did?"
echo "wget output:"
echo "$WGETOUT"|sed 's/^/\t/g'
clean_up $SIGNATUREFILENAME
exit 3
fi
SIGFILEDIFFS="$(diff $SIGNATUREFILENAME $SIGNATUREFILENAME.2)"
if [ "$SIGFILEDIFFS" != "" ]; then
echo "bitcoin.org and bitcoincore.org signature files were not equal?"
clean_up $SIGNATUREFILENAME $SIGNATUREFILENAME.2
exit 4
fi
#then we check it
GPGOUT=$(gpg --yes --decrypt --output "$TMPFILE" "$SIGNATUREFILENAME" 2>&1)
@ -111,7 +130,7 @@ if [ $RET -ne 0 ]; then
echo "gpg output:"
echo "$GPGOUT"|sed 's/^/\t/g'
clean_up $SIGNATUREFILENAME $TMPFILE
clean_up $SIGNATUREFILENAME $SIGNATUREFILENAME.2 $TMPFILE
exit "$RET"
fi
@ -131,7 +150,7 @@ FILES=$(awk '{print $2}' "$TMPFILE")
for file in $FILES
do
echo "Downloading $file"
wget --quiet -N "$BASEDIR$file"
wget --quiet -N "$HOST1$BASEDIR$file"
done
#check hashes
@ -149,7 +168,7 @@ fi
if [ -n "$2" ]; then
echo "Clean up the binaries"
clean_up $FILES $SIGNATUREFILENAME $TMPFILE
clean_up $FILES $SIGNATUREFILENAME $SIGNATUREFILENAME.2 $TMPFILE
else
echo "Keep the binaries in $WORKINGDIR"
clean_up $TMPFILE

View File

@ -40,11 +40,13 @@ Only supports JSON as output format.
* headers : (numeric) the current number of headers we have validated
* bestblockhash : (string) the hash of the currently best block
* difficulty : (numeric) the current difficulty
* mediantime : (numeric) the median time of the 11 blocks before the most recent block on the blockchain
* verificationprogress : (numeric) estimate of verification progress [0..1]
* chainwork : (string) total amount of work in active chain, in hexadecimal
* pruned : (boolean) if the blocks are subject to pruning
* pruneheight : (numeric) heighest block available
* softforks : (array) status of softforks in progress
* bip9_softforks : (object) status of BIP9 softforks in progress
#### Query UTXO set
`GET /rest/getutxos/<checkmempool>/<txid>-<n>/<txid>-<n>/.../<txid>-<n>.<bin|hex|json>`
@ -57,25 +59,25 @@ Example:
```
$ curl localhost:18332/rest/getutxos/checkmempool/b2cdfd7b89def827ff8af7cd9bff7627ff72e5e8b0f71210f92ea7a4000c5d75-0.json 2>/dev/null | json_pp
{
"chaintipHash" : "00000000fb01a7f3745a717f8caebee056c484e6e0bfe4a9591c235bb70506fb",
"chainHeight" : 325347,
"chaintipHash" : "00000000fb01a7f3745a717f8caebee056c484e6e0bfe4a9591c235bb70506fb",
"bitmap": "1",
"utxos" : [
{
"txvers" : 1
"height" : 2147483647,
"value" : 8.8687,
"scriptPubKey" : {
"addresses" : [
"mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
],
"type" : "pubkeyhash",
"asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a9141c7cebb529b86a04c683dfa87be49de35bcf589e88ac",
"reqSigs" : 1,
"asm" : "OP_DUP OP_HASH160 1c7cebb529b86a04c683dfa87be49de35bcf589e OP_EQUALVERIFY OP_CHECKSIG"
},
"value" : 8.8687,
"height" : 2147483647,
"txvers" : 1
"type" : "pubkeyhash",
"addresses" : [
"mi7as51dvLJsizWnTMurtRmrP8hG2m1XvD"
]
}
}
],
"bitmap" : "1"
]
}
```
@ -87,6 +89,8 @@ Only supports JSON as output format.
* size : (numeric) the number of transactions in the TX mempool
* bytes : (numeric) size of the TX mempool in bytes
* usage : (numeric) total TX mempool memory usage
* maxmempool : (numeric) maximum memory usage for the mempool in bytes
* mempoolminfee : (numeric) minimum feerate (DASH per KB) for tx to be accepted
`GET /rest/mempool/contents.json`

View File

@ -142,7 +142,7 @@ leveldb_libmemenv_a_SOURCES += leveldb/helpers/memenv/memenv.h
leveldb_libleveldb_sse42_a_CPPFLAGS = $(leveldb_libleveldb_a_CPPFLAGS)
leveldb_libleveldb_sse42_a_CXXFLAGS = $(leveldb_libleveldb_a_CXXFLAGS)
if ENABLE_SSE42
if ENABLE_HWCRC32
leveldb_libleveldb_sse42_a_CPPFLAGS += -DLEVELDB_PLATFORM_POSIX_SSE
leveldb_libleveldb_sse42_a_CXXFLAGS += $(SSE42_CXXFLAGS)
endif

View File

@ -110,7 +110,7 @@ std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
return EncodeBase58(&vch[0], &vch[0] + vch.size());
return EncodeBase58(vch.data(), vch.data() + vch.size());
}
bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
@ -160,7 +160,7 @@ void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const
vchVersion = vchVersionIn;
vchData.resize(nSize);
if (!vchData.empty())
memcpy(&vchData[0], pdata, nSize);
memcpy(vchData.data(), pdata, nSize);
}
void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
@ -180,8 +180,8 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
memory_cleanse(&vchTemp[0], vchTemp.size());
memcpy(vchData.data(), vchTemp.data() + nVersionBytes, vchData.size());
memory_cleanse(vchTemp.data(), vchTemp.size());
return true;
}
@ -262,7 +262,7 @@ CTxDestination CBitcoinAddress::Get() const
if (!IsValid())
return CNoDestination();
uint160 id;
memcpy(&id, &vchData[0], 20);
memcpy(&id, vchData.data(), 20);
if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return CKeyID(id);
else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
@ -293,7 +293,7 @@ bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
if (!IsValid() || vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))
return false;
uint160 id;
memcpy(&id, &vchData[0], 20);
memcpy(&id, vchData.data(), 20);
keyID = CKeyID(id);
return true;
}

View File

@ -149,7 +149,7 @@ public:
K ret;
if (vchData.size() == Size) {
// If base58 encoded data does not hold an ext key, return a !IsValid() key
ret.Decode(&vchData[0]);
ret.Decode(vchData.data());
}
return ret;
}

View File

@ -7,34 +7,37 @@
#include "validation.h"
#include "base58.h"
#include <array>
#include <vector>
#include <string>
static void Base58Encode(benchmark::State& state)
{
unsigned char buff[32] = {
17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147,
227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90,
200, 24
static const std::array<unsigned char, 32> buff = {
{
17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147,
227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90,
200, 24
}
};
unsigned char* b = buff;
while (state.KeepRunning()) {
EncodeBase58(b, b + 32);
EncodeBase58(buff.begin(), buff.end());
}
}
static void Base58CheckEncode(benchmark::State& state)
{
unsigned char buff[32] = {
17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147,
227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90,
200, 24
static const std::array<unsigned char, 32> buff = {
{
17, 79, 8, 99, 150, 189, 208, 162, 22, 23, 203, 163, 36, 58, 147,
227, 139, 2, 215, 100, 91, 38, 11, 141, 253, 40, 117, 21, 16, 90,
200, 24
}
};
unsigned char* b = buff;
std::vector<unsigned char> vch;
vch.assign(b, b + 32);
vch.assign(buff.begin(), buff.end());
while (state.KeepRunning()) {
EncodeBase58Check(vch);
}

View File

@ -93,7 +93,7 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigne
script[0] = OP_DUP;
script[1] = OP_HASH160;
script[2] = 20;
memcpy(&script[3], &in[0], 20);
memcpy(&script[3], in.data(), 20);
script[23] = OP_EQUALVERIFY;
script[24] = OP_CHECKSIG;
return true;
@ -101,7 +101,7 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigne
script.resize(23);
script[0] = OP_HASH160;
script[1] = 20;
memcpy(&script[2], &in[0], 20);
memcpy(&script[2], in.data(), 20);
script[22] = OP_EQUAL;
return true;
case 0x02:
@ -109,14 +109,14 @@ bool CScriptCompressor::Decompress(unsigned int nSize, const std::vector<unsigne
script.resize(35);
script[0] = 33;
script[1] = nSize;
memcpy(&script[2], &in[0], 32);
memcpy(&script[2], in.data(), 32);
script[34] = OP_CHECKSIG;
return true;
case 0x04:
case 0x05:
unsigned char vch[33] = {};
vch[0] = nSize - 2;
memcpy(&vch[1], &in[0], 32);
memcpy(&vch[1], in.data(), 32);
CPubKey pubkey(&vch[0], &vch[33]);
if (!pubkey.Decompress())
return false;

View File

@ -27,7 +27,7 @@ CScript ParseScript(const std::string& s)
if (mapOpNames.empty())
{
for (int op = 0; op <= OP_NOP10; op++)
for (unsigned int op = 0; op <= OP_NOP10; op++)
{
// Allow OP_RESERVED to get into mapOpNames
if (op < OP_NOP && op != OP_RESERVED)

View File

@ -204,8 +204,14 @@ static void http_error_cb(enum evhttp_request_error err, void *ctx)
UniValue CallRPC(const std::string& strMethod, const UniValue& params)
{
std::string host = gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT);
int port = gArgs.GetArg("-rpcport", BaseParams().RPCPort());
std::string host;
// In preference order, we choose the following for the port:
// 1. -rpcport
// 2. port in -rpcconnect (ie following : in ipv4 or ]: in ipv6)
// 3. default port for chain
int port = BaseParams().RPCPort();
SplitHostPort(gArgs.GetArg("-rpcconnect", DEFAULT_RPCCONNECT), port, host);
port = gArgs.GetArg("-rpcport", port);
// Obtain event base
raii_event_base base = obtain_event_base();

View File

@ -17,36 +17,34 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
{
// The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
uint32_t h1 = nHashSeed;
if (vDataToHash.size() > 0)
{
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
const int nblocks = vDataToHash.size() / 4;
const int nblocks = vDataToHash.size() / 4;
//----------
// body
const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
//----------
// body
const uint8_t* blocks = vDataToHash.data();
for (int i = -nblocks; i; i++) {
uint32_t k1 = ReadLE32(blocks + i*4);
for (int i = 0; i < nblocks; ++i) {
uint32_t k1 = ReadLE32(blocks + i*4);
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
h1 ^= k1;
h1 = ROTL32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
//----------
// tail
const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4);
//----------
// tail
const uint8_t* tail = vDataToHash.data() + nblocks * 4;
uint32_t k1 = 0;
uint32_t k1 = 0;
switch (vDataToHash.size() & 3) {
switch (vDataToHash.size() & 3) {
case 3:
k1 ^= tail[2] << 16;
case 2:
@ -57,7 +55,6 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
}
}
//----------

View File

@ -7,6 +7,7 @@
#include "chainparamsbase.h"
#include "compat.h"
#include "util.h"
#include "utilstrencodings.h"
#include "netbase.h"
#include "rpc/protocol.h" // For HTTP status codes
#include "sync.h"

View File

@ -1850,7 +1850,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Shutdown requested. Exiting.\n");
return false;
}
LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart);
if (fLoaded) {
LogPrintf(" block index %15dms\n", GetTimeMillis() - nStart);
}
fs::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME;
CAutoFile est_filein(fsbridge::fopen(est_path, "rb"), SER_DISK, CLIENT_VERSION);

View File

@ -138,7 +138,7 @@ CPrivKey CKey::GetPrivKey() const {
size_t privkeylen;
privkey.resize(279);
privkeylen = 279;
ret = ec_privkey_export_der(secp256k1_context_sign, (unsigned char*)&privkey[0], &privkeylen, begin(), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
ret = ec_privkey_export_der(secp256k1_context_sign, (unsigned char*) privkey.data(), &privkeylen, begin(), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
assert(ret);
privkey.resize(privkeylen);
return privkey;
@ -167,7 +167,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_
secp256k1_ecdsa_signature sig;
int ret = secp256k1_ecdsa_sign(secp256k1_context_sign, &sig, hash.begin(), begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL);
assert(ret);
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, (unsigned char*)&vchSig[0], &nSigLen, &sig);
secp256k1_ecdsa_signature_serialize_der(secp256k1_context_sign, (unsigned char*)vchSig.data(), &nSigLen, &sig);
vchSig.resize(nSigLen);
return true;
}
@ -202,7 +202,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
}
bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char*)begin(), &privkey[0], privkey.size()))
if (!ec_privkey_import_der(secp256k1_context_sign, (unsigned char*)begin(), privkey.data(), privkey.size()))
return false;
fCompressed = vchPubKey.IsCompressed();
fValid = true;
@ -245,8 +245,8 @@ void CExtKey::SetMaster(const unsigned char *seed, unsigned int nSeedLen) {
static const unsigned char hashkey[] = {'B','i','t','c','o','i','n',' ','s','e','e','d'};
std::vector<unsigned char, secure_allocator<unsigned char>> vout(64);
CHMAC_SHA512(hashkey, sizeof(hashkey)).Write(seed, nSeedLen).Finalize(vout.data());
key.Set(&vout[0], &vout[32], true);
memcpy(chaincode.begin(), &vout[32], 32);
key.Set(vout.data(), vout.data() + 32, true);
memcpy(chaincode.begin(), vout.data() + 32, 32);
nDepth = 0;
nChild = 0;
memset(vchFingerprint, 0, sizeof(vchFingerprint));

View File

@ -3365,5 +3365,5 @@ uint64_t CConnman::CalculateKeyedNetGroup(const CAddress& ad) const
{
std::vector<unsigned char> vchNetGroup(ad.GetGroup());
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(&vchNetGroup[0], vchNetGroup.size()).Finalize();
return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
}

View File

@ -583,7 +583,7 @@ std::vector<unsigned char> CService::GetKey() const
{
std::vector<unsigned char> vKey;
vKey.resize(18);
memcpy(&vKey[0], ip, 16);
memcpy(vKey.data(), ip, 16);
vKey[16] = port / 0x100;
vKey[17] = port & 0x0FF;
return vKey;

View File

@ -58,25 +58,6 @@ std::string GetNetworkName(enum Network net) {
}
}
void SplitHostPort(std::string in, int &portOut, std::string &hostOut) {
size_t colon = in.find_last_of(':');
// if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
bool fHaveColon = colon != in.npos;
bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
bool fMultiColon = fHaveColon && (in.find_last_of(':',colon-1) != in.npos);
if (fHaveColon && (colon==0 || fBracketed || !fMultiColon)) {
int32_t n;
if (ParseInt32(in.substr(colon + 1), &n) && n > 0 && n < 0x10000) {
in = in.substr(0, colon);
portOut = n;
}
}
if (in.size()>0 && in[0] == '[' && in[in.size()-1] == ']')
hostOut = in.substr(1, in.size()-2);
else
hostOut = in;
}
bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
@ -563,7 +544,7 @@ static bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDe
// do socks negotiation
if (proxy.randomize_credentials) {
ProxyCredentials random_auth;
static std::atomic_int counter;
static std::atomic_int counter(0);
random_auth.username = random_auth.password = strprintf("%i", counter++);
if (!Socks5(strDest, (unsigned short)port, &random_auth, hSocket))
return false;

View File

@ -40,7 +40,6 @@ public:
enum Network ParseNetwork(std::string net);
std::string GetNetworkName(enum Network net);
void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
bool SetProxy(enum Network net, const proxyType &addrProxy);
bool GetProxy(enum Network net, proxyType &proxyInfoOut);
bool IsProxy(const CNetAddr &addr);

View File

@ -220,7 +220,7 @@ public:
}
}
prevector() : _size(0) {}
prevector() : _size(0), _union{{}} {}
explicit prevector(size_type n) : _size(0) {
resize(n);

View File

@ -172,10 +172,7 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
return false;
}
if (vchSig.size() == 0) {
return false;
}
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) {
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
return false;
}
/* libsecp256k1's ECDSA verification requires lower-S signatures, which have
@ -274,7 +271,7 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
secp256k1_ecdsa_signature sig;
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) {
if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
return false;
}
return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, NULL, &sig));

View File

@ -389,6 +389,10 @@ void TransactionView::changedAmount(const QString &amount)
void TransactionView::exportClicked()
{
if (!model || !model->getOptionsModel()) {
return;
}
// CSV is currently the only supported format
QString filename = GUIUtil::getSaveFileName(this,
tr("Export Transaction History"), QString(),

View File

@ -36,6 +36,10 @@
#include <mutex>
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
#include <cpuid.h>
#endif
#include <openssl/err.h>
#include <openssl/rand.h>
@ -72,18 +76,9 @@ static bool rdrand_supported = false;
static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
static void RDRandInit()
{
uint32_t eax, ecx, edx;
#if defined(__i386__) && ( defined(__PIC__) || defined(__PIE__))
// Avoid clobbering ebx, as that is used for PIC on x86.
uint32_t tmp;
__asm__ ("mov %%ebx, %1; cpuid; mov %1, %%ebx": "=a"(eax), "=g"(tmp), "=c"(ecx), "=d"(edx) : "a"(1));
#else
uint32_t ebx;
__asm__ ("cpuid": "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1));
#endif
//! When calling cpuid function #1, ecx register will have this set if RDRAND is available.
if (ecx & CPUID_F1_ECX_RDRAND) {
LogPrintf("Using RdRand as entropy source\n");
uint32_t eax, ebx, ecx, edx;
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx & CPUID_F1_ECX_RDRAND)) {
LogPrintf("Using RdRand as an additional entropy source\n");
rdrand_supported = true;
}
hwrand_initialized.store(true);

View File

@ -1229,7 +1229,7 @@ UniValue gettxout(const JSONRPCRequest& request)
if (fMempool) {
LOCK(mempool.cs);
CCoinsViewMemPool view(pcoinsTip, mempool);
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) { // TODO: filtering spent coins should be done by the CCoinsViewMemPool
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
return NullUniValue;
}
} else {

View File

@ -101,6 +101,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listunspent", 3, "include_unsafe" },
{ "listunspent", 4, "query_options" },
{ "getblock", 1, "verbosity" },
{ "getblock", 1, "verbose" },
{ "getblockheader", 1, "verbose" },
{ "getblockheaders", 1, "count" },
{ "getblockheaders", 2, "verbose" },

View File

@ -335,6 +335,14 @@ UniValue validateaddress(const JSONRPCRequest& request)
" \"ismine\" : true|false, (boolean) If the address is yours or not\n"
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly\n"
" \"isscript\" : true|false, (boolean) If the key is a script\n"
" \"script\" : \"type\" (string, optional) The output script type. Possible types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata\n"
" \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address\n"
" \"addresses\" (string, optional) Array of addresses associated with the known redeemscript\n"
" [\n"
" \"address\"\n"
" ,...\n"
" ]\n"
" \"sigsrequired\" : xxxxx (numeric, optional) Number of signatures required to spend multisig output\n"
" \"pubkey\" : \"publickeyhex\", (string) The hex value of the raw public key\n"
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
" \"account\" : \"account\" (string) DEPRECATED. The account associated with the address, \"\" is the default account\n"

View File

@ -630,7 +630,7 @@ public:
}
string.resize(size);
if (size != 0)
s.read((char*)&string[0], size);
s.read((char*)string.data(), size);
}
template<typename Stream>
@ -638,7 +638,7 @@ public:
{
WriteCompactSize(s, string.size());
if (!string.empty())
s.write((char*)&string[0], string.size());
s.write((char*)string.data(), string.size());
}
};
@ -778,7 +778,7 @@ void Serialize(Stream& os, const std::basic_string<C>& str)
{
WriteCompactSize(os, str.size());
if (!str.empty())
os.write((char*)&str[0], str.size() * sizeof(str[0]));
os.write((char*)str.data(), str.size() * sizeof(C));
}
template<typename Stream, typename C>
@ -787,7 +787,7 @@ void Unserialize(Stream& is, std::basic_string<C>& str)
unsigned int nSize = ReadCompactSize(is);
str.resize(nSize);
if (nSize != 0)
is.read((char*)&str[0], nSize * sizeof(str[0]));
is.read((char*)str.data(), nSize * sizeof(C));
}
@ -800,7 +800,7 @@ void Serialize_impl(Stream& os, const prevector<N, T>& v, const unsigned char&)
{
WriteCompactSize(os, v.size());
if (!v.empty())
os.write((char*)&v[0], v.size() * sizeof(T));
os.write((char*)v.data(), v.size() * sizeof(T));
}
template<typename Stream, unsigned int N, typename T, typename V>
@ -868,7 +868,7 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, const unsigned char&
{
WriteCompactSize(os, v.size());
if (!v.empty())
os.write((char*)&v[0], v.size() * sizeof(T));
os.write((char*)v.data(), v.size() * sizeof(T));
}
template<typename Stream, typename T, typename A, typename V>

View File

@ -346,7 +346,7 @@ public:
{
// Special case: stream << stream concatenates like stream += stream
if (!vch.empty())
s.write((char*)&vch[0], vch.size() * sizeof(vch[0]));
s.write((char*)vch.data(), vch.size() * sizeof(value_type));
}
template<typename T>

View File

@ -148,9 +148,9 @@ class Win32LockedPageAllocator: public LockedPageAllocator
{
public:
Win32LockedPageAllocator();
void* AllocateLocked(size_t len, bool *lockingSuccess);
void FreeLocked(void* addr, size_t len);
size_t GetLimit();
void* AllocateLocked(size_t len, bool *lockingSuccess) override;
void FreeLocked(void* addr, size_t len) override;
size_t GetLimit() override;
private:
size_t page_size;
};
@ -200,9 +200,9 @@ class PosixLockedPageAllocator: public LockedPageAllocator
{
public:
PosixLockedPageAllocator();
void* AllocateLocked(size_t len, bool *lockingSuccess);
void FreeLocked(void* addr, size_t len);
size_t GetLimit();
void* AllocateLocked(size_t len, bool *lockingSuccess) override;
void FreeLocked(void* addr, size_t len) override;
size_t GetLimit() override;
private:
size_t page_size;
};

View File

@ -131,7 +131,7 @@ class TestLockedPageAllocator: public LockedPageAllocator
{
public:
TestLockedPageAllocator(int count_in, int lockedcount_in): count(count_in), lockedcount(lockedcount_in) {}
void* AllocateLocked(size_t len, bool *lockingSuccess)
void* AllocateLocked(size_t len, bool *lockingSuccess) override
{
*lockingSuccess = false;
if (count > 0) {
@ -146,10 +146,10 @@ public:
}
return 0;
}
void FreeLocked(void* addr, size_t len)
void FreeLocked(void* addr, size_t len) override
{
}
size_t GetLimit()
size_t GetLimit() override
{
return std::numeric_limits<size_t>::max();
}

View File

@ -5,6 +5,7 @@
#include "netbase.h"
#include "test/test_dash.h"
#include "utilstrencodings.h"
#include <string>

View File

@ -663,7 +663,7 @@ void TorController::protocolinfo_cb(TorControlConnection& _conn, const TorContro
// _conn.Command("AUTHENTICATE " + HexStr(status_cookie.second), boost::bind(&TorController::auth_cb, this, _1, _2));
cookie = std::vector<uint8_t>(status_cookie.second.begin(), status_cookie.second.end());
clientNonce = std::vector<uint8_t>(TOR_NONCE_SIZE, 0);
GetRandBytes(&clientNonce[0], TOR_NONCE_SIZE);
GetRandBytes(clientNonce.data(), TOR_NONCE_SIZE);
_conn.Command("AUTHCHALLENGE SAFECOOKIE " + HexStr(clientNonce), boost::bind(&TorController::authchallenge_cb, this, _1, _2));
} else {
if (status_cookie.first) {

View File

@ -657,13 +657,6 @@ public:
return (mapTx.count(hash) != 0);
}
bool exists(const COutPoint& outpoint) const
{
LOCK(cs);
auto it = mapTx.find(outpoint.hash);
return (it != mapTx.end() && outpoint.n < it->GetTx().vout.size());
}
CTransactionRef get(const uint256& hash) const;
TxMempoolInfo info(const uint256& hash) const;
std::vector<TxMempoolInfo> infoAll() const;
@ -717,6 +710,13 @@ private:
/**
* CCoinsView that brings transactions from a memorypool into view.
* It does not check for spendings by memory pool transactions.
* Instead, it provides access to all Coins which are either unspent in the
* base CCoinsView, or are outputs from any mempool transaction!
* This allows transaction replacement to work as expected, as you want to
* have all inputs "available" to check signatures, and any cycles in the
* dependency graph are checked directly in AcceptToMemoryPool.
* It also allows you to sign a double-spend directly in signrawtransaction,
* as long as the conflicting transaction is not yet confirmed.
*/
class CCoinsViewMemPool : public CCoinsViewBacked
{

View File

@ -91,6 +91,25 @@ std::vector<unsigned char> ParseHex(const std::string& str)
return ParseHex(str.c_str());
}
void SplitHostPort(std::string in, int &portOut, std::string &hostOut) {
size_t colon = in.find_last_of(':');
// if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
bool fHaveColon = colon != in.npos;
bool fBracketed = fHaveColon && (in[0]=='[' && in[colon-1]==']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
bool fMultiColon = fHaveColon && (in.find_last_of(':',colon-1) != in.npos);
if (fHaveColon && (colon==0 || fBracketed || !fMultiColon)) {
int32_t n;
if (ParseInt32(in.substr(colon + 1), &n) && n > 0 && n < 0x10000) {
in = in.substr(0, colon);
portOut = n;
}
}
if (in.size()>0 && in[0] == '[' && in[in.size()-1] == ']')
hostOut = in.substr(1, in.size()-2);
else
hostOut = in;
}
std::string EncodeBase64(const unsigned char* pch, size_t len)
{
static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@ -228,7 +247,7 @@ std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
std::string DecodeBase64(const std::string& str)
{
std::vector<unsigned char> vchRet = DecodeBase64(str.c_str());
return (vchRet.size() == 0) ? std::string() : std::string((const char*)&vchRet[0], vchRet.size());
return std::string((const char*)vchRet.data(), vchRet.size());
}
std::string EncodeBase32(const unsigned char* pch, size_t len)
@ -415,7 +434,7 @@ std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
std::string DecodeBase32(const std::string& str)
{
std::vector<unsigned char> vchRet = DecodeBase32(str.c_str());
return (vchRet.size() == 0) ? std::string() : std::string((const char*)&vchRet[0], vchRet.size());
return std::string((const char*)vchRet.data(), vchRet.size());
}
static bool ParsePrechecks(const std::string& str)

View File

@ -48,6 +48,7 @@ std::string DecodeBase32(const std::string& str);
std::string EncodeBase32(const unsigned char* pch, size_t len);
std::string EncodeBase32(const std::string& str);
void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
std::string i64tostr(int64_t n);
std::string itostr(int n);
int64_t atoi64(const char* psz);

View File

@ -734,24 +734,20 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
CCoinsViewMemPool viewMemPool(pcoinsTip, pool);
view.SetBackend(viewMemPool);
// do we already have it?
for (size_t out = 0; out < tx.vout.size(); out++) {
COutPoint outpoint(hash, out);
bool had_coin_in_cache = pcoinsTip->HaveCoinInCache(outpoint);
if (view.HaveCoin(outpoint)) {
if (!had_coin_in_cache) {
coins_to_uncache.push_back(outpoint);
}
return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known");
}
}
// do all inputs exist?
for (const CTxIn txin : tx.vin) {
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
coins_to_uncache.push_back(txin.prevout);
}
if (!view.HaveCoin(txin.prevout)) {
// Are inputs missing because we already have the tx?
for (size_t out = 0; out < tx.vout.size(); out++) {
// Optimistically just do efficient check of cache for outputs
if (pcoinsTip->HaveCoinInCache(COutPoint(hash, out))) {
return state.Invalid(false, REJECT_DUPLICATE, "txn-already-known");
}
}
// Otherwise assume this might be an orphan tx for which we just haven't seen parents yet
if (pfMissingInputs) {
*pfMissingInputs = true;
}
@ -1314,7 +1310,7 @@ static void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
// hash rate operating on the fork.
// We define it this way because it allows us to only store the highest fork tip (+ base) which meets
// the 7-block condition and from this always have the most-likely-to-cause-warning fork
if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) &&
if (pfork && (!pindexBestForkTip || pindexNewForkTip->nHeight > pindexBestForkTip->nHeight) &&
pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
chainActive.Height() - pindexNewForkTip->nHeight < 72)
{

View File

@ -95,13 +95,13 @@ class CWalletDBWrapper
friend class CDB;
public:
/** Create dummy DB handle */
CWalletDBWrapper() : nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr)
CWalletDBWrapper() : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr)
{
}
/** Create DB handle to real database */
CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in) :
nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(env_in), strFile(strFile_in)
nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(env_in), strFile(strFile_in)
{
}

View File

@ -363,7 +363,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request)
"\nExamples:\n"
+ HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("removprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
+ HelpExampleRpc("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
);
LOCK2(cs_main, pwallet->cs_wallet);

View File

@ -767,9 +767,9 @@ UniValue getbalance(const JSONRPCRequest& request)
"\nResult:\n"
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
"\nExamples:\n"
"\nThe total amount in the wallet\n"
"\nThe total amount in the wallet with 1 or more confirmations\n"
+ HelpExampleCli("getbalance", "") +
"\nThe total amount in the wallet at least 5 blocks confirmed\n"
"\nThe total amount in the wallet at least 6 blocks confirmed\n"
+ HelpExampleCli("getbalance", "\"*\" 6") +
"\nAs a json rpc call\n"
+ HelpExampleRpc("getbalance", "\"*\", 6")

View File

@ -5131,20 +5131,24 @@ bool CWallet::ParameterInteraction()
LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__);
}
if (gArgs.GetBoolArg("-salvagewallet", false) && gArgs.SoftSetBoolArg("-rescan", true)) {
if (gArgs.GetBoolArg("-salvagewallet", false)) {
if (is_multiwallet) {
return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet"));
}
// Rewrite just private keys: rescan to find transactions
LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
if (gArgs.SoftSetBoolArg("-rescan", true)) {
LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__);
}
}
// -zapwallettx implies a rescan
if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.SoftSetBoolArg("-rescan", true)) {
if (gArgs.GetBoolArg("-zapwallettxes", false)) {
if (is_multiwallet) {
return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes"));
}
LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
if (gArgs.SoftSetBoolArg("-rescan", true)) {
LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -rescan=1\n", __func__);
}
}
if (is_multiwallet) {

View File

@ -782,7 +782,7 @@ DBErrors CWalletDB::ZapWalletTx(std::vector<CWalletTx>& vWtx)
void MaybeCompactWalletDB()
{
static std::atomic<bool> fOneThread;
static std::atomic<bool> fOneThread(false);
if (fOneThread.exchange(true)) {
return;
}

View File

@ -1,157 +0,0 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 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 block proposals with getblocktemplate."""
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from binascii import a2b_hex, b2a_hex
from hashlib import sha256
from struct import pack
def b2x(b):
return b2a_hex(b).decode('ascii')
# NOTE: This does not work for signed numbers (set the high bit) or zero (use b'\0')
def encodeUNum(n):
s = bytearray(b'\1')
while n > 127:
s[0] += 1
s.append(n % 256)
n //= 256
s.append(n)
return bytes(s)
def varlenEncode(n):
if n < 0xfd:
return pack('<B', n)
if n <= 0xffff:
return b'\xfd' + pack('<H', n)
if n <= 0xffffffff:
return b'\xfe' + pack('<L', n)
return b'\xff' + pack('<Q', n)
def dblsha(b):
return sha256(sha256(b).digest()).digest()
def genmrklroot(leaflist):
cur = leaflist
while len(cur) > 1:
n = []
if len(cur) & 1:
cur.append(cur[-1])
for i in range(0, len(cur), 2):
n.append(dblsha(cur[i] + cur[i+1]))
cur = n
return cur[0]
def template_to_bytearray(tmpl, txlist):
blkver = pack('<L', tmpl['version'])
mrklroot = genmrklroot(list(dblsha(a) for a in txlist))
timestamp = pack('<L', tmpl['curtime'])
nonce = b'\0\0\0\0'
blk = blkver + a2b_hex(tmpl['previousblockhash'])[::-1] + mrklroot + timestamp + a2b_hex(tmpl['bits'])[::-1] + nonce
blk += varlenEncode(len(txlist))
for tx in txlist:
blk += tx
return bytearray(blk)
def template_to_hex(tmpl, txlist):
return b2x(template_to_bytearray(tmpl, txlist))
def assert_template(node, tmpl, txlist, expect):
rsp = node.getblocktemplate({'data':template_to_hex(tmpl, txlist),'mode':'proposal'})
if rsp != expect:
raise AssertionError('unexpected: %s' % (rsp,))
class GetBlockTemplateProposalTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = False
def run_test(self):
node = self.nodes[0]
node.generate(1) # Mine a block to leave initial block download
tmpl = node.getblocktemplate()
if 'coinbasetxn' not in tmpl:
rawcoinbase = encodeUNum(tmpl['height'])
rawcoinbase += b'\x01-'
hexcoinbase = b2x(rawcoinbase)
hexoutval = b2x(pack('<Q', tmpl['coinbasevalue']))
tmpl['coinbasetxn'] = {'data': '01000000' + '01' + '0000000000000000000000000000000000000000000000000000000000000000ffffffff' + ('%02x' % (len(rawcoinbase),)) + hexcoinbase + 'fffffffe' + '01' + hexoutval + '00' + '00000000'}
txlist = list(bytearray(a2b_hex(a['data'])) for a in (tmpl['coinbasetxn'],) + tuple(tmpl['transactions']))
# Test 0: Capability advertised
assert('proposal' in tmpl['capabilities'])
# NOTE: This test currently FAILS (regtest mode doesn't enforce block height in coinbase)
## Test 1: Bad height in coinbase
#txlist[0][4+1+36+1+1] += 1
#assert_template(node, tmpl, txlist, 'FIXME')
#txlist[0][4+1+36+1+1] -= 1
# Test 2: Bad input hash for gen tx
txlist[0][4+1] += 1
assert_template(node, tmpl, txlist, 'bad-cb-missing')
txlist[0][4+1] -= 1
# Test 3: Truncated final tx
lastbyte = txlist[-1].pop()
assert_raises_jsonrpc(-22, "Block decode failed", assert_template, node, tmpl, txlist, 'n/a')
txlist[-1].append(lastbyte)
# Test 4: Add an invalid tx to the end (duplicate of gen tx)
txlist.append(txlist[0])
assert_template(node, tmpl, txlist, 'bad-txns-duplicate')
txlist.pop()
# Test 5: Add an invalid tx to the end (non-duplicate)
txlist.append(bytearray(txlist[0]))
txlist[-1][4+1] = 0xff
assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent')
txlist.pop()
# Test 6: Future tx lock time
txlist[0][-4:] = b'\xff\xff\xff\xff'
assert_template(node, tmpl, txlist, 'bad-txns-nonfinal')
txlist[0][-4:] = b'\0\0\0\0'
# Test 7: Bad tx count
txlist.append(b'')
assert_raises_jsonrpc(-22, 'Block decode failed', assert_template, node, tmpl, txlist, 'n/a')
txlist.pop()
# Test 8: Bad bits
realbits = tmpl['bits']
tmpl['bits'] = '1c0000ff' # impossible in the real world
assert_template(node, tmpl, txlist, 'bad-diffbits')
tmpl['bits'] = realbits
# Test 9: Bad merkle root
rawtmpl = template_to_bytearray(tmpl, txlist)
rawtmpl[4+32] = (rawtmpl[4+32] + 1) % 0x100
rsp = node.getblocktemplate({'data':b2x(rawtmpl),'mode':'proposal'})
if rsp != 'bad-txnmrklroot':
raise AssertionError('unexpected: %s' % (rsp,))
# Test 10: Bad timestamps
realtime = tmpl['curtime']
tmpl['curtime'] = 0x7fffffff
assert_template(node, tmpl, txlist, 'time-too-new')
tmpl['curtime'] = 0
assert_template(node, tmpl, txlist, 'time-too-old')
tmpl['curtime'] = realtime
# Test 11: Valid block
assert_template(node, tmpl, txlist, None)
# Test 12: Orphan block
tmpl['previousblockhash'] = 'ff00' * 16
assert_template(node, tmpl, txlist, 'inconclusive-not-best-prevblk')
if __name__ == '__main__':
GetBlockTemplateProposalTest().main()

124
test/functional/mining.py Executable file
View File

@ -0,0 +1,124 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 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
- getblocktemplate proposal mode
- submitblock"""
from binascii import b2a_hex
import copy
from test_framework.blocktools import create_coinbase
from test_framework.test_framework import BitcoinTestFramework
from test_framework.mininode import CBlock
from test_framework.util import *
def b2x(b):
return b2a_hex(b).decode('ascii')
def assert_template(node, block, expect, rehash=True):
if rehash:
block.hashMerkleRoot = block.calc_merkle_root()
rsp = node.getblocktemplate({'data': b2x(block.serialize()), 'mode': 'proposal'})
assert_equal(rsp, expect)
class MiningTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = False
def run_test(self):
node = self.nodes[0]
# Mine a block to leave initial block download
node.generate(1)
tmpl = node.getblocktemplate()
self.log.info("getblocktemplate: Test capability advertised")
assert 'proposal' in tmpl['capabilities']
assert 'coinbasetxn' not in tmpl
coinbase_tx = create_coinbase(height=int(tmpl["height"]) + 1)
# sequence numbers must not be max for nLockTime to have effect
coinbase_tx.vin[0].nSequence = 2 ** 32 - 2
coinbase_tx.rehash()
block = CBlock()
block.nVersion = tmpl["version"]
block.hashPrevBlock = int(tmpl["previousblockhash"], 16)
block.nTime = tmpl["curtime"]
block.nBits = int(tmpl["bits"], 16)
block.nNonce = 0
block.vtx = [coinbase_tx]
self.log.info("getblocktemplate: Test valid block")
assert_template(node, block, None)
self.log.info("submitblock: Test block decode failure")
assert_raises_jsonrpc(-22, "Block decode failed", node.submitblock, b2x(block.serialize()[:-15]))
self.log.info("getblocktemplate: Test bad input hash for coinbase transaction")
bad_block = copy.deepcopy(block)
bad_block.vtx[0].vin[0].prevout.hash += 1
bad_block.vtx[0].rehash()
assert_template(node, bad_block, 'bad-cb-missing')
self.log.info("submitblock: Test invalid coinbase transaction")
assert_raises_jsonrpc(-22, "Block does not start with a coinbase", node.submitblock, b2x(bad_block.serialize()))
self.log.info("getblocktemplate: Test truncated final transaction")
assert_raises_jsonrpc(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(block.serialize()[:-1]), 'mode': 'proposal'})
self.log.info("getblocktemplate: Test duplicate transaction")
bad_block = copy.deepcopy(block)
bad_block.vtx.append(bad_block.vtx[0])
assert_template(node, bad_block, 'bad-txns-duplicate')
self.log.info("getblocktemplate: Test invalid transaction")
bad_block = copy.deepcopy(block)
bad_tx = copy.deepcopy(bad_block.vtx[0])
bad_tx.vin[0].prevout.hash = 255
bad_tx.rehash()
bad_block.vtx.append(bad_tx)
assert_template(node, bad_block, 'bad-txns-inputs-missingorspent')
self.log.info("getblocktemplate: Test nonfinal transaction")
bad_block = copy.deepcopy(block)
bad_block.vtx[0].nLockTime = 2 ** 32 - 1
bad_block.vtx[0].rehash()
assert_template(node, bad_block, 'bad-txns-nonfinal')
self.log.info("getblocktemplate: Test bad tx count")
# The tx count is immediately after the block header
TX_COUNT_OFFSET = 80
bad_block_sn = bytearray(block.serialize())
assert_equal(bad_block_sn[TX_COUNT_OFFSET], 1)
bad_block_sn[TX_COUNT_OFFSET] += 1
assert_raises_jsonrpc(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(bad_block_sn), 'mode': 'proposal'})
self.log.info("getblocktemplate: Test bad bits")
bad_block = copy.deepcopy(block)
bad_block.nBits = 469762303 # impossible in the real world
assert_template(node, bad_block, 'bad-diffbits')
self.log.info("getblocktemplate: Test bad merkle root")
bad_block = copy.deepcopy(block)
bad_block.hashMerkleRoot += 1
assert_template(node, bad_block, 'bad-txnmrklroot', False)
self.log.info("getblocktemplate: Test bad timestamps")
bad_block = copy.deepcopy(block)
bad_block.nTime = 2 ** 31 - 1
assert_template(node, bad_block, 'time-too-new')
bad_block.nTime = 0
assert_template(node, bad_block, 'time-too-old')
self.log.info("getblocktemplate: Test not best block")
bad_block = copy.deepcopy(block)
bad_block.hashPrevBlock = 123
assert_template(node, bad_block, 'inconclusive-not-best-prevblk')
if __name__ == '__main__':
MiningTest().main()

View File

@ -119,6 +119,7 @@ BASE_SCRIPTS= [
'signmessages.py',
'nulldummy.py',
'import-rescan.py',
'mining.py',
'rpcnamedargs.py',
'listsinceblock.py',
'p2p-leaktests.py',
@ -152,7 +153,6 @@ EXTENDED_SCRIPTS = [
'bipdersig-p2p.py', # NOTE: needs dash_hash to pass
'bipdersig.py',
'example_test.py',
'getblocktemplate_proposals.py',
'txn_doublespend.py',
'txn_clone.py --mineblock',
'txindex.py',