Merge pull request #3029 from PastaPastaPasta/backports-0.15-pr21
Backports 0.15 pr21
This commit is contained in:
commit
8231255dd3
34
configure.ac
34
configure.ac
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
43
src/hash.cpp
43
src/hash.cpp
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
//----------
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
10
src/key.cpp
10
src/key.cpp
@ -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));
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -220,7 +220,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
prevector() : _size(0) {}
|
||||
prevector() : _size(0), _union{{}} {}
|
||||
|
||||
explicit prevector(size_type n) : _size(0) {
|
||||
resize(n);
|
||||
|
@ -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));
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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" },
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "netbase.h"
|
||||
#include "test/test_dash.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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")
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
124
test/functional/mining.py
Executable 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()
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user