Merge branch 'cpp20-modernization' into master
Brings in the cpp20 modernization stream (28+ commits) plus the
CSyncManager extraction and LevelDB->RocksDB chain DB migration.
Conflict resolutions:
- clientversion.h: bumped to v6.0.1 (cpp20's v6.0.0 superseded
master's v5.9.7.0; bumped one revision to mark the merged release)
- .github/workflows/build-all.yml: kept master's explicit submodule
init (Windows CI hardening from 372b252/6c56e41)
- src/trianglesrpc.cpp: combined master's bad-auth crash fix (79b0c4a)
with cpp20's TrimString (de-boost), preserving both defenses
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@ name: Build All Platforms
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [master, cpp20-modernization]
|
||||
tags: ['v*']
|
||||
pull_request:
|
||||
branches: [master]
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ if(POLICY CMP0167)
|
||||
endif()
|
||||
|
||||
project(Triangles
|
||||
VERSION 5.9.5
|
||||
VERSION 6.0.1
|
||||
DESCRIPTION "Cryptographic Triangles Wallet"
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
@@ -62,6 +62,8 @@ set(CORE_SOURCES
|
||||
pbkdf2.cpp
|
||||
scrypt.cpp
|
||||
smessage.cpp
|
||||
syncmanager.cpp
|
||||
chaindb_migrate.cpp
|
||||
tor_embed_hooks.cpp
|
||||
rest.cpp
|
||||
trianglesrpc.cpp
|
||||
|
||||
+14
-17
@@ -81,15 +81,14 @@ double CAddrInfo::GetChance(int64_t nNow) const
|
||||
|
||||
CAddrInfo* CAddrMan::Find(const CNetAddr& addr, int *pnId)
|
||||
{
|
||||
std::map<CNetAddr, int>::iterator it = mapAddr.find(addr);
|
||||
auto it = mapAddr.find(addr);
|
||||
if (it == mapAddr.end())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
if (pnId)
|
||||
*pnId = (*it).second;
|
||||
std::map<int, CAddrInfo>::iterator it2 = mapInfo.find((*it).second);
|
||||
if (it2 != mapInfo.end())
|
||||
return &(*it2).second;
|
||||
return NULL;
|
||||
*pnId = it->second;
|
||||
if (auto it2 = mapInfo.find(it->second); it2 != mapInfo.end())
|
||||
return &it2->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CAddrInfo* CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId)
|
||||
@@ -177,13 +176,13 @@ int CAddrMan::ShrinkNew(int nUBucket)
|
||||
int n[4] = {GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size()), GetRandInt(vNew.size())};
|
||||
int nI = 0;
|
||||
int nOldest = -1;
|
||||
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
|
||||
for (const auto& elem : vNew)
|
||||
{
|
||||
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3])
|
||||
{
|
||||
assert(nOldest == -1 || mapInfo.count(*it) == 1);
|
||||
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
|
||||
nOldest = *it;
|
||||
assert(nOldest == -1 || mapInfo.count(elem) == 1);
|
||||
if (nOldest == -1 || mapInfo[elem].nTime < mapInfo[nOldest].nTime)
|
||||
nOldest = elem;
|
||||
}
|
||||
nI++;
|
||||
}
|
||||
@@ -440,10 +439,8 @@ int CAddrMan::Check_()
|
||||
|
||||
if (vRandom.size() != nTried + nNew) return -7;
|
||||
|
||||
for (std::map<int, CAddrInfo>::iterator it = mapInfo.begin(); it != mapInfo.end(); it++)
|
||||
for (auto& [n, info] : mapInfo)
|
||||
{
|
||||
int n = (*it).first;
|
||||
CAddrInfo &info = (*it).second;
|
||||
if (info.fInTried)
|
||||
{
|
||||
|
||||
@@ -467,10 +464,10 @@ int CAddrMan::Check_()
|
||||
for (int n=0; n<vvTried.size(); n++)
|
||||
{
|
||||
std::vector<int> &vTried = vvTried[n];
|
||||
for (std::vector<int>::iterator it = vTried.begin(); it != vTried.end(); it++)
|
||||
for (const auto& elem : vTried)
|
||||
{
|
||||
if (!setTried.count(*it)) return -11;
|
||||
setTried.erase(*it);
|
||||
if (!setTried.count(elem)) return -11;
|
||||
setTried.erase(elem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-13
@@ -66,7 +66,7 @@ public:
|
||||
if(it == histogram.end()) // Newly locked page
|
||||
{
|
||||
locker.Lock(reinterpret_cast<void*>(page), page_size);
|
||||
histogram.insert(std::make_pair(page, 1));
|
||||
histogram.insert({page, 1});
|
||||
}
|
||||
else // Page was already locked; increase counter
|
||||
{
|
||||
@@ -193,25 +193,25 @@ struct secure_allocator : public std::allocator<T>
|
||||
typedef const T& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
secure_allocator() throw() {}
|
||||
secure_allocator(const secure_allocator& a) throw() : base(a) {}
|
||||
secure_allocator() noexcept {}
|
||||
secure_allocator(const secure_allocator& a) noexcept : base(a) {}
|
||||
template <typename U>
|
||||
secure_allocator(const secure_allocator<U>& a) throw() : base(a) {}
|
||||
~secure_allocator() throw() {}
|
||||
secure_allocator(const secure_allocator<U>& a) noexcept : base(a) {}
|
||||
~secure_allocator() noexcept {}
|
||||
template<typename _Other> struct rebind
|
||||
{ typedef secure_allocator<_Other> other; };
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
T* p = std::allocator<T>::allocate(n);
|
||||
if (p != NULL)
|
||||
if (p != nullptr)
|
||||
LockedPageManager::instance.LockRange(p, sizeof(T) * n);
|
||||
return p;
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
if (p != NULL)
|
||||
if (p != nullptr)
|
||||
{
|
||||
memset(p, 0, sizeof(T) * n);
|
||||
LockedPageManager::instance.UnlockRange(p, sizeof(T) * n);
|
||||
@@ -237,24 +237,24 @@ struct zero_after_free_allocator : public std::allocator<T>
|
||||
typedef const T& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
zero_after_free_allocator() throw() {}
|
||||
zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {}
|
||||
zero_after_free_allocator() noexcept {}
|
||||
zero_after_free_allocator(const zero_after_free_allocator& a) noexcept : base(a) {}
|
||||
template <typename U>
|
||||
zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) {}
|
||||
~zero_after_free_allocator() throw() {}
|
||||
zero_after_free_allocator(const zero_after_free_allocator<U>& a) noexcept : base(a) {}
|
||||
~zero_after_free_allocator() noexcept {}
|
||||
template<typename _Other> struct rebind
|
||||
{ typedef zero_after_free_allocator<_Other> other; };
|
||||
|
||||
void deallocate(T* p, std::size_t n)
|
||||
{
|
||||
if (p != NULL)
|
||||
if (p != nullptr)
|
||||
memset(p, 0, sizeof(T) * n);
|
||||
std::allocator<T>::deallocate(p, n);
|
||||
}
|
||||
};
|
||||
|
||||
// This is exactly like std::string, but with a custom allocator.
|
||||
typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
|
||||
using SecureString = std::basic_string<char, std::char_traits<char>, secure_allocator<char>>;
|
||||
|
||||
static inline SecureString MakeSecureString(const std::string& value)
|
||||
{
|
||||
|
||||
+22
-14
@@ -11,6 +11,7 @@
|
||||
#include "version.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
@@ -37,20 +38,20 @@ public:
|
||||
CAutoBN_CTX()
|
||||
{
|
||||
pctx = BN_CTX_new();
|
||||
if (pctx == NULL)
|
||||
if (pctx == nullptr)
|
||||
throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL");
|
||||
}
|
||||
|
||||
~CAutoBN_CTX()
|
||||
{
|
||||
if (pctx != NULL)
|
||||
if (pctx != nullptr)
|
||||
BN_CTX_free(pctx);
|
||||
}
|
||||
|
||||
operator BN_CTX*() { return pctx; }
|
||||
BN_CTX& operator*() { return *pctx; }
|
||||
BN_CTX** operator&() { return &pctx; }
|
||||
bool operator!() { return (pctx == NULL); }
|
||||
bool operator!() { return (pctx == nullptr); }
|
||||
};
|
||||
|
||||
|
||||
@@ -64,14 +65,14 @@ public:
|
||||
CBigNum()
|
||||
{
|
||||
pbn = BN_new();
|
||||
if (pbn == NULL)
|
||||
if (pbn == nullptr)
|
||||
throw bignum_error("CBigNum::CBigNum() : BN_new() returned NULL");
|
||||
}
|
||||
|
||||
CBigNum(const CBigNum& b)
|
||||
{
|
||||
pbn = BN_new();
|
||||
if (pbn == NULL)
|
||||
if (pbn == nullptr)
|
||||
throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_new() returned NULL");
|
||||
if (!BN_copy(pbn, b.pbn))
|
||||
{
|
||||
@@ -89,7 +90,7 @@ public:
|
||||
|
||||
~CBigNum()
|
||||
{
|
||||
if (pbn != NULL)
|
||||
if (pbn != nullptr)
|
||||
BN_clear_free(pbn);
|
||||
}
|
||||
|
||||
@@ -220,7 +221,7 @@ public:
|
||||
|
||||
uint64_t getuint64()
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(pbn, NULL);
|
||||
unsigned int nSize = BN_bn2mpi(pbn, nullptr);
|
||||
if (nSize < 4)
|
||||
return 0;
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
@@ -290,7 +291,7 @@ public:
|
||||
|
||||
uint256 getuint256() const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(pbn, NULL);
|
||||
unsigned int nSize = BN_bn2mpi(pbn, nullptr);
|
||||
if (nSize < 4)
|
||||
return 0;
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
@@ -321,7 +322,7 @@ public:
|
||||
|
||||
std::vector<unsigned char> getvch() const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(pbn, NULL);
|
||||
unsigned int nSize = BN_bn2mpi(pbn, nullptr);
|
||||
if (nSize <= 4)
|
||||
return std::vector<unsigned char>();
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
@@ -345,7 +346,7 @@ public:
|
||||
|
||||
unsigned int GetCompact() const
|
||||
{
|
||||
unsigned int nSize = BN_bn2mpi(pbn, NULL);
|
||||
unsigned int nSize = BN_bn2mpi(pbn, nullptr);
|
||||
std::vector<unsigned char> vch(nSize);
|
||||
nSize -= 4;
|
||||
BN_bn2mpi(pbn, &vch[0]);
|
||||
@@ -374,7 +375,7 @@ public:
|
||||
psz++;
|
||||
|
||||
// hex string to bignum
|
||||
static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
|
||||
static constexpr signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
|
||||
*this = 0;
|
||||
while (isxdigit(*psz))
|
||||
{
|
||||
@@ -515,7 +516,7 @@ public:
|
||||
*/
|
||||
static CBigNum generatePrime(const unsigned int numBits, bool safe = false) {
|
||||
CBigNum ret;
|
||||
if(!BN_generate_prime_ex(ret.pbn, numBits, (safe == true), NULL, NULL, NULL))
|
||||
if(!BN_generate_prime_ex(ret.pbn, numBits, (safe == true), nullptr, nullptr, nullptr))
|
||||
throw bignum_error("CBigNum::generatePrime*= :BN_generate_prime_ex");
|
||||
return ret;
|
||||
}
|
||||
@@ -541,7 +542,14 @@ public:
|
||||
*/
|
||||
bool isPrime(const int checks=BN_prime_checks) const {
|
||||
CAutoBN_CTX pctx;
|
||||
int ret = BN_is_prime_ex(pbn, checks, pctx, NULL);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
int ret = BN_is_prime_ex(pbn, checks, pctx, nullptr);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
if(ret < 0){
|
||||
throw bignum_error("CBigNum::isPrime :BN_is_prime_ex");
|
||||
}
|
||||
@@ -706,7 +714,7 @@ inline const CBigNum operator/(const CBigNum& a, const CBigNum& b)
|
||||
{
|
||||
CAutoBN_CTX pctx;
|
||||
CBigNum r;
|
||||
if (!BN_div(r.pbn, NULL, a.pbn, b.pbn, pctx))
|
||||
if (!BN_div(r.pbn, nullptr, a.pbn, b.pbn, pctx))
|
||||
throw bignum_error("CBigNum::operator/ : BN_div failed");
|
||||
return r;
|
||||
}
|
||||
|
||||
+6
-7
@@ -7,7 +7,6 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
@@ -64,7 +63,7 @@ static SOCKET ConnectDirectTCP(const std::string& host, int port, std::string& s
|
||||
}
|
||||
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
for (rp = result; rp != nullptr; rp = rp->ai_next) {
|
||||
hSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (hSocket == INVALID_SOCKET)
|
||||
continue;
|
||||
@@ -300,7 +299,7 @@ bool DownloadFile(const std::string& host, const std::string& urlPath,
|
||||
location = headerData.substr(valStart, lineEnd - valStart);
|
||||
else
|
||||
location = headerData.substr(valStart);
|
||||
boost::trim(location);
|
||||
location = TrimString(location);
|
||||
|
||||
// Parse redirect URL — supports http://, https://, and relative paths
|
||||
if (location.compare(0, 7, "http://") == 0 ||
|
||||
@@ -416,7 +415,7 @@ bool FetchFileList(const std::string& host,
|
||||
files.clear();
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
boost::trim(line);
|
||||
line = TrimString(line);
|
||||
if (!line.empty() && line[0] != '#')
|
||||
files.push_back(line);
|
||||
}
|
||||
@@ -576,7 +575,7 @@ bool ParseManifest(const fs::path& manifestPath,
|
||||
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
boost::trim(line);
|
||||
line = TrimString(line);
|
||||
if (line.empty() || line[0] == '#')
|
||||
continue;
|
||||
|
||||
@@ -586,8 +585,8 @@ bool ParseManifest(const fs::path& manifestPath,
|
||||
|
||||
std::string key = line.substr(0, eq);
|
||||
std::string val = line.substr(eq + 1);
|
||||
boost::trim(key);
|
||||
boost::trim(val);
|
||||
key = TrimString(key);
|
||||
val = TrimString(val);
|
||||
|
||||
if (key == "format")
|
||||
manifest.format = std::atoi(val.c_str());
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
// Copyright (c) 2026 The Triangles developers.
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chaindb_migrate.h"
|
||||
|
||||
#include "txdb-leveldb.h"
|
||||
#include "txdb-rocksdb.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace {
|
||||
|
||||
struct ChainDbStats
|
||||
{
|
||||
int64_t nRecords = 0;
|
||||
int64_t nUtxos = 0;
|
||||
int64_t nUtxoValue = 0;
|
||||
uint256 hashBestChain = 0;
|
||||
int nDbFormat = 0;
|
||||
};
|
||||
|
||||
bool CollectStats(CTxDBBase& db, ChainDbStats& stats, std::string& strError)
|
||||
{
|
||||
stats = ChainDbStats();
|
||||
|
||||
auto it = db.NewIterator();
|
||||
for (it->Seek(std::string()); it->Valid(); it->Next())
|
||||
stats.nRecords++;
|
||||
|
||||
int nUtxos = 0;
|
||||
stats.nUtxoValue = db.SumUtxoValues(nUtxos);
|
||||
stats.nUtxos = nUtxos;
|
||||
db.ReadHashBestChain(stats.hashBestChain);
|
||||
db.ReadDbFormat(stats.nDbFormat);
|
||||
|
||||
if (stats.nRecords <= 0) {
|
||||
strError = "source chain database contains no records";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StatsMatch(const ChainDbStats& src, const ChainDbStats& dst, std::string& strError)
|
||||
{
|
||||
if (src.nRecords != dst.nRecords) {
|
||||
strError = strprintf("record count mismatch after migration: source=%lld rocksdb=%lld",
|
||||
(long long)src.nRecords, (long long)dst.nRecords);
|
||||
return false;
|
||||
}
|
||||
if (src.nUtxos != dst.nUtxos || src.nUtxoValue != dst.nUtxoValue) {
|
||||
strError = strprintf("UTXO mismatch after migration: source=(%lld,%lld) rocksdb=(%lld,%lld)",
|
||||
(long long)src.nUtxos, (long long)src.nUtxoValue,
|
||||
(long long)dst.nUtxos, (long long)dst.nUtxoValue);
|
||||
return false;
|
||||
}
|
||||
if (src.hashBestChain != dst.hashBestChain) {
|
||||
strError = strprintf("best-chain hash mismatch after migration: source=%s rocksdb=%s",
|
||||
src.hashBestChain.ToString().c_str(),
|
||||
dst.hashBestChain.ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
if (src.nDbFormat != dst.nDbFormat) {
|
||||
strError = strprintf("dbformat mismatch after migration: source=%d rocksdb=%d",
|
||||
src.nDbFormat, dst.nDbFormat);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool MaybeMigrateLevelDbToRocksDb(bool fForce, std::string& strError)
|
||||
{
|
||||
strError.clear();
|
||||
|
||||
const fs::path dataDir = GetDataDir();
|
||||
const fs::path levelPath = dataDir / "txleveldb";
|
||||
const fs::path rocksPath = dataDir / "rocksdb";
|
||||
const fs::path markerPath = rocksPath / "MIGRATION_INCOMPLETE";
|
||||
|
||||
if (!fs::exists(levelPath))
|
||||
return true;
|
||||
|
||||
if (fs::exists(rocksPath)) {
|
||||
if (fs::exists(markerPath)) {
|
||||
printf("ChainDB migration: removing incomplete previous RocksDB migration\n");
|
||||
fs::remove_all(rocksPath);
|
||||
}
|
||||
else if (!fForce)
|
||||
return true;
|
||||
else {
|
||||
printf("ChainDB migration: removing existing RocksDB directory due to -migratechaindbforce\n");
|
||||
fs::remove_all(rocksPath);
|
||||
}
|
||||
}
|
||||
|
||||
printf("ChainDB migration: copying LevelDB chain state to RocksDB...\n");
|
||||
printf("ChainDB migration: source=%s destination=%s\n",
|
||||
levelPath.string().c_str(), rocksPath.string().c_str());
|
||||
|
||||
try {
|
||||
fs::create_directories(rocksPath);
|
||||
{
|
||||
std::ofstream marker(markerPath);
|
||||
marker << "RocksDB migration in progress. Safe to delete this directory and retry.\n";
|
||||
}
|
||||
|
||||
CTxDB source("r");
|
||||
CRocksTxDB destination("c+");
|
||||
|
||||
ChainDbStats srcStats;
|
||||
if (!CollectStats(source, srcStats, strError)) {
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!destination.TxnBegin()) {
|
||||
strError = "failed to begin RocksDB migration batch";
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t nCopied = 0;
|
||||
auto it = source.NewIterator();
|
||||
for (it->Seek(std::string()); it->Valid(); it->Next())
|
||||
{
|
||||
if (!destination.WriteRawRecordForMigration(it->KeyStr(), it->ValueStr())) {
|
||||
destination.TxnAbort();
|
||||
strError = "failed to write migrated record to RocksDB";
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (++nCopied % 100000 == 0)
|
||||
{
|
||||
if (!destination.TxnCommit()) {
|
||||
strError = "failed to commit RocksDB migration batch";
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
printf("ChainDB migration: copied %lld / %lld records\n",
|
||||
(long long)nCopied, (long long)srcStats.nRecords);
|
||||
if (!destination.TxnBegin()) {
|
||||
strError = "failed to begin RocksDB migration batch";
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!destination.TxnCommit()) {
|
||||
strError = "failed to commit final RocksDB migration batch";
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
ChainDbStats dstStats;
|
||||
if (!CollectStats(destination, dstStats, strError)) {
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
if (!StatsMatch(srcStats, dstStats, strError)) {
|
||||
source.Close();
|
||||
destination.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("ChainDB migration: verified %lld records, %lld UTXOs, best=%s\n",
|
||||
(long long)dstStats.nRecords,
|
||||
(long long)dstStats.nUtxos,
|
||||
dstStats.hashBestChain.ToString().substr(0,20).c_str());
|
||||
|
||||
source.Close();
|
||||
destination.Close();
|
||||
fs::remove(markerPath);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
strError = e.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("ChainDB migration: complete. Legacy LevelDB was left untouched at %s\n",
|
||||
levelPath.string().c_str());
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2026 The Triangles developers.
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef TRIANGLES_CHAINDB_MIGRATE_H
|
||||
#define TRIANGLES_CHAINDB_MIGRATE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
// Migrate legacy LevelDB chain state from <datadir>/txleveldb to RocksDB in
|
||||
// <datadir>/rocksdb. The source is never modified. Returns true when migration
|
||||
// succeeds or when there is nothing to migrate.
|
||||
bool MaybeMigrateLevelDbToRocksDb(bool fForce, std::string& strError);
|
||||
|
||||
#endif // TRIANGLES_CHAINDB_MIGRATE_H
|
||||
+8
-26
@@ -25,21 +25,13 @@ namespace Checkpoints
|
||||
{ 2101, uint256("0xd4ea1ac45b63c8162a7fc8033cec441db8d532ba988202849d7831e32fe2d059")},
|
||||
{ 2847, uint256("0xb5015e2835f13fd3bb6135cff9b31ac33310c9b77d694bdb592b8680d98d018e")},
|
||||
{ 3589, uint256("0xb12a2ca3db4e288cada98aa2139768532bd4474c49dd7b8158031032dac08d51")},
|
||||
{ 3935, uint256("0xe16290c9757d1368b8d7c35de07d4f8f70c2c9f9c785b667df0c3bff85086ca6")},
|
||||
{ 3935, uint256("0xe16290c9757d1368b8d7c35de4f8f70c2c9f9c785b667df0c3bff85086ca6")},
|
||||
{ 5703, uint256("0x587db07bb2172ad7db72c5fabc2518262a1b27f503f99417510b2c6fafa6557b")},
|
||||
{ 9000, uint256("0x00000000019ef6b2f5e7c324c7d083ee94502305aabc7e9cd73a7fb2a57bb8db")},
|
||||
{ 9001, uint256("0x6d5c6c5f201cc9e59659ee0da30d1430dc6bf3b12a8ff4c3864ab8d6286b0007")},
|
||||
{ 9002, uint256("0xa1e20fb1d44688b763690cf74d6aefe859e4cc32981f9e3f2b2ae9702bbcf249")},
|
||||
{ 10881, uint256("0x4b6554c45e1e6764a6f3c309c47baf53c9edd81f624e52b072518cd15da237e6")},
|
||||
{ 17650, uint256("0x224940e1f986a202209b8e762728d1452ab45870c308abf84905674acf326a47")},
|
||||
{2000000, uint256("0xb0b02d4bb5ffa31f6f22fd042082ca0a085257af34dc2d4b31c3c8567b5574d5")},
|
||||
{2186940, uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0")},
|
||||
{2190000, uint256("0x682baf783581468ba18f9967254a7f3944e8b8c4cc7101e7d99b68f4f9dd5271")},
|
||||
{2200000, uint256("0x0a8d0442f031f1258120f713f34e45f4f9a625fb753558e27b89b32ad5a9a740")},
|
||||
{2205000, uint256("0xf7aa893ec012181e321783d6a5487addf6997377908faa3e760c9054a4217d29")},
|
||||
{2206000, uint256("0x780ae878f8b10b6cbd51ceb2c0799c90d3551fa916be62974375071b9e36581c")},
|
||||
{2203594, uint256("0x5e016ae5d1f163c6679292b717a3db467a39d24b0a315182f4783caa79c722d8")},
|
||||
{2207000, uint256("0x8836d67b0f08036c4a7c26ff0a29d4461a52b6d8f552165ad9c1abec2f3cadfd")},
|
||||
};
|
||||
|
||||
// Published UTXO snapshot file SHA256, keyed by snapshot height.
|
||||
@@ -51,7 +43,6 @@ namespace Checkpoints
|
||||
// here. The corresponding (height, blockhash) must already exist in
|
||||
// mapCheckpoints / mapCheckpointsTestnet.
|
||||
static std::map<int, uint256> mapSnapshotHashes = {
|
||||
{2203594, uint256("0x49b35dd01659975c4a31954f37174c6e2e8878dd0723ab306ccecd991c80f79a")},
|
||||
};
|
||||
|
||||
static std::map<int, uint256> mapSnapshotHashesTestnet = {
|
||||
@@ -63,22 +54,13 @@ namespace Checkpoints
|
||||
{ 2101, uint256("0xd4ea1ac45b63c8162a7fc8033cec441db8d532ba988202849d7831e32fe2d059")},
|
||||
{ 2847, uint256("0xb5015e2835f13fd3bb6135cff9b31ac33310c9b77d694bdb592b8680d98d018e")},
|
||||
{ 3589, uint256("0xb12a2ca3db4e288cada98aa2139768532bd4474c49dd7b8158031032dac08d51")},
|
||||
{ 3935, uint256("0xe16290c9757d1368b8d7c35de07d4f8f70c2c9f9c785b667df0c3bff85086ca6")},
|
||||
{ 3935, uint256("0xe16290c9757d1368b8d7c35de4f8f70c2c9f9c785b667df0c3bff85086ca6")},
|
||||
{ 5703, uint256("0x587db07bb2172ad7db72c5fabc2518262a1b27f503f99417510b2c6fafa6557b")},
|
||||
{ 9000, uint256("0x00000000019ef6b2f5e7c324c7d083ee94502305aabc7e9cd73a7fb2a57bb8db")},
|
||||
{ 9001, uint256("0x6d5c6c5f201cc9e59659ee0da30d1430dc6bf3b12a8ff4c3864ab8d6286b0007")},
|
||||
{ 9002, uint256("0xa1e20fb1d44688b763690cf74d6aefe859e4cc32981f9e3f2b2ae9702bbcf249")},
|
||||
{ 10881, uint256("0x4b6554c45e1e6764a6f3c309c47baf53c9edd81f624e52b072518cd15da237e6")},
|
||||
{ 17650, uint256("0x224940e1f986a202209b8e762728d1452ab45870c308abf84905674acf326a47")},
|
||||
{2000000, uint256("0xb0b02d4bb5ffa31f6f22fd042082ca0a085257af34dc2d4b31c3c8567b5574d5")},
|
||||
{2186940, uint256("0xbd952e8d4a612e336d840ad924a7e09395e36bcd9d929b302e47e60b5c3098c0")},
|
||||
{2190000, uint256("0x682baf783581468ba18f9967254a7f3944e8b8c4cc7101e7d99b68f4f9dd5271")},
|
||||
{2200000, uint256("0x0a8d0442f031f1258120f713f34e45f4f9a625fb753558e27b89b32ad5a9a740")},
|
||||
{2205000, uint256("0xf7aa893ec012181e321783d6a5487addf6997377908faa3e760c9054a4217d29")},
|
||||
{2206000, uint256("0x780ae878f8b10b6cbd51ceb2c0799c90d3551fa916be62974375071b9e36581c")},
|
||||
{2207000, uint256("0x8836d67b0f08036c4a7c26ff0a29d4461a52b6d8f552165ad9c1abec2f3cadfd")},
|
||||
{2208000, uint256("0xe4a19e8a29fa7aae47f7563377af3e896fee18ed069a64e325b8c2c6c820a1be")},
|
||||
{2209000, uint256("0x04c78a6fc863bed918a9364c58c64489943b2e85d84ddb1ac2fba584f390d5dc")},
|
||||
};
|
||||
|
||||
bool CheckHardened(int nHeight, const uint256& hash)
|
||||
@@ -132,7 +114,7 @@ namespace Checkpoints
|
||||
if (t != mapBlockIndex.end())
|
||||
return t->second;
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// triangles: synchronized checkpoint (centrally broadcasted)
|
||||
@@ -151,7 +133,7 @@ namespace Checkpoints
|
||||
error("GetSyncCheckpoint: block index missing for current sync-checkpoint %s", hashSyncCheckpoint.ToString().c_str());
|
||||
else
|
||||
return mapBlockIndex[hashSyncCheckpoint];
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// triangles: only descendant of current sync-checkpoint is allowed
|
||||
@@ -281,8 +263,8 @@ namespace Checkpoints
|
||||
return false;
|
||||
if (hashBlock == hashPendingCheckpoint)
|
||||
return true;
|
||||
if (mapOrphanBlocks.count(hashPendingCheckpoint)
|
||||
&& hashBlock == WantedByOrphan(mapOrphanBlocks[hashPendingCheckpoint]))
|
||||
if (mapOrphanBlocks.count(hashPendingCheckpoint)
|
||||
&& hashBlock == WantedByOrphan(mapOrphanBlocks[hashPendingCheckpoint].get()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -371,7 +353,7 @@ namespace Checkpoints
|
||||
if (!key.Sign(Hash(checkpoint.vchMsg.begin(), checkpoint.vchMsg.end()), checkpoint.vchSig))
|
||||
return error("SendSyncCheckpoint: Unable to sign checkpoint, check private key?");
|
||||
|
||||
if(!checkpoint.ProcessSyncCheckpoint(NULL))
|
||||
if(!checkpoint.ProcessSyncCheckpoint(nullptr))
|
||||
{
|
||||
printf("WARNING: SendSyncCheckpoint: Failed to process checkpoint.\n");
|
||||
return false;
|
||||
@@ -432,7 +414,7 @@ bool CSyncCheckpoint::ProcessSyncCheckpoint(CNode* pfrom)
|
||||
pfrom->PushGetBlocks(pindexBest, hashCheckpoint);
|
||||
// ask directly as well in case rejected earlier by duplicate
|
||||
// proof-of-stake because getblocks may not get it this time
|
||||
pfrom->AskFor(CInv(MSG_BLOCK, mapOrphanBlocks.count(hashCheckpoint)? WantedByOrphan(mapOrphanBlocks[hashCheckpoint]) : hashCheckpoint));
|
||||
pfrom->AskFor(CInv(MSG_BLOCK, mapOrphanBlocks.count(hashCheckpoint)? WantedByOrphan(mapOrphanBlocks[hashCheckpoint].get()) : hashCheckpoint));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-2
@@ -72,10 +72,10 @@ private:
|
||||
nIdle--;
|
||||
lock.unlock();
|
||||
|
||||
for (unsigned int i = 0; i < vChecks.size(); i++)
|
||||
for (auto& check : vChecks)
|
||||
{
|
||||
if (fOk)
|
||||
fOk = vChecks[i]();
|
||||
fOk = check();
|
||||
}
|
||||
vChecks.clear();
|
||||
|
||||
|
||||
+3
-3
@@ -6,9 +6,9 @@
|
||||
//
|
||||
|
||||
// These need to be macros, as version.cpp's and triangles-qt.rc's voodoo requires it
|
||||
#define CLIENT_VERSION_MAJOR 5
|
||||
#define CLIENT_VERSION_MINOR 9
|
||||
#define CLIENT_VERSION_REVISION 7
|
||||
#define CLIENT_VERSION_MAJOR 6
|
||||
#define CLIENT_VERSION_MINOR 0
|
||||
#define CLIENT_VERSION_REVISION 1
|
||||
#define CLIENT_VERSION_BUILD 0
|
||||
|
||||
// Converts the parameter X to a string after macro replacement on X has been performed.
|
||||
|
||||
+2
-2
@@ -75,7 +75,7 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
|
||||
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, chKey, chIV);
|
||||
if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
|
||||
if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0])+nCLen, &nFLen);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
@@ -102,7 +102,7 @@ bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingM
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
|
||||
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, chKey, chIV);
|
||||
if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
|
||||
if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0])+nPLen, &nFLen);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||
using CKeyingMaterial = std::vector<unsigned char, secure_allocator<unsigned char>>;
|
||||
|
||||
/** Encryption/decryption context with key information */
|
||||
class CCrypter
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ secp256k1_context* GetECDHContext()
|
||||
}
|
||||
|
||||
// Hash function callback that returns the raw X coordinate of the shared
|
||||
// point. Mirrors OpenSSL's ECDH_compute_key behaviour when the KDF is NULL.
|
||||
// point. Mirrors OpenSSL's ECDH_compute_key behaviour when the KDF is nullptr.
|
||||
int hash_xonly(unsigned char* output,
|
||||
const unsigned char* x32,
|
||||
const unsigned char* /*y32*/,
|
||||
|
||||
+19
-19
@@ -133,7 +133,7 @@ void CDBEnv::MakeMock()
|
||||
#ifdef DB_LOG_IN_MEMORY
|
||||
dbenv.log_set_config(DB_LOG_IN_MEMORY, 1);
|
||||
#endif
|
||||
int ret = dbenv.open(NULL,
|
||||
int ret = dbenv.open(nullptr,
|
||||
DB_CREATE |
|
||||
DB_INIT_LOCK |
|
||||
DB_INIT_LOG |
|
||||
@@ -155,10 +155,10 @@ CDBEnv::VerifyResult CDBEnv::Verify(std::string strFile, bool (*recoverFunc)(CDB
|
||||
assert(mapFileUseCount.count(strFile) == 0);
|
||||
|
||||
Db db(&dbenv, 0);
|
||||
int result = db.verify(strFile.c_str(), NULL, NULL, 0);
|
||||
int result = db.verify(strFile.c_str(), nullptr, nullptr, 0);
|
||||
if (result == 0)
|
||||
return VERIFY_OK;
|
||||
else if (recoverFunc == NULL)
|
||||
else if (recoverFunc == nullptr)
|
||||
return RECOVER_FAIL;
|
||||
|
||||
// Try to recover:
|
||||
@@ -178,7 +178,7 @@ bool CDBEnv::Salvage(std::string strFile, bool fAggressive,
|
||||
stringstream strDump;
|
||||
|
||||
Db db(&dbenv, 0);
|
||||
int result = db.verify(strFile.c_str(), NULL, &strDump, flags);
|
||||
int result = db.verify(strFile.c_str(), nullptr, &strDump, flags);
|
||||
if (result == DB_VERIFY_BAD)
|
||||
{
|
||||
printf("Error: Salvage found errors, all data may not be recoverable.\n");
|
||||
@@ -231,10 +231,10 @@ void CDBEnv::CheckpointLSN(std::string strFile)
|
||||
|
||||
|
||||
CDB::CDB(const char *pszFile, const char* pszMode) :
|
||||
pdb(NULL), activeTxn(NULL)
|
||||
pdb(nullptr), activeTxn(nullptr)
|
||||
{
|
||||
int ret;
|
||||
if (pszFile == NULL)
|
||||
if (pszFile == nullptr)
|
||||
return;
|
||||
|
||||
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
||||
@@ -251,7 +251,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) :
|
||||
strFile = pszFile;
|
||||
++bitdb.mapFileUseCount[strFile];
|
||||
pdb = bitdb.mapDb[strFile];
|
||||
if (pdb == NULL)
|
||||
if (pdb == nullptr)
|
||||
{
|
||||
pdb = new Db(&bitdb.dbenv, 0);
|
||||
|
||||
@@ -264,8 +264,8 @@ CDB::CDB(const char *pszFile, const char* pszMode) :
|
||||
throw runtime_error(strprintf("CDB() : failed to configure for no temp file backing for database %s", pszFile));
|
||||
}
|
||||
|
||||
ret = pdb->open(NULL, // Txn pointer
|
||||
fMockDb ? NULL : pszFile, // Filename
|
||||
ret = pdb->open(nullptr, // Txn pointer
|
||||
fMockDb ? nullptr : pszFile, // Filename
|
||||
"main", // Logical db name
|
||||
DB_BTREE, // Database type
|
||||
nFlags, // Flags
|
||||
@@ -274,7 +274,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) :
|
||||
if (ret != 0)
|
||||
{
|
||||
delete pdb;
|
||||
pdb = NULL;
|
||||
pdb = nullptr;
|
||||
--bitdb.mapFileUseCount[strFile];
|
||||
strFile = "";
|
||||
throw runtime_error(strprintf("CDB() : can't open database file %s, error %d", pszFile, ret));
|
||||
@@ -307,8 +307,8 @@ void CDB::Close()
|
||||
return;
|
||||
if (activeTxn)
|
||||
activeTxn->abort();
|
||||
activeTxn = NULL;
|
||||
pdb = NULL;
|
||||
activeTxn = nullptr;
|
||||
pdb = nullptr;
|
||||
|
||||
// Flush database activity from memory pool to disk log
|
||||
unsigned int nMinutes = 0;
|
||||
@@ -331,13 +331,13 @@ void CDBEnv::CloseDb(const string& strFile)
|
||||
{
|
||||
{
|
||||
LOCK(cs_db);
|
||||
if (mapDb[strFile] != NULL)
|
||||
if (mapDb[strFile] != nullptr)
|
||||
{
|
||||
// Close the database handle
|
||||
Db* pdb = mapDb[strFile];
|
||||
pdb->close(0);
|
||||
delete pdb;
|
||||
mapDb[strFile] = NULL;
|
||||
mapDb[strFile] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,7 @@ bool CDBEnv::RemoveDb(const string& strFile)
|
||||
this->CloseDb(strFile);
|
||||
|
||||
LOCK(cs_db);
|
||||
int rc = dbenv.dbremove(NULL, strFile.c_str(), NULL, DB_AUTO_COMMIT);
|
||||
int rc = dbenv.dbremove(nullptr, strFile.c_str(), nullptr, DB_AUTO_COMMIT);
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
|
||||
CDB db(strFile.c_str(), "r");
|
||||
Db* pdbCopy = new Db(&bitdb.dbenv, 0);
|
||||
|
||||
int ret = pdbCopy->open(NULL, // Txn pointer
|
||||
int ret = pdbCopy->open(nullptr, // Txn pointer
|
||||
strFileRes.c_str(), // Filename
|
||||
"main", // Logical db name
|
||||
DB_BTREE, // Database type
|
||||
@@ -412,7 +412,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
|
||||
}
|
||||
Dbt datKey(&ssKey[0], ssKey.size());
|
||||
Dbt datValue(&ssValue[0], ssValue.size());
|
||||
int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
|
||||
int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, DB_NOOVERWRITE);
|
||||
if (ret2 > 0)
|
||||
fSuccess = false;
|
||||
}
|
||||
@@ -428,10 +428,10 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
|
||||
if (fSuccess)
|
||||
{
|
||||
Db dbA(&bitdb.dbenv, 0);
|
||||
if (dbA.remove(strFile.c_str(), NULL, 0))
|
||||
if (dbA.remove(strFile.c_str(), nullptr, 0))
|
||||
fSuccess = false;
|
||||
Db dbB(&bitdb.dbenv, 0);
|
||||
if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
|
||||
if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), 0))
|
||||
fSuccess = false;
|
||||
}
|
||||
if (!fSuccess)
|
||||
|
||||
@@ -84,10 +84,10 @@ public:
|
||||
|
||||
DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)
|
||||
{
|
||||
DbTxn* ptxn = NULL;
|
||||
int ret = dbenv.txn_begin(NULL, &ptxn, flags);
|
||||
DbTxn* ptxn = nullptr;
|
||||
int ret = dbenv.txn_begin(nullptr, &ptxn, flags);
|
||||
if (!ptxn || ret != 0)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
return ptxn;
|
||||
}
|
||||
};
|
||||
@@ -130,7 +130,7 @@ protected:
|
||||
datValue.set_flags(DB_DBT_MALLOC);
|
||||
int ret = pdb->get(activeTxn, &datKey, &datValue, 0);
|
||||
memset(datKey.get_data(), 0, datKey.get_size());
|
||||
if (datValue.get_data() == NULL)
|
||||
if (datValue.get_data() == nullptr)
|
||||
return false;
|
||||
|
||||
// Unserialize value
|
||||
@@ -222,11 +222,11 @@ protected:
|
||||
Dbc* GetCursor()
|
||||
{
|
||||
if (!pdb)
|
||||
return NULL;
|
||||
Dbc* pcursor = NULL;
|
||||
int ret = pdb->cursor(NULL, &pcursor, 0);
|
||||
return nullptr;
|
||||
Dbc* pcursor = nullptr;
|
||||
int ret = pdb->cursor(nullptr, &pcursor, 0);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
return pcursor;
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ protected:
|
||||
int ret = pcursor->get(&datKey, &datValue, fFlags);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
|
||||
else if (datKey.get_data() == nullptr || datValue.get_data() == nullptr)
|
||||
return 99999;
|
||||
|
||||
// Convert to streams
|
||||
@@ -286,7 +286,7 @@ public:
|
||||
if (!pdb || !activeTxn)
|
||||
return false;
|
||||
int ret = activeTxn->commit(0);
|
||||
activeTxn = NULL;
|
||||
activeTxn = nullptr;
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ public:
|
||||
if (!pdb || !activeTxn)
|
||||
return false;
|
||||
int ret = activeTxn->abort();
|
||||
activeTxn = NULL;
|
||||
activeTxn = nullptr;
|
||||
return (ret == 0);
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ public:
|
||||
return Write(std::string("version"), nVersion);
|
||||
}
|
||||
|
||||
bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
|
||||
bool static Rewrite(const std::string& strFile, const char* pszSkip = nullptr);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+52
-43
@@ -24,12 +24,13 @@
|
||||
#endif
|
||||
#include "notificationqueue.h"
|
||||
#include "addressindex.h"
|
||||
#include "chaindb_migrate.h"
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <boost/interprocess/sync/file_lock.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#ifndef WIN32
|
||||
@@ -51,20 +52,20 @@ using namespace std;
|
||||
using namespace boost;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
CWallet* pwalletMain;
|
||||
std::unique_ptr<CWallet> pwalletMain;
|
||||
CClientUIInterface uiInterface;
|
||||
std::string strWalletFileName;
|
||||
bool fConfChange;
|
||||
bool fEnforceCanonical;
|
||||
unsigned int nNodeLifespan;
|
||||
unsigned int nDerivationMethodIndex;
|
||||
//unsigned int nMinerSleep;
|
||||
|
||||
bool fUseFastIndex;
|
||||
enum Checkpoints::CPMode CheckpointsMode;
|
||||
|
||||
static CCriticalSection cs_DeferredStartup;
|
||||
static bool fDeferredStartupRunning = false;
|
||||
static std::vector<std::thread>* pScriptCheckThreads = nullptr;
|
||||
static std::unique_ptr<std::vector<std::thread>> pScriptCheckThreads;
|
||||
|
||||
static void ThreadScriptCheck()
|
||||
{
|
||||
@@ -109,7 +110,7 @@ fRequestShutdown = true;
|
||||
uiInterface.QueueShutdown();
|
||||
#else
|
||||
// Without UI, Shutdown() can simply be started in a new thread
|
||||
NewThread(Shutdown, NULL);
|
||||
NewThread(Shutdown, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -178,7 +179,7 @@ void ThreadDeferredStartup(void* parg)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
PrintExceptionContinue(NULL, "ThreadDeferredStartup()");
|
||||
PrintExceptionContinue(nullptr, "ThreadDeferredStartup()");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -235,11 +236,9 @@ void Shutdown(void* parg)
|
||||
{
|
||||
for (std::thread& t : *pScriptCheckThreads)
|
||||
if (t.joinable()) t.join();
|
||||
delete pScriptCheckThreads;
|
||||
pScriptCheckThreads = nullptr;
|
||||
pScriptCheckThreads.reset();
|
||||
}
|
||||
delete pScriptCheckQueue;
|
||||
pScriptCheckQueue = NULL;
|
||||
pScriptCheckQueue.reset();
|
||||
}
|
||||
|
||||
// NOW safe to destroy Tor state - all threads have stopped
|
||||
@@ -251,24 +250,24 @@ void Shutdown(void* parg)
|
||||
{
|
||||
pzmqNotifier->Shutdown();
|
||||
delete pzmqNotifier;
|
||||
pzmqNotifier = NULL;
|
||||
pzmqNotifier = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pNotificationQueue)
|
||||
{
|
||||
delete pNotificationQueue;
|
||||
pNotificationQueue = NULL;
|
||||
pNotificationQueue = nullptr;
|
||||
}
|
||||
|
||||
// MakeChainDB()->Close();
|
||||
bitdb.Flush(false);
|
||||
bitdb.Flush(true);
|
||||
fs::remove(GetPidFile());
|
||||
UnregisterWallet(pwalletMain);
|
||||
delete pwalletMain;
|
||||
UnregisterWallet(pwalletMain.get());
|
||||
pwalletMain.reset();
|
||||
// DB is flushed and wallet saved - safe to force-exit if something hangs
|
||||
NewThread(ExitTimeout, NULL);
|
||||
NewThread(ExitTimeout, nullptr);
|
||||
MilliSleep(50);
|
||||
printf("Triangles exited\n\n");
|
||||
fExit = true;
|
||||
@@ -318,7 +317,7 @@ bool AppInit(int argc, char* argv[])
|
||||
if (!fs::is_directory(GetDataDir(false)))
|
||||
{
|
||||
fprintf(stderr, "Error: Specified directory does not exist\n");
|
||||
Shutdown(NULL);
|
||||
Shutdown(nullptr);
|
||||
}
|
||||
ReadConfigFile(mapArgs, mapMultiArgs);
|
||||
|
||||
@@ -340,7 +339,7 @@ bool AppInit(int argc, char* argv[])
|
||||
|
||||
// Command-line RPC
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "Triangles:"))
|
||||
if (!IsSwitchChar(argv[i][0]) && !std::equal(std::begin("Triangles:"), std::end("Triangles:") - 1, argv[i], [](char a, char b) { return std::tolower(static_cast<unsigned char>(a)) == std::tolower(static_cast<unsigned char>(b)); }))
|
||||
fCommandLine = true;
|
||||
|
||||
if (fCommandLine)
|
||||
@@ -354,10 +353,10 @@ bool AppInit(int argc, char* argv[])
|
||||
catch (std::exception& e) {
|
||||
PrintException(&e, "AppInit()");
|
||||
} catch (...) {
|
||||
PrintException(NULL, "AppInit()");
|
||||
PrintException(nullptr, "AppInit()");
|
||||
}
|
||||
if (!fRet)
|
||||
Shutdown(NULL);
|
||||
Shutdown(nullptr);
|
||||
return fRet;
|
||||
}
|
||||
|
||||
@@ -542,7 +541,7 @@ bool AppInit2()
|
||||
#ifdef _MSC_VER
|
||||
// Turn off Microsoft heap dump noise
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
|
||||
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0));
|
||||
#endif
|
||||
#if _MSC_VER >= 1400
|
||||
// Disable confusing "helpful" text message on abort, Ctrl-C
|
||||
@@ -559,7 +558,7 @@ bool AppInit2()
|
||||
#endif
|
||||
typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
|
||||
PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
|
||||
if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
|
||||
if (setProcDEPPol != nullptr) setProcDEPPol(PROCESS_DEP_ENABLE);
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
umask(077);
|
||||
@@ -569,15 +568,15 @@ bool AppInit2()
|
||||
sa.sa_handler = HandleSIGTERM;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, nullptr);
|
||||
sigaction(SIGINT, &sa, nullptr);
|
||||
|
||||
// Reopen debug.log on SIGHUP
|
||||
struct sigaction sa_hup;
|
||||
sa_hup.sa_handler = HandleSIGHUP;
|
||||
sigemptyset(&sa_hup.sa_mask);
|
||||
sa_hup.sa_flags = 0;
|
||||
sigaction(SIGHUP, &sa_hup, NULL);
|
||||
sigaction(SIGHUP, &sa_hup, nullptr);
|
||||
#endif
|
||||
|
||||
// ********************************************************* Step 2: parameter interactions
|
||||
@@ -587,7 +586,7 @@ bool AppInit2()
|
||||
//nMinerSleep = GetArg("-minersleep", 500);
|
||||
|
||||
CheckpointsMode = Checkpoints::STRICT;
|
||||
std::string strCpMode = GetArg("-cppolicy", "strict");
|
||||
std::string strCpMode = GetArg(std::string_view{"-cppolicy"}, std::string_view{"strict"});
|
||||
|
||||
if(strCpMode == "strict")
|
||||
CheckpointsMode = Checkpoints::STRICT;
|
||||
@@ -706,8 +705,8 @@ bool AppInit2()
|
||||
nScriptCheckThreads = 16;
|
||||
if (nScriptCheckThreads > 1)
|
||||
{
|
||||
pScriptCheckQueue = new CCheckQueue<CScriptCheck>(32);
|
||||
pScriptCheckThreads = new std::vector<std::thread>();
|
||||
pScriptCheckQueue = std::make_unique<CCheckQueue<CScriptCheck>>(32);
|
||||
pScriptCheckThreads = std::make_unique<std::vector<std::thread>>();
|
||||
for (int i = 0; i < nScriptCheckThreads - 1; ++i)
|
||||
pScriptCheckThreads->emplace_back(&ThreadScriptCheck);
|
||||
printf("Script verification threads: %d workers + main thread\n", nScriptCheckThreads - 1);
|
||||
@@ -729,7 +728,7 @@ bool AppInit2()
|
||||
return InitError(_("Initialization sanity check failed. Triangles is shutting down."));
|
||||
|
||||
std::string strDataDir = GetDataDir().string();
|
||||
std::string strWalletFileName = GetArg("-wallet", "wallet.dat");
|
||||
std::string strWalletFileName = GetArg(std::string_view{"-wallet"}, std::string_view{"wallet.dat"});
|
||||
|
||||
// strWalletFileName must be a plain filename without a directory
|
||||
if (strWalletFileName != fs::path(strWalletFileName).stem().string() + fs::path(strWalletFileName).extension().string())
|
||||
@@ -913,7 +912,7 @@ bool AppInit2()
|
||||
|
||||
if (mapArgs.count("-checkpointkey")) // triangles: checkpoint master priv key
|
||||
{
|
||||
if (!Checkpoints::SetCheckpointPrivKey(GetArg("-checkpointkey", "")))
|
||||
if (!Checkpoints::SetCheckpointPrivKey(GetArg(std::string_view{"-checkpointkey"}, std::string_view{""})))
|
||||
InitError(_("Unable to sign checkpoint, wrong checkpointkey?\n"));
|
||||
}
|
||||
|
||||
@@ -1036,6 +1035,16 @@ bool AppInit2()
|
||||
}
|
||||
}
|
||||
|
||||
// ********************************************************* Step 6d: optional LevelDB -> RocksDB chain DB migration
|
||||
if (GetBoolArg("-migratechaindb", false) || GetBoolArg("-migratechaindbforce", false))
|
||||
{
|
||||
uiInterface.InitMessage(_("Migrating chain database to RocksDB..."));
|
||||
std::string strMigrateError;
|
||||
bool fForce = GetBoolArg("-migratechaindbforce", false);
|
||||
if (!MaybeMigrateLevelDbToRocksDb(fForce, strMigrateError))
|
||||
return InitError(strprintf(_("Chain DB migration failed: %s"), strMigrateError.c_str()));
|
||||
}
|
||||
|
||||
// ********************************************************* Step 7: load blockchain
|
||||
|
||||
if (!bitdb.Open(GetDataDir()))
|
||||
@@ -1154,7 +1163,7 @@ bool AppInit2()
|
||||
printf("Loading wallet...\n");
|
||||
nStart = GetTimeMillis();
|
||||
bool fFirstRun = true;
|
||||
pwalletMain = new CWallet(strWalletFileName);
|
||||
pwalletMain = std::make_unique<CWallet>(strWalletFileName);
|
||||
|
||||
// Auto-backup wallet.dat before loading (protects against corruption during load/flush)
|
||||
{
|
||||
@@ -1198,9 +1207,9 @@ bool AppInit2()
|
||||
int nMaxVersion = GetArg("-upgradewallet", 0);
|
||||
if (nMaxVersion == 0) // the -upgradewallet without argument case
|
||||
{
|
||||
printf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
|
||||
printf("Performing wallet upgrade to %i\n", static_cast<int>(WalletFeature::Latest));
|
||||
nMaxVersion = CLIENT_VERSION;
|
||||
pwalletMain->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
|
||||
pwalletMain->SetMinVersion(WalletFeature::Latest); // permanently upgrade the wallet immediately
|
||||
}
|
||||
else
|
||||
printf("Allowing wallet upgrade up to %i\n", nMaxVersion);
|
||||
@@ -1226,7 +1235,7 @@ bool AppInit2()
|
||||
printf(" wallet %15" PRId64 "ms\n", GetTimeMillis() - nStart);
|
||||
StartupPerfLog("wallet_load", GetTimeMillis() - nStart, strprintf("firstrun=%d", fFirstRun));
|
||||
|
||||
RegisterWallet(pwalletMain);
|
||||
RegisterWallet(pwalletMain.get());
|
||||
|
||||
CBlockIndex *pindexRescan = pindexBest;
|
||||
if (GetBoolArg("-rescan"))
|
||||
@@ -1425,7 +1434,7 @@ bool AppInit2()
|
||||
|
||||
// Launch background thread for Tor health monitoring and seeder maintenance
|
||||
if (torStarted) {
|
||||
if (!NewThread(ThreadTorMaintenance, NULL))
|
||||
if (!NewThread(ThreadTorMaintenance, nullptr))
|
||||
printf("Warning: ThreadTorMaintenance could not be started\n");
|
||||
}
|
||||
}
|
||||
@@ -1493,11 +1502,11 @@ bool AppInit2()
|
||||
printf("mapWallet.size() = %" PRIszu "\n", pwalletMain->mapWallet.size());
|
||||
printf("mapAddressBook.size() = %" PRIszu "\n", pwalletMain->mapAddressBook.size());
|
||||
|
||||
if (!NewThread(StartNode, NULL))
|
||||
if (!NewThread(StartNode, nullptr))
|
||||
InitError(_("Error: could not start node"));
|
||||
|
||||
if (fServer)
|
||||
NewThread(ThreadRPCServer, NULL);
|
||||
NewThread(ThreadRPCServer, nullptr);
|
||||
|
||||
// ********************************************************* Step 11.6: P2P UTXO snapshot fetch
|
||||
// If the chain is empty and snapshot mode is enabled (default), spawn a
|
||||
@@ -1513,7 +1522,7 @@ bool AppInit2()
|
||||
if (snapshotMode && needsSnapshot && !haveSnapshotFile &&
|
||||
Checkpoints::GetBestSnapshotHeight() > 0)
|
||||
{
|
||||
NewThread(ThreadSnapshotFetch, NULL);
|
||||
NewThread(ThreadSnapshotFetch, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1521,21 +1530,21 @@ bool AppInit2()
|
||||
LOCK(cs_DeferredStartup);
|
||||
fDeferredStartupRunning = true;
|
||||
}
|
||||
if (!NewThread(ThreadDeferredStartup, NULL))
|
||||
if (!NewThread(ThreadDeferredStartup, nullptr))
|
||||
{
|
||||
printf("Warning: deferred startup thread could not be started, running inline\n");
|
||||
ThreadDeferredStartup(NULL);
|
||||
ThreadDeferredStartup(nullptr);
|
||||
}
|
||||
StartupPerfLog("start_services", GetTimeMillis() - nStart);
|
||||
|
||||
// ********************************************************* Step 11.5: ZMQ notifications
|
||||
#ifdef ENABLE_ZMQ
|
||||
{
|
||||
std::string zmqAddr = GetArg("-zmqpubhashblock", "");
|
||||
std::string zmqAddr = GetArg(std::string_view{"-zmqpubhashblock"}, std::string_view{""});
|
||||
if (zmqAddr.empty())
|
||||
zmqAddr = GetArg("-zmqpubhashtx", "");
|
||||
zmqAddr = GetArg(std::string_view{"-zmqpubhashtx"}, std::string_view{""});
|
||||
if (zmqAddr.empty())
|
||||
zmqAddr = GetArg("-zmqpub", "");
|
||||
zmqAddr = GetArg(std::string_view{"-zmqpub"}, std::string_view{""});
|
||||
if (!zmqAddr.empty())
|
||||
{
|
||||
pzmqNotifier = new CZMQPublishNotifier();
|
||||
@@ -1543,7 +1552,7 @@ bool AppInit2()
|
||||
{
|
||||
printf("ZMQ: Failed to initialize publisher on %s\n", zmqAddr.c_str());
|
||||
delete pzmqNotifier;
|
||||
pzmqNotifier = NULL;
|
||||
pzmqNotifier = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -7,8 +7,9 @@
|
||||
|
||||
#include "wallet.h"
|
||||
#include "tor_embed_hooks.h"
|
||||
#include <memory>
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
extern std::unique_ptr<CWallet> pwalletMain;
|
||||
extern std::string strWalletFileName;
|
||||
void StartShutdown();
|
||||
bool ShutdownRequested();
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ extern unsigned int nTargetSpacing;
|
||||
// Set to 20-minute for production network
|
||||
//unsigned int nModifierInterval = MODIFIER_INTERVAL;
|
||||
|
||||
typedef std::map<int, unsigned int> MapModifierCheckpoints;
|
||||
using MapModifierCheckpoints = std::map<int, unsigned int>;
|
||||
|
||||
// Hard checkpoints of stake modifiers to ensure they are deterministic
|
||||
static std::map<int, unsigned int> mapStakeModifierCheckpoints = {
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
CPubKey() { }
|
||||
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
|
||||
friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
|
||||
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
|
||||
friend bool operator!=(const CPubKey &a, const CPubKey &b) = default;
|
||||
friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
|
||||
|
||||
IMPLEMENT_SERIALIZE(
|
||||
@@ -99,9 +99,8 @@ public:
|
||||
|
||||
// secure_allocator is defined in allocators.h
|
||||
// CPrivKey is a serialized private key, with all parameters included (279 bytes)
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
|
||||
// CSecret is a serialization of just the secret parameter (32 bytes)
|
||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
|
||||
using CPrivKey = std::vector<unsigned char, secure_allocator<unsigned char>>;
|
||||
using CSecret = std::vector<unsigned char, secure_allocator<unsigned char>>;
|
||||
|
||||
/** An encapsulated secp256k1 elliptic-curve key (public and/or private). */
|
||||
class CKey
|
||||
|
||||
+14
-18
@@ -50,10 +50,9 @@ bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
ScriptMap::const_iterator mi = mapScripts.find(hash);
|
||||
if (mi != mapScripts.end())
|
||||
if (auto mi = mapScripts.find(hash); mi != mapScripts.end())
|
||||
{
|
||||
redeemScriptOut = (*mi).second;
|
||||
redeemScriptOut = mi->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -94,20 +93,19 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||
if (!SetCrypted())
|
||||
return false;
|
||||
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||
for (; mi != mapCryptedKeys.end(); ++mi)
|
||||
for (const auto& [pubKeyHash, val] : mapCryptedKeys)
|
||||
{
|
||||
const CPubKey &vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||
const CPubKey &vchPubKey = val.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = val.second;
|
||||
CSecret vchSecret;
|
||||
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||
return false;
|
||||
if (vchSecret.size() != 32)
|
||||
return false;
|
||||
CKey key;
|
||||
key.SetPubKey(vchPubKey);
|
||||
key.SetSecret(vchSecret);
|
||||
if (key.GetPubKey() == vchPubKey)
|
||||
CKey decryptedKey;
|
||||
decryptedKey.SetPubKey(vchPubKey);
|
||||
decryptedKey.SetSecret(vchSecret);
|
||||
if (decryptedKey.GetPubKey() == vchPubKey)
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
@@ -159,11 +157,10 @@ bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
|
||||
if (!IsCrypted())
|
||||
return CBasicKeyStore::GetKey(address, keyOut);
|
||||
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||
if (mi != mapCryptedKeys.end())
|
||||
if (auto mi = mapCryptedKeys.find(address); mi != mapCryptedKeys.end())
|
||||
{
|
||||
const CPubKey &vchPubKey = (*mi).second.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
|
||||
const CPubKey &vchPubKey = mi->second.first;
|
||||
const std::vector<unsigned char> &vchCryptedSecret = mi->second.second;
|
||||
CSecret vchSecret;
|
||||
if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
|
||||
return false;
|
||||
@@ -184,10 +181,9 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
|
||||
if (!IsCrypted())
|
||||
return CKeyStore::GetPubKey(address, vchPubKeyOut);
|
||||
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
|
||||
if (mi != mapCryptedKeys.end())
|
||||
if (auto mi = mapCryptedKeys.find(address); mi != mapCryptedKeys.end())
|
||||
{
|
||||
vchPubKeyOut = (*mi).second.first;
|
||||
vchPubKeyOut = mi->second.first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-14
@@ -44,8 +44,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
|
||||
typedef std::map<CScriptID, CScript > ScriptMap;
|
||||
using KeyMap = std::map<CKeyID, std::pair<CSecret, bool>>;
|
||||
using ScriptMap = std::map<CScriptID, CScript>;
|
||||
|
||||
/** Basic key store, that keeps keys in an address->secret map */
|
||||
class CBasicKeyStore : public CKeyStore
|
||||
@@ -70,11 +70,9 @@ public:
|
||||
setAddress.clear();
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
KeyMap::const_iterator mi = mapKeys.begin();
|
||||
while (mi != mapKeys.end())
|
||||
for (const auto& [key, val] : mapKeys)
|
||||
{
|
||||
setAddress.insert((*mi).first);
|
||||
mi++;
|
||||
setAddress.insert(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,11 +80,10 @@ public:
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
KeyMap::const_iterator mi = mapKeys.find(address);
|
||||
if (mi != mapKeys.end())
|
||||
if (auto mi = mapKeys.find(address); mi != mapKeys.end())
|
||||
{
|
||||
keyOut.Reset();
|
||||
keyOut.SetSecret((*mi).second.first, (*mi).second.second);
|
||||
keyOut.SetSecret(mi->second.first, mi->second.second);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +94,7 @@ public:
|
||||
virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
|
||||
};
|
||||
|
||||
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||
using CryptedKeyMap = std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char>>>;
|
||||
|
||||
/** Keystore which keeps the private keys encrypted.
|
||||
* It derives from the basic key store, which is used if no encryption is active.
|
||||
@@ -160,17 +157,16 @@ public:
|
||||
bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
|
||||
void GetKeys(std::set<CKeyID> &setAddress) const
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
if (!IsCrypted())
|
||||
{
|
||||
CBasicKeyStore::GetKeys(setAddress);
|
||||
return;
|
||||
}
|
||||
setAddress.clear();
|
||||
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
|
||||
while (mi != mapCryptedKeys.end())
|
||||
for (const auto& [key, val] : mapCryptedKeys)
|
||||
{
|
||||
setAddress.insert((*mi).first);
|
||||
mi++;
|
||||
setAddress.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+168
-891
File diff suppressed because it is too large
Load Diff
+75
-103
@@ -15,6 +15,8 @@
|
||||
#include "sigcache.h"
|
||||
|
||||
#include <list>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
class CWallet;
|
||||
class CBlock;
|
||||
@@ -29,29 +31,29 @@ class CRequestTracker;
|
||||
class CNode;
|
||||
class CScriptCheck;
|
||||
|
||||
static const int CUTOFF_POW_BLOCK = 9000;
|
||||
static const int CRAPCHAIN_CUTOFF_BLOCK = 17691; // pre-Pharao (version 4) blockchain until block 17691
|
||||
static const int FORK_HEIGHT_V5 = 17651; // v5 hard fork: decentralization + Tor v3 (next block after last checkpoint)
|
||||
static const int FORK_HEIGHT_V5_4 = 2186941; // v5.4: tighter timestamps, deterministic fork resolution
|
||||
constexpr int CUTOFF_POW_BLOCK = 9000;
|
||||
constexpr int CRAPCHAIN_CUTOFF_BLOCK = 17691; // pre-Pharao (version 4) blockchain until block 17691
|
||||
constexpr int FORK_HEIGHT_V5 = 17651; // v5 hard fork: decentralization + Tor v3 (next block after last checkpoint)
|
||||
constexpr int FORK_HEIGHT_V5_4 = 2186941; // v5.4: tighter timestamps, deterministic fork resolution
|
||||
|
||||
static const unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
|
||||
static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
|
||||
static const unsigned int MAX_ORPHAN_BLOCKS = 750;
|
||||
static const unsigned int MAX_ORPHAN_BLOCKS_IBD = 1500;
|
||||
static const unsigned int MAX_REORG_DEPTH = 100; // reject reorgs deeper than this (finality)
|
||||
static const unsigned int MAX_INV_SZ = 50000;
|
||||
static const int64_t MIN_TX_FEE = (1 * CENT) / 100;
|
||||
static const int64_t MIN_RELAY_TX_FEE = (1 * CENT) / 100;
|
||||
static const int64_t MAX_MONEY = 2222222 * COIN;
|
||||
static const int64_t COIN_YEAR_REWARD = 33 * CENT; // 33% per year
|
||||
static const int64_t MAX_TRI_PROOF_OF_STAKE = 0.33 * COIN;
|
||||
static const int MODIFIER_INTERVAL_SWITCH = 1;
|
||||
constexpr unsigned int MAX_BLOCK_SIZE = 1000000;
|
||||
constexpr unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2;
|
||||
constexpr unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;
|
||||
constexpr unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100;
|
||||
constexpr unsigned int MAX_ORPHAN_BLOCKS = 750;
|
||||
constexpr unsigned int MAX_ORPHAN_BLOCKS_IBD = 1500;
|
||||
constexpr unsigned int MAX_REORG_DEPTH = 100; // reject reorgs deeper than this (finality)
|
||||
constexpr unsigned int MAX_INV_SZ = 50000;
|
||||
constexpr int64_t MIN_TX_FEE = (1 * CENT) / 100;
|
||||
constexpr int64_t MIN_RELAY_TX_FEE = (1 * CENT) / 100;
|
||||
constexpr int64_t MAX_MONEY = 2222222 * COIN;
|
||||
constexpr int64_t COIN_YEAR_REWARD = 33 * CENT; // 33% per year
|
||||
constexpr int64_t MAX_TRI_PROOF_OF_STAKE = 0.33 * COIN;
|
||||
constexpr int MODIFIER_INTERVAL_SWITCH = 1;
|
||||
|
||||
inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
|
||||
// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
|
||||
static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
|
||||
constexpr unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
|
||||
|
||||
#ifdef USE_UPNP
|
||||
static const int fHaveUPnP = true;
|
||||
@@ -95,7 +97,7 @@ extern int64_t nTimeBestReceived;
|
||||
extern CCriticalSection cs_setpwalletRegistered;
|
||||
extern std::set<CWallet*> setpwalletRegistered;
|
||||
extern unsigned char pchMessageStart[4];
|
||||
extern std::map<uint256, CBlock*> mapOrphanBlocks;
|
||||
extern std::map<uint256, std::unique_ptr<CBlock>> mapOrphanBlocks;
|
||||
|
||||
// Settings
|
||||
extern int64_t nTransactionFee;
|
||||
@@ -107,7 +109,7 @@ extern unsigned int nDerivationMethodIndex;
|
||||
extern bool fEnforceCanonical;
|
||||
|
||||
// Minimum disk space required - used in CheckDiskSpace()
|
||||
static const uint64_t nMinDiskSpace = 52428800;
|
||||
constexpr uint64_t nMinDiskSpace = 52428800;
|
||||
|
||||
class CReserveKey;
|
||||
class CTxDBBase;
|
||||
@@ -115,7 +117,7 @@ class CTxIndex;
|
||||
|
||||
void RegisterWallet(CWallet* pwalletIn);
|
||||
void UnregisterWallet(CWallet* pwalletIn);
|
||||
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false, bool fConnect = true);
|
||||
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = nullptr, bool fUpdate = false, bool fConnect = true);
|
||||
bool ProcessBlock(CNode* pfrom, CBlock* pblock);
|
||||
bool CheckDiskSpace(uint64_t nAdditionalBytes=0);
|
||||
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
||||
@@ -135,7 +137,7 @@ int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees);
|
||||
unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
|
||||
unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime);
|
||||
int GetNumBlocksOfPeers();
|
||||
bool IsInitialBlockDownload();
|
||||
[[nodiscard]] bool IsInitialBlockDownload();
|
||||
std::string GetWarnings(std::string strFor);
|
||||
bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock);
|
||||
uint256 WantedByOrphan(const CBlock* pblockOrphan);
|
||||
@@ -186,10 +188,7 @@ public:
|
||||
a.nTxPos == b.nTxPos);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) = default;
|
||||
|
||||
|
||||
std::string ToString() const
|
||||
@@ -217,8 +216,8 @@ public:
|
||||
|
||||
CInPoint() { SetNull(); }
|
||||
CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
|
||||
void SetNull() { ptx = NULL; n = (unsigned int) -1; }
|
||||
bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); }
|
||||
void SetNull() { ptx = nullptr; n = (unsigned int) -1; }
|
||||
bool IsNull() const { return (ptx == nullptr && n == (unsigned int) -1); }
|
||||
};
|
||||
|
||||
|
||||
@@ -246,10 +245,7 @@ public:
|
||||
return (a.hash == b.hash && a.n == b.n);
|
||||
}
|
||||
|
||||
friend bool operator!=(const COutPoint& a, const COutPoint& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
friend bool operator!=(const COutPoint& a, const COutPoint& b) = default;
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
@@ -314,10 +310,7 @@ public:
|
||||
a.nSequence == b.nSequence);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CTxIn& a, const CTxIn& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
friend bool operator!=(const CTxIn& a, const CTxIn& b) = default;
|
||||
|
||||
std::string ToStringShort() const
|
||||
{
|
||||
@@ -407,10 +400,7 @@ public:
|
||||
a.scriptPubKey == b.scriptPubKey);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CTxOut& a, const CTxOut& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
friend bool operator!=(const CTxOut& a, const CTxOut& b) = default;
|
||||
|
||||
std::string ToStringShort() const
|
||||
{
|
||||
@@ -434,11 +424,11 @@ public:
|
||||
|
||||
|
||||
|
||||
enum GetMinFee_mode
|
||||
enum class GetMinFeeMode : int
|
||||
{
|
||||
GMF_BLOCK,
|
||||
GMF_RELAY,
|
||||
GMF_SEND,
|
||||
Block,
|
||||
Relay,
|
||||
Send,
|
||||
};
|
||||
|
||||
/** A single unspent transaction output entry in the UTXO database.
|
||||
@@ -485,7 +475,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<COutPoint, CUtxoEntry> MapPrevTx;
|
||||
using MapPrevTx = std::map<COutPoint, CUtxoEntry>;
|
||||
|
||||
/** The basic transaction that is broadcasted on the network and contained in
|
||||
* blocks. A transaction can contain multiple inputs and outputs.
|
||||
@@ -599,7 +589,7 @@ public:
|
||||
/** Check for standard transaction types
|
||||
@return True if all outputs (scriptPubKeys) use only standard transaction forms
|
||||
*/
|
||||
bool IsStandard() const;
|
||||
[[nodiscard]] bool IsStandard() const;
|
||||
|
||||
/** Check for standard transaction types
|
||||
@param[in] mapInputs Map of previous transactions that have outputs we're spending
|
||||
@@ -647,9 +637,9 @@ public:
|
||||
*/
|
||||
int64_t GetValueIn(const MapPrevTx& mapInputs) const;
|
||||
|
||||
int64_t GetMinFee(unsigned int nBlockSize=1, enum GetMinFee_mode mode=GMF_BLOCK, unsigned int nBytes = 0) const;
|
||||
int64_t GetMinFee(unsigned int nBlockSize=1, GetMinFeeMode mode=GetMinFeeMode::Block, unsigned int nBytes = 0) const;
|
||||
|
||||
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL)
|
||||
bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=nullptr)
|
||||
{
|
||||
CAutoFile filein = CAutoFile(OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"), SER_DISK, CLIENT_VERSION);
|
||||
if (!filein)
|
||||
@@ -685,10 +675,7 @@ public:
|
||||
a.nLockTime == b.nLockTime);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CTransaction& a, const CTransaction& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
friend bool operator!=(const CTransaction& a, const CTransaction& b) = default;
|
||||
|
||||
std::string ToStringShort() const
|
||||
{
|
||||
@@ -708,10 +695,10 @@ public:
|
||||
vin.size(),
|
||||
vout.size(),
|
||||
nLockTime);
|
||||
for (unsigned int i = 0; i < vin.size(); i++)
|
||||
str += " " + vin[i].ToString() + "\n";
|
||||
for (unsigned int i = 0; i < vout.size(); i++)
|
||||
str += " " + vout[i].ToString() + "\n";
|
||||
for (const CTxIn& txin : vin)
|
||||
str += " " + txin.ToString() + "\n";
|
||||
for (const CTxOut& txout : vout)
|
||||
str += " " + txout.ToString() + "\n";
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -747,12 +734,12 @@ public:
|
||||
@param[in] fMiner true if called from CreateNewBlock
|
||||
@return Returns true if all checks succeed
|
||||
*/
|
||||
bool ConnectInputs(CTxDBBase& txdb, const MapPrevTx& inputs,
|
||||
[[nodiscard]] bool ConnectInputs(CTxDBBase& txdb, const MapPrevTx& inputs,
|
||||
const CBlockIndex* pindexBlock, bool fBlock, bool fMiner,
|
||||
std::vector<CScriptCheck>* pvChecks = NULL);
|
||||
std::vector<CScriptCheck>* pvChecks = nullptr);
|
||||
bool ClientConnectInputs();
|
||||
bool CheckTransaction() const;
|
||||
bool AcceptToMemoryPool(CTxDBBase& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL);
|
||||
[[nodiscard]] bool CheckTransaction() const;
|
||||
[[nodiscard]] bool AcceptToMemoryPool(CTxDBBase& txdb, bool fCheckInputs=true, bool* pfMissingInputs=nullptr);
|
||||
bool GetCoinAge(CTxDBBase& txdb, uint64_t& nCoinAge) const; // triangles: get transaction coin age
|
||||
|
||||
protected:
|
||||
@@ -805,7 +792,7 @@ public:
|
||||
)
|
||||
|
||||
|
||||
int SetMerkleBranch(const CBlock* pblock=NULL);
|
||||
int SetMerkleBranch(const CBlock* pblock=nullptr);
|
||||
|
||||
// Return depth of transaction in blockchain:
|
||||
// -1 : not in blockchain, and not in memory pool (conflicted transaction)
|
||||
@@ -869,10 +856,7 @@ public:
|
||||
a.vSpent == b.vSpent);
|
||||
}
|
||||
|
||||
friend bool operator!=(const CTxIndex& a, const CTxIndex& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
friend bool operator!=(const CTxIndex& a, const CTxIndex& b) = default;
|
||||
int GetDepthInMainChain() const;
|
||||
|
||||
};
|
||||
@@ -957,6 +941,7 @@ public:
|
||||
vMerkleTree.clear();
|
||||
nDoS = 0;
|
||||
fCachedHash = false;
|
||||
fMerkleTreeCached = false;
|
||||
}
|
||||
|
||||
bool IsNull() const
|
||||
@@ -966,6 +951,7 @@ public:
|
||||
|
||||
mutable uint256 cachedHash;
|
||||
mutable bool fCachedHash;
|
||||
mutable bool fMerkleTreeCached;
|
||||
|
||||
uint256 GetHash() const
|
||||
{
|
||||
@@ -1007,7 +993,7 @@ public:
|
||||
|
||||
std::pair<COutPoint, unsigned int> GetProofOfStake() const
|
||||
{
|
||||
return IsProofOfStake()? std::make_pair(vtx[1].vin[0].prevout, vtx[1].nTime) : std::make_pair(COutPoint(), (unsigned int)0);
|
||||
return IsProofOfStake()? std::pair{vtx[1].vin[0].prevout, vtx[1].nTime} : std::pair{COutPoint(), (unsigned int)0};
|
||||
}
|
||||
|
||||
// triangles: get max transaction timestamp
|
||||
@@ -1021,6 +1007,9 @@ public:
|
||||
|
||||
uint256 BuildMerkleTree() const
|
||||
{
|
||||
if (fMerkleTreeCached)
|
||||
return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
|
||||
|
||||
vMerkleTree.clear();
|
||||
for (const CTransaction& tx : vtx)
|
||||
vMerkleTree.push_back(tx.GetHash());
|
||||
@@ -1035,6 +1024,7 @@ public:
|
||||
}
|
||||
j += nSize;
|
||||
}
|
||||
fMerkleTreeCached = true;
|
||||
return (vMerkleTree.empty() ? 0 : vMerkleTree.back());
|
||||
}
|
||||
|
||||
@@ -1134,25 +1124,25 @@ public:
|
||||
nTime, nBits, nNonce,
|
||||
vtx.size(),
|
||||
HexStr(vchBlockSig.begin(), vchBlockSig.end()).c_str());
|
||||
for (unsigned int i = 0; i < vtx.size(); i++)
|
||||
for (const CTransaction& tx : vtx)
|
||||
{
|
||||
printf(" ");
|
||||
vtx[i].print();
|
||||
tx.print();
|
||||
}
|
||||
printf(" vMerkleTree: ");
|
||||
for (unsigned int i = 0; i < vMerkleTree.size(); i++)
|
||||
printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
|
||||
for (const uint256& merkle : vMerkleTree)
|
||||
printf("%s ", merkle.ToString().substr(0,10).c_str());
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
bool DisconnectBlock(CTxDBBase& txdb, CBlockIndex* pindex);
|
||||
bool ConnectBlock(CTxDBBase& txdb, CBlockIndex* pindex, bool fJustCheck=false);
|
||||
[[nodiscard]] bool ConnectBlock(CTxDBBase& txdb, CBlockIndex* pindex, bool fJustCheck=false);
|
||||
bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true);
|
||||
bool SetBestChain(CTxDBBase& txdb, CBlockIndex* pindexNew);
|
||||
bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos, const uint256& hashProofOfStake);
|
||||
bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true, bool fCheckSig=true) const;
|
||||
bool AcceptBlock();
|
||||
[[nodiscard]] bool AcceptBlock();
|
||||
bool GetCoinAge(uint64_t& nCoinAge) const; // triangles: calculate total coin age spent in block
|
||||
bool SignBlock(CWallet& keystore, int64_t nFees);
|
||||
bool CheckBlockSignature() const;
|
||||
@@ -1212,9 +1202,9 @@ public:
|
||||
|
||||
CBlockIndex()
|
||||
{
|
||||
phashBlock = NULL;
|
||||
pprev = NULL;
|
||||
pnext = NULL;
|
||||
phashBlock = nullptr;
|
||||
pprev = nullptr;
|
||||
pnext = nullptr;
|
||||
nFile = 0;
|
||||
nBlockPos = 0;
|
||||
nHeight = 0;
|
||||
@@ -1235,32 +1225,16 @@ public:
|
||||
nNonce = 0;
|
||||
}
|
||||
|
||||
CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block)
|
||||
CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) : CBlockIndex()
|
||||
{
|
||||
phashBlock = NULL;
|
||||
pprev = NULL;
|
||||
pnext = NULL;
|
||||
nFile = nFileIn;
|
||||
nBlockPos = nBlockPosIn;
|
||||
nHeight = 0;
|
||||
nChainTrust = 0;
|
||||
nMint = 0;
|
||||
nMoneySupply = 0;
|
||||
nFlags = 0;
|
||||
nStakeModifier = 0;
|
||||
nStakeModifierChecksum = 0;
|
||||
hashProofOfStake = 0;
|
||||
if (block.IsProofOfStake())
|
||||
{
|
||||
SetProofOfStake();
|
||||
prevoutStake = block.vtx[1].vin[0].prevout;
|
||||
nStakeTime = block.vtx[1].nTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevoutStake.SetNull();
|
||||
nStakeTime = 0;
|
||||
}
|
||||
|
||||
nVersion = block.nVersion;
|
||||
hashMerkleRoot = block.hashMerkleRoot;
|
||||
@@ -1313,9 +1287,9 @@ public:
|
||||
|
||||
int64_t GetMedianTimePast() const
|
||||
{
|
||||
int64_t pmedian[nMedianTimeSpan];
|
||||
int64_t* pbegin = &pmedian[nMedianTimeSpan];
|
||||
int64_t* pend = &pmedian[nMedianTimeSpan];
|
||||
std::array<int64_t, nMedianTimeSpan> pmedian{};
|
||||
auto pbegin = pmedian.end();
|
||||
auto pend = pmedian.end();
|
||||
|
||||
const CBlockIndex* pindex = this;
|
||||
for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
|
||||
@@ -1541,10 +1515,7 @@ public:
|
||||
Set((*mi).second);
|
||||
}
|
||||
|
||||
CBlockLocator(const std::vector<uint256>& vHaveIn)
|
||||
{
|
||||
vHave = vHaveIn;
|
||||
}
|
||||
CBlockLocator(std::vector<uint256> vHaveIn) : vHave(std::move(vHaveIn)) {}
|
||||
|
||||
IMPLEMENT_SERIALIZE
|
||||
(
|
||||
@@ -1678,6 +1649,7 @@ public:
|
||||
|
||||
bool exists(uint256 hash)
|
||||
{
|
||||
LOCK(cs);
|
||||
return (mapTx.count(hash) != 0);
|
||||
}
|
||||
|
||||
@@ -1744,7 +1716,7 @@ public:
|
||||
{
|
||||
if (i <= 1) {
|
||||
// Always prefill coinbase (idx 0) and coinstake (idx 1)
|
||||
vPrefilledTxn.push_back(std::make_pair(i, block.vtx[i]));
|
||||
vPrefilledTxn.push_back({i, block.vtx[i]});
|
||||
} else {
|
||||
vShortTxIds.push_back(GetShortTxId(block.vtx[i].GetHash(), nShortIdNonce));
|
||||
}
|
||||
@@ -1818,7 +1790,7 @@ private:
|
||||
int nHashType;
|
||||
|
||||
public:
|
||||
CScriptCheck() : ptxTo(NULL), nIn(0), nHashType(0) {}
|
||||
CScriptCheck() : ptxTo(nullptr), nIn(0), nHashType(0) {}
|
||||
|
||||
CScriptCheck(const CScript& scriptPubKeyIn, const CScript& scriptSigIn,
|
||||
const CTransaction& txToIn, unsigned int nInIn, int nHashTypeIn)
|
||||
@@ -1845,6 +1817,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
extern CCheckQueue<CScriptCheck>* pScriptCheckQueue;
|
||||
extern std::unique_ptr<CCheckQueue<CScriptCheck>> pScriptCheckQueue;
|
||||
|
||||
#endif
|
||||
|
||||
+7
-8
@@ -50,7 +50,7 @@ uint64_t nLastBlockSize = 0;
|
||||
int64_t nLastCoinStakeSearchInterval = 0;
|
||||
|
||||
// We want to sort transactions by priority and fee, so:
|
||||
typedef std::tuple<double, double, CTransaction*> TxPriority;
|
||||
using TxPriority = std::tuple<double, double, CTransaction*>;
|
||||
class TxPriorityCompare
|
||||
{
|
||||
bool byFee;
|
||||
@@ -79,7 +79,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
// Create new block
|
||||
unique_ptr<CBlock> pblock(new CBlock());
|
||||
if (!pblock.get())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
CBlockIndex* pindexPrev = pindexBest;
|
||||
|
||||
@@ -145,13 +145,12 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
// This vector will be sorted into a priority queue:
|
||||
vector<TxPriority> vecPriority;
|
||||
vecPriority.reserve(mempool.mapTx.size());
|
||||
for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
|
||||
for (auto& [hash, tx] : mempool.mapTx)
|
||||
{
|
||||
CTransaction& tx = (*mi).second;
|
||||
if (tx.IsCoinBase() || tx.IsCoinStake() || !tx.IsFinal())
|
||||
continue;
|
||||
|
||||
COrphan* porphan = NULL;
|
||||
COrphan* porphan = nullptr;
|
||||
double dPriority = 0;
|
||||
int64_t nTotalIn = 0;
|
||||
bool fMissingInputs = false;
|
||||
@@ -210,7 +209,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
porphan->dFeePerKb = dFeePerKb;
|
||||
}
|
||||
else
|
||||
vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &(*mi).second));
|
||||
vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &tx));
|
||||
}
|
||||
|
||||
// Collect transactions into block
|
||||
@@ -247,7 +246,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake, int64_t* pFees)
|
||||
continue;
|
||||
|
||||
// Transaction fee
|
||||
int64_t nMinFee = tx.GetMinFee(nBlockSize, GMF_BLOCK);
|
||||
int64_t nMinFee = tx.GetMinFee(nBlockSize, GetMinFeeMode::Block);
|
||||
|
||||
// Skip free transactions if we're past the minimum block size:
|
||||
if (fSortedByFee && (dFeePerKb < nMinTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
|
||||
@@ -372,7 +371,7 @@ bool CheckStake(CBlock* pblock, CWallet& wallet)
|
||||
}
|
||||
|
||||
// Process this block the same as if we had received it from another node
|
||||
if (!ProcessBlock(NULL, pblock))
|
||||
if (!ProcessBlock(nullptr, pblock))
|
||||
return error("CheckStake() : ProcessBlock, block not accepted");
|
||||
}
|
||||
|
||||
|
||||
+44
-44
@@ -47,7 +47,7 @@ void ThreadMapPort2(void* parg);
|
||||
#endif
|
||||
void ThreadHTTPSeedFetch(void* parg);
|
||||
bool ThreadHTTPSeedFetch2(void* parg);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
|
||||
bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false);
|
||||
|
||||
|
||||
struct LocalServiceInfo {
|
||||
@@ -59,7 +59,7 @@ struct LocalServiceInfo {
|
||||
// Global state variables
|
||||
//
|
||||
bool fClient = false;
|
||||
//bool fDiscover = true;
|
||||
|
||||
|
||||
#ifdef USE_UPNP
|
||||
bool fUseUPnP = GetBoolArg("-upnp", USE_UPNP);
|
||||
@@ -71,10 +71,10 @@ static CCriticalSection cs_mapLocalHost;
|
||||
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
|
||||
static bool vfReachable[NET_MAX] = {};
|
||||
static bool vfLimited[NET_MAX] = {};
|
||||
static CNode* pnodeLocalHost = NULL;
|
||||
static CNode* pnodeLocalHost = nullptr;
|
||||
CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices);
|
||||
uint64_t nLocalHostNonce = 0;
|
||||
boost::array<int, THREAD_MAX> vnThreadsRunning;
|
||||
std::array<int, THREAD_MAX> vnThreadsRunning;
|
||||
static std::vector<SOCKET> vhListenSocket;
|
||||
CAddrMan addrman;
|
||||
|
||||
@@ -91,7 +91,7 @@ CCriticalSection cs_vOneShots;
|
||||
set<CNetAddr> setservAddNodeAddresses;
|
||||
CCriticalSection cs_setservAddNodeAddresses;
|
||||
|
||||
static CSemaphore *semOutbound = NULL;
|
||||
static CSemaphore *semOutbound = nullptr;
|
||||
|
||||
void AddOneShot(string strDest)
|
||||
{
|
||||
@@ -347,7 +347,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
|
||||
closesocket(hSocket);
|
||||
return false;
|
||||
}
|
||||
if (pszKeyword == NULL)
|
||||
if (pszKeyword == nullptr)
|
||||
break;
|
||||
if (strLine.find(pszKeyword) != string::npos)
|
||||
{
|
||||
@@ -423,7 +423,7 @@ bool GetMyExternalIP(CNetAddr& ipRet)
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
pszKeyword = NULL; // Returns just IP address
|
||||
pszKeyword = nullptr; // Returns just IP address
|
||||
}
|
||||
|
||||
if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
|
||||
@@ -469,7 +469,7 @@ CNode* FindNode(const CNetAddr& ip)
|
||||
if ((CNetAddr)pnode->addr == ip)
|
||||
return (pnode);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CNode* FindNode(std::string addrName)
|
||||
@@ -478,7 +478,7 @@ CNode* FindNode(std::string addrName)
|
||||
for (CNode* pnode : vNodes)
|
||||
if (pnode->addrName == addrName)
|
||||
return (pnode);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CNode* FindNode(const CService& addr)
|
||||
@@ -489,7 +489,7 @@ CNode* FindNode(const CService& addr)
|
||||
if ((CService)pnode->addr == addr)
|
||||
return (pnode);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
@@ -499,12 +499,12 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
if (addrStr.find(".onion") == std::string::npos) {
|
||||
if (fDebug)
|
||||
printf("ConnectNode(): REJECTED non-onion address: %s (Tor-native mode)\n", addrStr.c_str());
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (pszDest == NULL) {
|
||||
if (pszDest == nullptr) {
|
||||
if (IsLocal(addrConnect))
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
// Look for an existing connection
|
||||
CNode* pnode = FindNode((CService)addrConnect);
|
||||
@@ -557,7 +557,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1042,7 +1042,7 @@ void ThreadSocketHandler2(void* parg)
|
||||
bool fIsSeed = false;
|
||||
static const char *(*strOnionSeedCheck)[1] = fTestNet ? strTestNetOnionSeed : strMainNetOnionSeed;
|
||||
std::string incomingAddr = addr.ToStringIP();
|
||||
for (unsigned int si = 0; strOnionSeedCheck[si][0] != NULL; si++) {
|
||||
for (unsigned int si = 0; strOnionSeedCheck[si][0] != nullptr; si++) {
|
||||
if (incomingAddr.find(strOnionSeedCheck[si][0]) != std::string::npos) {
|
||||
fIsSeed = true;
|
||||
break;
|
||||
@@ -1204,7 +1204,7 @@ void ThreadMapPort(void* parg)
|
||||
PrintException(&e, "ThreadMapPort()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[THREAD_UPNP]--;
|
||||
PrintException(NULL, "ThreadMapPort()");
|
||||
PrintException(nullptr, "ThreadMapPort()");
|
||||
}
|
||||
printf("ThreadMapPort exited\n");
|
||||
}
|
||||
@@ -1325,7 +1325,7 @@ void MapPort()
|
||||
printf("MapPort()...\n");
|
||||
if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
|
||||
{
|
||||
if (!NewThread(ThreadMapPort, NULL))
|
||||
if (!NewThread(ThreadMapPort, nullptr))
|
||||
printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
|
||||
}
|
||||
}
|
||||
@@ -1403,7 +1403,7 @@ void ThreadOnionSeed(void* parg)
|
||||
static const char *(*strOnionSeed)[1] = fTestNet ? strTestNetOnionSeed : strMainNetOnionSeed;
|
||||
int found = 0;
|
||||
|
||||
for (unsigned int seed_idx = 0; strOnionSeed[seed_idx][0] != NULL; seed_idx++) {
|
||||
for (unsigned int seed_idx = 0; strOnionSeed[seed_idx][0] != nullptr; seed_idx++) {
|
||||
CNetAddr parsed;
|
||||
if (!parsed.SetSpecial(strOnionSeed[seed_idx][0]))
|
||||
throw runtime_error("ThreadOnionSeed() : invalid .onion seed");
|
||||
@@ -1441,7 +1441,7 @@ void ThreadOnionSeed(void* parg)
|
||||
MilliSleep(1000);
|
||||
}
|
||||
if (!fShutdown)
|
||||
ok = ThreadHTTPSeedFetch2(NULL);
|
||||
ok = ThreadHTTPSeedFetch2(nullptr);
|
||||
}
|
||||
if (!ok && !fShutdown)
|
||||
printf("ThreadOnionSeed: all HTTPS seed fetch attempts failed\n");
|
||||
@@ -1499,10 +1499,10 @@ void ThreadOnionSeed(void* parg)
|
||||
else
|
||||
printf("ThreadOnionSeed: low outbound peers (%d), re-seeding...\n", nOutbound);
|
||||
|
||||
ThreadHTTPSeedFetch2(NULL);
|
||||
ThreadHTTPSeedFetch2(nullptr);
|
||||
|
||||
// Re-queue hardcoded seeds for direct connection
|
||||
for (unsigned int seed_idx = 0; strOnionSeed[seed_idx][0] != NULL; seed_idx++) {
|
||||
for (unsigned int seed_idx = 0; strOnionSeed[seed_idx][0] != nullptr; seed_idx++) {
|
||||
std::string oneShotAddr = std::string(strOnionSeed[seed_idx][0])
|
||||
+ ":" + std::to_string(GetDefaultPort());
|
||||
AddOneShot(oneShotAddr);
|
||||
@@ -1587,8 +1587,8 @@ bool ThreadHTTPSeedFetch2(void* parg)
|
||||
|
||||
printf("Fetching seed list from https://%s%s (via Tor)...\n", seedHost.c_str(), seedPath.c_str());
|
||||
|
||||
SSL_CTX* ctx = NULL;
|
||||
SSL* ssl = NULL;
|
||||
SSL_CTX* ctx = nullptr;
|
||||
SSL* ssl = nullptr;
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
|
||||
try {
|
||||
@@ -1611,7 +1611,7 @@ bool ThreadHTTPSeedFetch2(void* parg)
|
||||
|
||||
// Use system default CA certificates for verification
|
||||
SSL_CTX_set_default_verify_paths(ctx);
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, nullptr);
|
||||
|
||||
ssl = SSL_new(ctx);
|
||||
if (!ssl) {
|
||||
@@ -1677,8 +1677,8 @@ bool ThreadHTTPSeedFetch2(void* parg)
|
||||
SSL_free(ssl);
|
||||
SSL_CTX_free(ctx);
|
||||
closesocket(hSocket);
|
||||
ssl = NULL;
|
||||
ctx = NULL;
|
||||
ssl = nullptr;
|
||||
ctx = nullptr;
|
||||
hSocket = INVALID_SOCKET;
|
||||
|
||||
if (response.empty()) {
|
||||
@@ -1785,7 +1785,7 @@ void ThreadHTTPSeedFetch(void* parg)
|
||||
PrintException(&e, "ThreadHTTPSeedFetch()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[THREAD_HTTPSEED]--;
|
||||
PrintException(NULL, "ThreadHTTPSeedFetch()");
|
||||
PrintException(nullptr, "ThreadHTTPSeedFetch()");
|
||||
}
|
||||
printf("ThreadHTTPSeedFetch exited\n");
|
||||
}
|
||||
@@ -1806,7 +1806,7 @@ void ThreadOpenConnections(void* parg)
|
||||
PrintException(&e, "ThreadOpenConnections()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
|
||||
PrintException(NULL, "ThreadOpenConnections()");
|
||||
PrintException(nullptr, "ThreadOpenConnections()");
|
||||
}
|
||||
printf("ThreadOpenConnections exited\n");
|
||||
}
|
||||
@@ -1880,7 +1880,7 @@ void ThreadOpenConnections2(void* parg)
|
||||
for (string strAddr : mapMultiArgs["-connect"])
|
||||
{
|
||||
CAddress addr;
|
||||
OpenNetworkConnection(addr, NULL, strAddr.c_str());
|
||||
OpenNetworkConnection(addr, nullptr, strAddr.c_str());
|
||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||
{
|
||||
MilliSleep(500);
|
||||
@@ -1988,7 +1988,7 @@ void ThreadOpenAddedConnections(void* parg)
|
||||
PrintException(&e, "ThreadOpenAddedConnections()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
|
||||
PrintException(NULL, "ThreadOpenAddedConnections()");
|
||||
PrintException(nullptr, "ThreadOpenAddedConnections()");
|
||||
}
|
||||
printf("ThreadOpenAddedConnections exited\n");
|
||||
}
|
||||
@@ -2120,7 +2120,7 @@ void ThreadMessageHandler(void* parg)
|
||||
PrintException(&e, "ThreadMessageHandler()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
|
||||
PrintException(NULL, "ThreadMessageHandler()");
|
||||
PrintException(nullptr, "ThreadMessageHandler()");
|
||||
}
|
||||
printf("ThreadMessageHandler exited\n");
|
||||
}
|
||||
@@ -2141,7 +2141,7 @@ void ThreadMessageHandler2(void* parg)
|
||||
}
|
||||
|
||||
// Poll the connected nodes for messages
|
||||
CNode* pnodeTrickle = NULL;
|
||||
CNode* pnodeTrickle = nullptr;
|
||||
if (!vNodesCopy.empty())
|
||||
pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
|
||||
for (CNode* pnode : vNodesCopy)
|
||||
@@ -2386,7 +2386,7 @@ void StartNode(void* parg)
|
||||
// Make this thread recognisable as the startup thread
|
||||
RenameThread("Triangles-start");
|
||||
|
||||
if (semOutbound == NULL) {
|
||||
if (semOutbound == nullptr) {
|
||||
// initialize semaphore — use -maxoutbound if specified, else default
|
||||
int nMaxOutbound = (int)GetArg("-maxoutbound", MAX_OUTBOUND_CONNECTIONS);
|
||||
nMaxOutbound = min(nMaxOutbound, (int)GetArg("-maxconnections", 125));
|
||||
@@ -2395,7 +2395,7 @@ void StartNode(void* parg)
|
||||
semOutbound = new CSemaphore(nMaxOutbound);
|
||||
}
|
||||
|
||||
if (pnodeLocalHost == NULL)
|
||||
if (pnodeLocalHost == nullptr)
|
||||
pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
|
||||
|
||||
printf("StartNode(): pnodeLocalHost addr: %s\n",
|
||||
@@ -2411,7 +2411,7 @@ void StartNode(void* parg)
|
||||
if (!GetBoolArg("-onionseed", true))
|
||||
printf(".onion seeding disabled\n");
|
||||
else
|
||||
if (!NewThread(ThreadOnionSeed, NULL))
|
||||
if (!NewThread(ThreadOnionSeed, nullptr))
|
||||
printf("Error: NewThread(ThreadOnionSeed) failed\n");
|
||||
|
||||
// Map ports with UPnP (default)
|
||||
@@ -2424,34 +2424,34 @@ void StartNode(void* parg)
|
||||
printf("HTTP seed fetch handled by onion seed thread\n");
|
||||
else if (GetBoolArg("-noseedurl", false))
|
||||
printf("HTTP seed fetch disabled\n");
|
||||
else if (!NewThread(ThreadHTTPSeedFetch, NULL))
|
||||
else if (!NewThread(ThreadHTTPSeedFetch, nullptr))
|
||||
printf("Error: NewThread(ThreadHTTPSeedFetch) failed\n");
|
||||
|
||||
// Send and receive from sockets, accept connections
|
||||
if (!NewThread(ThreadSocketHandler, NULL))
|
||||
if (!NewThread(ThreadSocketHandler, nullptr))
|
||||
printf("Error: NewThread(ThreadSocketHandler) failed\n");
|
||||
|
||||
// Initiate outbound connections from -addnode
|
||||
if (!NewThread(ThreadOpenAddedConnections, NULL))
|
||||
if (!NewThread(ThreadOpenAddedConnections, nullptr))
|
||||
printf("Error: NewThread(ThreadOpenAddedConnections) failed\n");
|
||||
|
||||
// Initiate outbound connections
|
||||
if (!NewThread(ThreadOpenConnections, NULL))
|
||||
if (!NewThread(ThreadOpenConnections, nullptr))
|
||||
printf("Error: NewThread(ThreadOpenConnections) failed\n");
|
||||
|
||||
// Process messages
|
||||
if (!NewThread(ThreadMessageHandler, NULL))
|
||||
if (!NewThread(ThreadMessageHandler, nullptr))
|
||||
printf("Error: NewThread(ThreadMessageHandler) failed\n");
|
||||
|
||||
// Dump network addresses
|
||||
if (!NewThread(ThreadDumpAddress, NULL))
|
||||
if (!NewThread(ThreadDumpAddress, nullptr))
|
||||
printf("Error; NewThread(ThreadDumpAddress) failed\n");
|
||||
|
||||
// Mine proof-of-stake blocks in the background
|
||||
if (!GetBoolArg("-stake", true))
|
||||
printf("Staking disabled at startup (stake=0).\n");
|
||||
else
|
||||
if (!NewThread(ThreadStakeMiner, pwalletMain))
|
||||
if (!NewThread(ThreadStakeMiner, pwalletMain.get()))
|
||||
printf("Error: NewThread(ThreadStakeMiner) failed\n");
|
||||
}
|
||||
|
||||
@@ -2567,8 +2567,8 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
|
||||
}
|
||||
|
||||
// Save original serialized message so newer versions are preserved
|
||||
mapRelay.insert(std::make_pair(inv, ss));
|
||||
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
|
||||
mapRelay.insert({inv, ss});
|
||||
vRelayExpiration.push_back({GetTime() + 15 * 60, inv});
|
||||
}
|
||||
|
||||
RelayInventory(inv);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define TRIANGLES_NET_H
|
||||
|
||||
#include <deque>
|
||||
#include <boost/array.hpp>
|
||||
#include <array>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#ifndef WIN32
|
||||
@@ -34,7 +34,7 @@ bool GetMyExternalIP(CNetAddr& ipRet);
|
||||
void AddressCurrentlyConnected(const CService& addr);
|
||||
CNode* FindNode(const CNetAddr& ip);
|
||||
CNode* FindNode(const CService& ip);
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL);
|
||||
CNode* ConnectNode(CAddress addrConnect, const char *strDest = nullptr);
|
||||
void MapPort();
|
||||
unsigned short GetListenPort();
|
||||
bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
|
||||
@@ -63,10 +63,10 @@ bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
|
||||
bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
|
||||
bool SeenLocal(const CService& addr);
|
||||
bool IsLocal(const CService& addr);
|
||||
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
|
||||
bool GetLocal(CService &addr, const CNetAddr *paddrPeer = nullptr);
|
||||
bool IsReachable(const CNetAddr &addr);
|
||||
void SetReachable(enum Network net, bool fFlag = true);
|
||||
CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
|
||||
CAddress GetLocalAddress(const CNetAddr *paddrPeer = nullptr);
|
||||
|
||||
|
||||
enum
|
||||
@@ -98,7 +98,7 @@ extern bool fUseUPnP;
|
||||
extern uint64_t nLocalServices;
|
||||
extern uint64_t nLocalHostNonce;
|
||||
extern CAddress addrSeenByPeer;
|
||||
extern boost::array<int, THREAD_MAX> vnThreadsRunning;
|
||||
extern std::array<int, THREAD_MAX> vnThreadsRunning;
|
||||
extern CAddrMan addrman;
|
||||
|
||||
extern std::vector<CNode*> vNodes;
|
||||
@@ -444,7 +444,7 @@ public:
|
||||
nRequestTime = nNow;
|
||||
else
|
||||
nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
|
||||
mapAskFor.insert(std::make_pair(nRequestTime, inv));
|
||||
mapAskFor.insert({nRequestTime, inv});
|
||||
}
|
||||
|
||||
|
||||
@@ -523,141 +523,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
void PushMessage(const char* pszCommand, const T1& a1)
|
||||
template<typename T1, typename... Args>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const Args&... args)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3 << a4;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3 << a4 << a5;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3 << a4 << a5 << a6;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
AbortMessage();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9)
|
||||
{
|
||||
try
|
||||
{
|
||||
BeginMessage(pszCommand);
|
||||
ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
|
||||
using swallow = int[];
|
||||
(void)swallow{0, ((void)(ssSend << args), 0)...};
|
||||
EndMessage();
|
||||
}
|
||||
catch (...)
|
||||
|
||||
+11
-12
@@ -13,7 +13,6 @@
|
||||
#endif
|
||||
|
||||
#include "strlcpy.h"
|
||||
#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -27,7 +26,7 @@ bool fNameLookup = false;
|
||||
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
|
||||
|
||||
enum Network ParseNetwork(std::string net) {
|
||||
boost::to_lower(net);
|
||||
net = ToLower(net);
|
||||
if (net == "ipv4") return NET_IPV4;
|
||||
if (net == "ipv6") return NET_IPV6;
|
||||
if (net == "tor") return NET_TOR;
|
||||
@@ -42,7 +41,7 @@ void SplitHostPort(std::string in, int &portOut, std::string &hostOut) {
|
||||
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)) {
|
||||
char *endp = NULL;
|
||||
char *endp = nullptr;
|
||||
int n = strtol(in.c_str() + colon + 1, &endp, 10);
|
||||
if (endp && *endp == 0 && n >= 0) {
|
||||
in = in.substr(0, colon);
|
||||
@@ -88,13 +87,13 @@ bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsign
|
||||
# endif
|
||||
aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST;
|
||||
#endif
|
||||
struct addrinfo *aiRes = NULL;
|
||||
int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes);
|
||||
struct addrinfo *aiRes = nullptr;
|
||||
int nErr = getaddrinfo(pszName, nullptr, &aiHint, &aiRes);
|
||||
if (nErr)
|
||||
return false;
|
||||
|
||||
struct addrinfo *aiTrav = aiRes;
|
||||
while (aiTrav != NULL && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions))
|
||||
while (aiTrav != nullptr && (nMaxSolutions == 0 || vIP.size() < nMaxSolutions))
|
||||
{
|
||||
if (aiTrav->ai_family == AF_INET)
|
||||
{
|
||||
@@ -384,7 +383,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(hSocket, &fdset);
|
||||
int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
|
||||
int nRet = select(hSocket + 1, nullptr, &fdset, nullptr, &timeout);
|
||||
if (nRet == 0)
|
||||
{
|
||||
printf("connection timeout\n");
|
||||
@@ -454,7 +453,7 @@ bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) {
|
||||
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
||||
return false;
|
||||
LOCK(cs_proxyInfos);
|
||||
proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion);
|
||||
proxyInfo[net] = {addrProxy, nSocksVersion};
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -473,7 +472,7 @@ bool SetNameProxy(CService addrProxy, int nSocksVersion) {
|
||||
if (nSocksVersion != 0 && !addrProxy.IsValid())
|
||||
return false;
|
||||
LOCK(cs_proxyInfos);
|
||||
nameproxyInfo = std::make_pair(addrProxy, nSocksVersion);
|
||||
nameproxyInfo = {addrProxy, nSocksVersion};
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -868,7 +867,7 @@ std::string CNetAddr::ToStringIP() const
|
||||
unsigned char sha3hash[32];
|
||||
unsigned int sha3len = 0;
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex(mdctx, EVP_sha3_256(), NULL);
|
||||
EVP_DigestInit_ex(mdctx, EVP_sha3_256(), nullptr);
|
||||
EVP_DigestUpdate(mdctx, checksumInput, 48);
|
||||
EVP_DigestFinal_ex(mdctx, sha3hash, &sha3len);
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
@@ -890,7 +889,7 @@ std::string CNetAddr::ToStringIP() const
|
||||
socklen_t socklen = sizeof(sockaddr);
|
||||
if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
|
||||
char name[1025] = "";
|
||||
if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST))
|
||||
if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), nullptr, 0, NI_NUMERICHOST))
|
||||
return std::string(name);
|
||||
}
|
||||
if (IsIPv4())
|
||||
@@ -1043,7 +1042,7 @@ static const int NET_UNKNOWN = NET_MAX + 0;
|
||||
static const int NET_TEREDO = NET_MAX + 1;
|
||||
int static GetExtNetwork(const CNetAddr *addr)
|
||||
{
|
||||
if (addr == NULL)
|
||||
if (addr == nullptr)
|
||||
return NET_UNKNOWN;
|
||||
if (addr->IsRFC4380())
|
||||
return NET_TEREDO;
|
||||
|
||||
+2
-2
@@ -18,11 +18,11 @@ static const char *strMainNetOnionSeed[][1] = {
|
||||
{"on4noksywc7b6cdbbxsp535l7j4cugunvlyz3iyhf6sfcg2qzaoy3eqd.onion"},
|
||||
// Contabo seed 4
|
||||
{"3uyzltm5cy7xzunncp3d7ariw75erabdnj4l3cxwvsxb6h4orc7eiqad.onion"},
|
||||
{NULL}
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
static const char *strTestNetOnionSeed[][1] = {
|
||||
{NULL}
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -545,7 +545,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
|
||||
int64_t nFee = nTransactionFee * (1 + (int64_t)nBytes / 1000);
|
||||
|
||||
// Min Fee
|
||||
int64_t nMinFee = txDummy.GetMinFee(1, GMF_SEND, nBytes);
|
||||
int64_t nMinFee = txDummy.GetMinFee(1, GetMinFeeMode::Send, nBytes);
|
||||
|
||||
nPayFee = max(nFee, nMinFee);
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/interprocess/ipc/message_queue.hpp>
|
||||
#include <boost/version.hpp>
|
||||
@@ -26,6 +25,9 @@ using namespace boost;
|
||||
using namespace boost::interprocess;
|
||||
using namespace boost::posix_time;
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
#if defined MAC_OSX || defined __FreeBSD__
|
||||
// URI handling not implemented on OSX yet
|
||||
|
||||
@@ -42,7 +44,7 @@ static bool ipcScanCmd(int argc, char *argv[], bool fRelay)
|
||||
bool fSent = false;
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (boost::algorithm::istarts_with(argv[i], "Triangles:"))
|
||||
if (std::equal(std::begin("Triangles:"), std::end("Triangles:") - 1, argv[i], [](char a, char b) { return std::tolower(static_cast<unsigned char>(a)) == std::tolower(static_cast<unsigned char>(b)); }))
|
||||
{
|
||||
const char *strURI = argv[i];
|
||||
try {
|
||||
|
||||
@@ -229,7 +229,7 @@ int main(int argc, char *argv[])
|
||||
// calling Shutdown().
|
||||
|
||||
ClientModel clientModel(&optionsModel);
|
||||
WalletModel walletModel(pwalletMain, &optionsModel);
|
||||
WalletModel walletModel(pwalletMain.get(), &optionsModel);
|
||||
|
||||
window.setClientModel(&clientModel);
|
||||
window.setWalletModel(&walletModel);
|
||||
|
||||
@@ -89,7 +89,8 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
#include <memory>
|
||||
extern std::unique_ptr<CWallet> pwalletMain;
|
||||
extern int64_t nLastCoinStakeSearchInterval;
|
||||
extern unsigned int nTargetSpacing;
|
||||
double GetPoSKernelPS();
|
||||
@@ -655,7 +656,7 @@ void TrianglesGUI::ensureMessageModel()
|
||||
if(messageModel || !walletModel)
|
||||
return;
|
||||
|
||||
setMessageModel(new MessageModel(pwalletMain, walletModel, this));
|
||||
setMessageModel(new MessageModel(pwalletMain.get(), walletModel, this));
|
||||
}
|
||||
|
||||
void TrianglesGUI::ensureSendCoinsPage()
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
};
|
||||
|
||||
// Send coins to a list of recipients
|
||||
SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl=NULL);
|
||||
SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl=nullptr);
|
||||
|
||||
// Wallet encryption
|
||||
bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
|
||||
|
||||
+7
-10
@@ -12,8 +12,6 @@
|
||||
#include "wallet.h"
|
||||
#include "init.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
@@ -95,7 +93,7 @@ bool CheckRESTRateLimit(const string& strIP)
|
||||
|
||||
string HTTPReplyREST(int nStatus, const string& strMsg, const string& contentType)
|
||||
{
|
||||
string strCorsOrigin = GetArg("-restcorsorigin", "*");
|
||||
string strCorsOrigin = GetArg(std::string_view{"-restcorsorigin"}, std::string_view{"*"});
|
||||
|
||||
const char *cStatus;
|
||||
if (nStatus == 200) cStatus = "OK";
|
||||
@@ -149,12 +147,11 @@ static void ParseRESTPath(const string& strURI, vector<string>& parts, map<strin
|
||||
}
|
||||
|
||||
// Split path into parts
|
||||
boost::split(parts, path, boost::is_any_of("/"));
|
||||
parts = SplitString(path, '/');
|
||||
|
||||
// Parse query parameters
|
||||
if (!queryString.empty()) {
|
||||
vector<string> pairs;
|
||||
boost::split(pairs, queryString, boost::is_any_of("&"));
|
||||
auto pairs = SplitString(queryString, '&');
|
||||
for (size_t i = 0; i < pairs.size(); i++) {
|
||||
size_t eq = pairs[i].find('=');
|
||||
if (eq != string::npos)
|
||||
@@ -175,12 +172,12 @@ bool IsRESTPath(const string& strURI)
|
||||
static bool RESTAuthorized(map<string, string>& mapHeaders)
|
||||
{
|
||||
// Check Bearer token first (if -restapikey is set)
|
||||
string strApiKey = GetArg("-restapikey", "");
|
||||
string strApiKey = GetArg(std::string_view{"-restapikey"}, std::string_view{""});
|
||||
if (!strApiKey.empty()) {
|
||||
string strAuth = mapHeaders.count("authorization") ? mapHeaders["authorization"] : "";
|
||||
if (strAuth.substr(0, 7) == "Bearer ") {
|
||||
string strToken = strAuth.substr(7);
|
||||
boost::trim(strToken);
|
||||
strToken = TrimString(strToken);
|
||||
if (TimingResistantEqual(strToken, strApiKey))
|
||||
return true;
|
||||
}
|
||||
@@ -300,8 +297,8 @@ static bool HandleBlockHeader(const string& param, string& strReply, int& nStatu
|
||||
result.push_back(Pair("height", pblockindex->nHeight));
|
||||
result.push_back(Pair("version", pblockindex->nVersion));
|
||||
result.push_back(Pair("merkleroot", pblockindex->hashMerkleRoot.GetHex()));
|
||||
result.push_back(Pair("time", (boost::int64_t)pblockindex->GetBlockTime()));
|
||||
result.push_back(Pair("nonce", (boost::uint64_t)pblockindex->nNonce));
|
||||
result.push_back(Pair("time", (int64_t)pblockindex->GetBlockTime()));
|
||||
result.push_back(Pair("nonce", (uint64_t)pblockindex->nNonce));
|
||||
result.push_back(Pair("bits", HexBits(pblockindex->nBits)));
|
||||
result.push_back(Pair("difficulty", GetDifficulty(pblockindex)));
|
||||
result.push_back(Pair("flags", strprintf("%s%s",
|
||||
|
||||
+10
-10
@@ -34,15 +34,15 @@ double GetDifficulty(const CBlockIndex* blockindex)
|
||||
{
|
||||
// Floating point number that is a multiple of the minimum difficulty,
|
||||
// minimum difficulty = 1.0.
|
||||
if (blockindex == NULL)
|
||||
if (blockindex == nullptr)
|
||||
{
|
||||
if (pindexBest == NULL)
|
||||
if (pindexBest == nullptr)
|
||||
return 1.0;
|
||||
else
|
||||
blockindex = GetLastBlockIndex(pindexBest, false);
|
||||
}
|
||||
|
||||
if (blockindex == NULL)
|
||||
if (blockindex == nullptr)
|
||||
return 1.0;
|
||||
|
||||
int nShift = (blockindex->nBits >> 24) & 0xff;
|
||||
@@ -98,7 +98,7 @@ double GetPoSKernelPS()
|
||||
int nStakesHandled = 0, nStakesTime = 0;
|
||||
|
||||
CBlockIndex* pindex = pindexBest;;
|
||||
CBlockIndex* pindexPrevStake = NULL;
|
||||
CBlockIndex* pindexPrevStake = nullptr;
|
||||
|
||||
while (pindex && nStakesHandled < nPoSInterval)
|
||||
{
|
||||
@@ -128,8 +128,8 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPri
|
||||
result.push_back(Pair("version", block.nVersion));
|
||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||
result.push_back(Pair("mint", ValueFromAmount(blockindex->nMint)));
|
||||
result.push_back(Pair("time", (boost::int64_t)block.GetBlockTime()));
|
||||
result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
|
||||
result.push_back(Pair("time", (int64_t)block.GetBlockTime()));
|
||||
result.push_back(Pair("nonce", (uint64_t)block.nNonce));
|
||||
result.push_back(Pair("bits", HexBits(block.nBits)));
|
||||
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
|
||||
result.push_back(Pair("blocktrust", leftTrim(blockindex->GetBlockTrust().GetHex(), '0')));
|
||||
@@ -330,8 +330,8 @@ Value getblockheader(const Array& params, bool fHelp)
|
||||
result.push_back(Pair("version", pblockindex->nVersion));
|
||||
result.push_back(Pair("merkleroot", pblockindex->hashMerkleRoot.GetHex()));
|
||||
result.push_back(Pair("mint", ValueFromAmount(pblockindex->nMint)));
|
||||
result.push_back(Pair("time", (boost::int64_t)pblockindex->GetBlockTime()));
|
||||
result.push_back(Pair("nonce", (boost::uint64_t)pblockindex->nNonce));
|
||||
result.push_back(Pair("time", (int64_t)pblockindex->GetBlockTime()));
|
||||
result.push_back(Pair("nonce", (uint64_t)pblockindex->nNonce));
|
||||
result.push_back(Pair("bits", HexBits(pblockindex->nBits)));
|
||||
result.push_back(Pair("difficulty", GetDifficulty(pblockindex)));
|
||||
result.push_back(Pair("blocktrust", leftTrim(pblockindex->GetBlockTrust().GetHex(), '0')));
|
||||
@@ -708,7 +708,7 @@ Value getblockchaininfo(const Array& params, bool fHelp)
|
||||
obj.push_back(Pair("difficulty", diff));
|
||||
|
||||
obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply)));
|
||||
obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
|
||||
obj.push_back(Pair("timeoffset", (int64_t)GetTimeOffset()));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
||||
return obj;
|
||||
@@ -1042,7 +1042,7 @@ Value invalidateblock(const Array& params, bool fHelp)
|
||||
setStakeSeen.erase(make_pair(pindexWalk->prevoutStake, pindexWalk->nStakeTime));
|
||||
}
|
||||
|
||||
pindexWalk->pprev->pnext = NULL;
|
||||
pindexWalk->pprev->pnext = nullptr;
|
||||
pindexWalk = pindexWalk->pprev;
|
||||
}
|
||||
|
||||
|
||||
+6
-8
@@ -11,7 +11,6 @@
|
||||
#include "base58.h"
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#define printf OutputDebugStringF
|
||||
|
||||
@@ -94,9 +93,9 @@ public:
|
||||
bool fSpent;
|
||||
CWalletTx* ptx;
|
||||
int nOut;
|
||||
CTxDump(CWalletTx* ptx = NULL, int nOut = -1)
|
||||
CTxDump(CWalletTx* ptx = nullptr, int nOut = -1)
|
||||
{
|
||||
pindex = NULL;
|
||||
pindex = nullptr;
|
||||
nValue = 0;
|
||||
fSpent = false;
|
||||
this->ptx = ptx;
|
||||
@@ -167,8 +166,7 @@ Value importwallet(const Array& params, bool fHelp)
|
||||
if (line.empty() || line[0] == '#')
|
||||
continue;
|
||||
|
||||
std::vector<std::string> vstr;
|
||||
boost::split(vstr, line, boost::is_any_of(" "));
|
||||
auto vstr = SplitString(line, ' ');
|
||||
if (vstr.size() < 2)
|
||||
continue;
|
||||
CTrianglesSecret vchSecret;
|
||||
@@ -189,13 +187,13 @@ Value importwallet(const Array& params, bool fHelp)
|
||||
std::string strLabel;
|
||||
bool fLabel = true;
|
||||
for (unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
|
||||
if (boost::algorithm::starts_with(vstr[nStr], "#"))
|
||||
if (vstr[nStr].starts_with("#"))
|
||||
break;
|
||||
if (vstr[nStr] == "change=1")
|
||||
fLabel = false;
|
||||
if (vstr[nStr] == "reserve=1")
|
||||
fLabel = false;
|
||||
if (boost::algorithm::starts_with(vstr[nStr], "label=")) {
|
||||
if (vstr[nStr].starts_with("label=")) {
|
||||
strLabel = DecodeDumpString(vstr[nStr].substr(6));
|
||||
fLabel = true;
|
||||
}
|
||||
@@ -281,7 +279,7 @@ Value dumpwallet(const Array& params, bool fHelp)
|
||||
// sort time/key pairs
|
||||
std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
|
||||
for (std::map<CKeyID, int64_t>::const_iterator it = mapKeyBirth.begin(); it != mapKeyBirth.end(); it++) {
|
||||
vKeyBirth.push_back(std::make_pair(it->second, it->first));
|
||||
vKeyBirth.push_back({it->second, it->first});
|
||||
}
|
||||
mapKeyBirth.clear();
|
||||
std::sort(vKeyBirth.begin(), vKeyBirth.end());
|
||||
|
||||
+8
-8
@@ -31,7 +31,7 @@ Value getnetworkinfo(const Array& params, bool fHelp)
|
||||
healthObj.push_back(Pair("torpeers", health.torPeers));
|
||||
healthObj.push_back(Pair("bootstrapped", health.isBootstrapped));
|
||||
healthObj.push_back(Pair("syncing", health.isSyncing));
|
||||
healthObj.push_back(Pair("lastblocktime", static_cast<boost::int64_t>(health.lastBlockTime)));
|
||||
healthObj.push_back(Pair("lastblocktime", static_cast<int64_t>(health.lastBlockTime)));
|
||||
healthObj.push_back(Pair("networkmode", "tor_native"));
|
||||
|
||||
Object obj;
|
||||
@@ -88,9 +88,9 @@ Value getpeerinfo(const Array& params, bool fHelp)
|
||||
|
||||
obj.push_back(Pair("addr", stats.addrName));
|
||||
obj.push_back(Pair("services", strprintf("%08"PRIx64, stats.nServices)));
|
||||
obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend));
|
||||
obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv));
|
||||
obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected));
|
||||
obj.push_back(Pair("lastsend", (int64_t)stats.nLastSend));
|
||||
obj.push_back(Pair("lastrecv", (int64_t)stats.nLastRecv));
|
||||
obj.push_back(Pair("conntime", (int64_t)stats.nTimeConnected));
|
||||
obj.push_back(Pair("version", stats.nVersion));
|
||||
obj.push_back(Pair("subver", stats.strSubVer));
|
||||
obj.push_back(Pair("inbound", stats.fInbound));
|
||||
@@ -195,7 +195,7 @@ Value getseedlist(const Array& params, bool fHelp)
|
||||
Object obj;
|
||||
obj.push_back(Pair("address", addr.ToStringIP()));
|
||||
obj.push_back(Pair("port", (int)addr.GetPort()));
|
||||
obj.push_back(Pair("lastseen", (boost::int64_t)addr.nTime));
|
||||
obj.push_back(Pair("lastseen", (int64_t)addr.nTime));
|
||||
ret.push_back(obj);
|
||||
}
|
||||
|
||||
@@ -274,11 +274,11 @@ Value getnetworkstability(const Array& params, bool fHelp)
|
||||
obj.push_back(Pair("ping", pingObj));
|
||||
|
||||
Object uptimeObj;
|
||||
uptimeObj.push_back(Pair("newest_sec", nTotal > 0 ? (boost::int64_t)nNewestConnection : 0));
|
||||
uptimeObj.push_back(Pair("oldest_sec", nTotal > 0 ? (boost::int64_t)nOldestConnection : 0));
|
||||
uptimeObj.push_back(Pair("newest_sec", nTotal > 0 ? (int64_t)nNewestConnection : 0));
|
||||
uptimeObj.push_back(Pair("oldest_sec", nTotal > 0 ? (int64_t)nOldestConnection : 0));
|
||||
obj.push_back(Pair("connection_uptime", uptimeObj));
|
||||
|
||||
obj.push_back(Pair("seconds_since_last_block", (boost::int64_t)(GetTime() - nTimeBestReceived)));
|
||||
obj.push_back(Pair("seconds_since_last_block", (int64_t)(GetTime() - nTimeBestReceived)));
|
||||
obj.push_back(Pair("current_height", nBestHeight));
|
||||
|
||||
return obj;
|
||||
|
||||
+10
-10
@@ -17,7 +17,7 @@ using namespace json_spirit;
|
||||
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
|
||||
{
|
||||
txnouttype type;
|
||||
TxnOutType type;
|
||||
vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
@@ -28,7 +28,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH
|
||||
|
||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
|
||||
{
|
||||
out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
|
||||
out.push_back(Pair("type", GetTxnOutputType(TxnOutType::NonStandard)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
||||
{
|
||||
entry.push_back(Pair("txid", tx.GetHash().GetHex()));
|
||||
entry.push_back(Pair("version", tx.nVersion));
|
||||
entry.push_back(Pair("time", (boost::int64_t)tx.nTime));
|
||||
entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime));
|
||||
entry.push_back(Pair("time", (int64_t)tx.nTime));
|
||||
entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
|
||||
Array vin;
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
@@ -56,13 +56,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
||||
else
|
||||
{
|
||||
in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
|
||||
in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n));
|
||||
in.push_back(Pair("vout", (int64_t)txin.prevout.n));
|
||||
Object o;
|
||||
o.push_back(Pair("asm", txin.scriptSig.ToString()));
|
||||
o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
|
||||
in.push_back(Pair("scriptSig", o));
|
||||
}
|
||||
in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence));
|
||||
in.push_back(Pair("sequence", (int64_t)txin.nSequence));
|
||||
vin.push_back(in);
|
||||
}
|
||||
entry.push_back(Pair("vin", vin));
|
||||
@@ -72,7 +72,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
||||
const CTxOut& txout = tx.vout[i];
|
||||
Object out;
|
||||
out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
|
||||
out.push_back(Pair("n", (boost::int64_t)i));
|
||||
out.push_back(Pair("n", (int64_t)i));
|
||||
Object o;
|
||||
ScriptPubKeyToJSON(txout.scriptPubKey, o, false);
|
||||
out.push_back(Pair("scriptPubKey", o));
|
||||
@@ -90,8 +90,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
||||
if (pindex->IsInMainChain())
|
||||
{
|
||||
entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight));
|
||||
entry.push_back(Pair("time", (boost::int64_t)pindex->nTime));
|
||||
entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime));
|
||||
entry.push_back(Pair("time", (int64_t)pindex->nTime));
|
||||
entry.push_back(Pair("blocktime", (int64_t)pindex->nTime));
|
||||
}
|
||||
else
|
||||
entry.push_back(Pair("confirmations", 0));
|
||||
@@ -552,7 +552,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||
if (!tx.AcceptToMemoryPool(txdb))
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected");
|
||||
|
||||
SyncWithWallets(tx, NULL, true);
|
||||
SyncWithWallets(tx, nullptr, true);
|
||||
}
|
||||
RelayTransaction(tx, hashTx);
|
||||
|
||||
|
||||
+14
-14
@@ -59,11 +59,11 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
|
||||
entry.push_back(Pair("blockindex", wtx.nIndex));
|
||||
auto mi = mapBlockIndex.find(wtx.hashBlock);
|
||||
if (mi != mapBlockIndex.end() && mi->second)
|
||||
entry.push_back(Pair("blocktime", (boost::int64_t)(mi->second->nTime)));
|
||||
entry.push_back(Pair("blocktime", (int64_t)(mi->second->nTime)));
|
||||
}
|
||||
entry.push_back(Pair("txid", wtx.GetHash().GetHex()));
|
||||
entry.push_back(Pair("time", (boost::int64_t)wtx.GetTxTime()));
|
||||
entry.push_back(Pair("timereceived", (boost::int64_t)wtx.nTimeReceived));
|
||||
entry.push_back(Pair("time", (int64_t)wtx.GetTxTime()));
|
||||
entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
|
||||
for (const auto& item : wtx.mapValue)
|
||||
entry.push_back(Pair(item.first, item.second));
|
||||
}
|
||||
@@ -94,7 +94,7 @@ Value getinfo(const Array& params, bool fHelp)
|
||||
obj.push_back(Pair("newmint", ValueFromAmount(pwalletMain->GetNewMint())));
|
||||
obj.push_back(Pair("stake", ValueFromAmount(pwalletMain->GetStake())));
|
||||
obj.push_back(Pair("blocks", (int)nBestHeight));
|
||||
obj.push_back(Pair("timeoffset", (boost::int64_t)GetTimeOffset()));
|
||||
obj.push_back(Pair("timeoffset", (int64_t)GetTimeOffset()));
|
||||
obj.push_back(Pair("moneysupply", ValueFromAmount(pindexBest->nMoneySupply)));
|
||||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string())));
|
||||
@@ -105,14 +105,14 @@ Value getinfo(const Array& params, bool fHelp)
|
||||
obj.push_back(Pair("difficulty", diff));
|
||||
|
||||
obj.push_back(Pair("testnet", fTestNet));
|
||||
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||
obj.push_back(Pair("keypoololdest", (int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
|
||||
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
|
||||
obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue)));
|
||||
if (pwalletMain->IsCrypted())
|
||||
{
|
||||
LOCK(cs_nWalletUnlockTime);
|
||||
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
|
||||
obj.push_back(Pair("unlocked_until", (int64_t)nWalletUnlockTime / 1000));
|
||||
}
|
||||
obj.push_back(Pair("errors", GetWarnings("statusbar")));
|
||||
return obj;
|
||||
@@ -139,14 +139,14 @@ Value getwalletinfo(const Array& params, bool fHelp)
|
||||
obj.push_back(Pair("stake", ValueFromAmount(pwalletMain->GetStake())));
|
||||
obj.push_back(Pair("newmint", ValueFromAmount(pwalletMain->GetNewMint())));
|
||||
obj.push_back(Pair("txcount", txCount));
|
||||
obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||
obj.push_back(Pair("keypoololdest", (int64_t)pwalletMain->GetOldestKeyPoolTime()));
|
||||
obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize()));
|
||||
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
|
||||
obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue)));
|
||||
if (pwalletMain->IsCrypted())
|
||||
{
|
||||
LOCK(cs_nWalletUnlockTime);
|
||||
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
|
||||
obj.push_back(Pair("unlocked_until", (int64_t)nWalletUnlockTime / 1000));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@@ -818,7 +818,7 @@ Value sendmany(const Array& params, bool fHelp)
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
||||
|
||||
// Send
|
||||
CReserveKey keyChange(pwalletMain);
|
||||
CReserveKey keyChange(pwalletMain.get());
|
||||
int64_t nFeeRequired = 0;
|
||||
bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
|
||||
if (!fCreated)
|
||||
@@ -1151,7 +1151,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar
|
||||
Object entry;
|
||||
entry.push_back(Pair("account", acentry.strAccount));
|
||||
entry.push_back(Pair("category", "move"));
|
||||
entry.push_back(Pair("time", (boost::int64_t)acentry.nTime));
|
||||
entry.push_back(Pair("time", (int64_t)acentry.nTime));
|
||||
entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
|
||||
entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
|
||||
entry.push_back(Pair("comment", acentry.strComment));
|
||||
@@ -1284,7 +1284,7 @@ Value listsinceblock(const Array& params, bool fHelp)
|
||||
"listsinceblock [blockhash] [target-confirmations]\n"
|
||||
"Get all transactions in blocks since block [blockhash], or all transactions if omitted");
|
||||
|
||||
CBlockIndex *pindex = NULL;
|
||||
CBlockIndex *pindex = nullptr;
|
||||
int target_confirms = 1;
|
||||
|
||||
if (params.size() > 0)
|
||||
@@ -1535,7 +1535,7 @@ Value walletpassphrase(const Array& params, bool fHelp)
|
||||
"walletpassphrase <passphrase> <timeout>\n"
|
||||
"Stores the wallet decryption key in memory for <timeout> seconds.");
|
||||
|
||||
NewThread(ThreadTopUpKeyPool, NULL);
|
||||
NewThread(ThreadTopUpKeyPool, nullptr);
|
||||
int64_t* pnSleepTime = new int64_t(params[1].get_int64());
|
||||
NewThread(ThreadCleanWalletPassphrase, pnSleepTime);
|
||||
|
||||
@@ -1654,7 +1654,7 @@ public:
|
||||
CScript subscript;
|
||||
pwalletMain->GetCScript(scriptID, subscript);
|
||||
std::vector<CTxDestination> addresses;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
int nRequired;
|
||||
ExtractDestinations(subscript, whichType, addresses, nRequired);
|
||||
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
|
||||
@@ -1663,7 +1663,7 @@ public:
|
||||
for (const CTxDestination& addr : addresses)
|
||||
a.push_back(CTrianglesAddress(addr).ToString());
|
||||
obj.push_back(Pair("addresses", a));
|
||||
if (whichType == TX_MULTISIG)
|
||||
if (whichType == TxnOutType::MultiSig)
|
||||
obj.push_back(Pair("sigsrequired", nRequired));
|
||||
return obj;
|
||||
}
|
||||
|
||||
+73
-79
@@ -16,7 +16,7 @@ using namespace std;
|
||||
#include "sync.h"
|
||||
#include "util.h"
|
||||
|
||||
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
bool CheckSig(const vector<unsigned char>& vchSig, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
|
||||
static const valtype vchFalse(0);
|
||||
static const valtype vchZero(0);
|
||||
@@ -93,17 +93,17 @@ static inline void popstack(vector<valtype>& stack)
|
||||
}
|
||||
|
||||
|
||||
const char* GetTxnOutputType(txnouttype t)
|
||||
const char* GetTxnOutputType(TxnOutType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case TX_NONSTANDARD: return "nonstandard";
|
||||
case TX_PUBKEY: return "pubkey";
|
||||
case TX_PUBKEYHASH: return "pubkeyhash";
|
||||
case TX_SCRIPTHASH: return "scripthash";
|
||||
case TX_MULTISIG: return "multisig";
|
||||
case TxnOutType::NonStandard: return "nonstandard";
|
||||
case TxnOutType::PubKey: return "pubkey";
|
||||
case TxnOutType::PubKeyHash: return "pubkeyhash";
|
||||
case TxnOutType::ScriptHash: return "scripthash";
|
||||
case TxnOutType::MultiSig: return "multisig";
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -751,8 +751,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
if (stack.size() < 1)
|
||||
return false;
|
||||
valtype& vch = stacktop(-1);
|
||||
for (unsigned int i = 0; i < vch.size(); i++)
|
||||
vch[i] = ~vch[i];
|
||||
for (auto& b : vch)
|
||||
b = ~b;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -893,7 +893,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
break;
|
||||
|
||||
case OP_DIV:
|
||||
if (!BN_div(bn.get(), NULL, bn1.get(), bn2.get(), pctx))
|
||||
if (!BN_div(bn.get(), nullptr, bn1.get(), bn2.get(), pctx))
|
||||
return false;
|
||||
break;
|
||||
|
||||
@@ -973,7 +973,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
|
||||
valtype& vch = stacktop(-1);
|
||||
valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
|
||||
if (opcode == OP_RIPEMD160)
|
||||
{
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
else if (opcode == OP_SHA1)
|
||||
SHA1(&vch[0], vch.size(), &vchHash[0]);
|
||||
else if (opcode == OP_SHA256)
|
||||
@@ -1227,7 +1231,7 @@ private:
|
||||
// Mix sighash with first 8 bytes of sig and pubkey for a fast key
|
||||
uint64_t k = hash.Get64();
|
||||
if (vchSig.size() >= 8)
|
||||
memcpy(&k, &k, 4); // keep upper half
|
||||
k = (k & 0xffffffff00000000ULL) | (k & 0x00000000ffffffffULL);
|
||||
k ^= std::hash<size_t>()(vchSig.size()) * 0x9e3779b97f4a7c15ULL;
|
||||
k ^= std::hash<size_t>()(vchPubKey.size()) * 0x517cc1b727220a95ULL;
|
||||
// Mix in actual signature bytes for uniqueness
|
||||
@@ -1271,7 +1275,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
|
||||
bool CheckSig(const vector<unsigned char>& vchSig, const vector<unsigned char>& vchPubKey, const CScript& scriptCode,
|
||||
const CTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
{
|
||||
static CSignatureCache signatureCache;
|
||||
@@ -1283,18 +1287,20 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
|
||||
nHashType = vchSig.back();
|
||||
else if (nHashType != vchSig.back())
|
||||
return false;
|
||||
vchSig.pop_back();
|
||||
|
||||
vector<unsigned char> vchSigCopy(vchSig);
|
||||
vchSigCopy.pop_back();
|
||||
|
||||
uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
|
||||
|
||||
if (signatureCache.Get(sighash, vchSig, vchPubKey))
|
||||
if (signatureCache.Get(sighash, vchSigCopy, vchPubKey))
|
||||
return true;
|
||||
|
||||
CKey key;
|
||||
if (!key.SetPubKey(vchPubKey))
|
||||
return false;
|
||||
|
||||
if (!key.Verify(sighash, vchSig))
|
||||
if (!key.Verify(sighash, vchSigCopy))
|
||||
return false;
|
||||
|
||||
signatureCache.Set(sighash, vchSig, vchPubKey);
|
||||
@@ -1312,27 +1318,21 @@ bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CSc
|
||||
//
|
||||
// Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
|
||||
//
|
||||
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
|
||||
bool Solver(const CScript& scriptPubKey, TxnOutType& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
|
||||
{
|
||||
// Templates
|
||||
static map<txnouttype, CScript> mTemplates;
|
||||
static map<TxnOutType, CScript> mTemplates;
|
||||
if (mTemplates.empty())
|
||||
{
|
||||
// Standard tx, sender provides pubkey, receiver adds signature
|
||||
mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));
|
||||
|
||||
// Triangles address tx, sender provides hash of pubkey, receiver provides signature and pubkey
|
||||
mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));
|
||||
|
||||
// Sender provides N pubkeys, receivers provides M signatures
|
||||
mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
|
||||
mTemplates.insert(make_pair(TxnOutType::PubKey, CScript() << OP_PUBKEY << OP_CHECKSIG));
|
||||
mTemplates.insert(make_pair(TxnOutType::PubKeyHash, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));
|
||||
mTemplates.insert(make_pair(TxnOutType::MultiSig, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
|
||||
}
|
||||
|
||||
// Shortcut for pay-to-script-hash, which are more constrained than the other types:
|
||||
// it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
|
||||
if (scriptPubKey.IsPayToScriptHash())
|
||||
{
|
||||
typeRet = TX_SCRIPTHASH;
|
||||
typeRet = TxnOutType::ScriptHash;
|
||||
vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
|
||||
vSolutionsRet.push_back(hashBytes);
|
||||
return true;
|
||||
@@ -1357,7 +1357,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
|
||||
{
|
||||
// Found a match
|
||||
typeRet = tplate.first;
|
||||
if (typeRet == TX_MULTISIG)
|
||||
if (typeRet == TxnOutType::MultiSig)
|
||||
{
|
||||
// Additional checks for TX_MULTISIG:
|
||||
unsigned char m = vSolutionsRet.front()[0];
|
||||
@@ -1419,7 +1419,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
|
||||
}
|
||||
|
||||
vSolutionsRet.clear();
|
||||
typeRet = TX_NONSTANDARD;
|
||||
typeRet = TxnOutType::NonStandard;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1460,7 +1460,7 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2
|
||||
// Returns false if scriptPubKey could not be completely satisfied.
|
||||
//
|
||||
bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType,
|
||||
CScript& scriptSigRet, txnouttype& whichTypeRet)
|
||||
CScript& scriptSigRet, TxnOutType& whichTypeRet)
|
||||
{
|
||||
scriptSigRet.clear();
|
||||
|
||||
@@ -1471,12 +1471,12 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
|
||||
CKeyID keyID;
|
||||
switch (whichTypeRet)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TxnOutType::NonStandard:
|
||||
return false;
|
||||
case TX_PUBKEY:
|
||||
case TxnOutType::PubKey:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
return Sign1(keyID, keystore, hash, nHashType, scriptSigRet);
|
||||
case TX_PUBKEYHASH:
|
||||
case TxnOutType::PubKeyHash:
|
||||
keyID = CKeyID(uint160(vSolutions[0]));
|
||||
if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet))
|
||||
return false;
|
||||
@@ -1487,32 +1487,32 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
|
||||
scriptSigRet << vch;
|
||||
}
|
||||
return true;
|
||||
case TX_SCRIPTHASH:
|
||||
case TxnOutType::ScriptHash:
|
||||
return keystore.GetCScript(uint160(vSolutions[0]), scriptSigRet);
|
||||
|
||||
case TX_MULTISIG:
|
||||
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
|
||||
case TxnOutType::MultiSig:
|
||||
scriptSigRet << OP_0;
|
||||
return (SignN(vSolutions, keystore, hash, nHashType, scriptSigRet));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
|
||||
int ScriptSigArgsExpected(TxnOutType t, const std::vector<std::vector<unsigned char> >& vSolutions)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TxnOutType::NonStandard:
|
||||
return -1;
|
||||
case TX_PUBKEY:
|
||||
case TxnOutType::PubKey:
|
||||
return 1;
|
||||
case TX_PUBKEYHASH:
|
||||
case TxnOutType::PubKeyHash:
|
||||
return 2;
|
||||
case TX_MULTISIG:
|
||||
case TxnOutType::MultiSig:
|
||||
if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
|
||||
return -1;
|
||||
return vSolutions[0][0] + 1;
|
||||
case TX_SCRIPTHASH:
|
||||
return 1; // doesn't include args needed by the script
|
||||
case TxnOutType::ScriptHash:
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1520,11 +1520,11 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned c
|
||||
bool IsStandard(const CScript& scriptPubKey)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
|
||||
if (whichType == TX_MULTISIG)
|
||||
if (whichType == TxnOutType::MultiSig)
|
||||
{
|
||||
unsigned char m = vSolutions.front()[0];
|
||||
unsigned char n = vSolutions.back()[0];
|
||||
@@ -1535,7 +1535,7 @@ bool IsStandard(const CScript& scriptPubKey)
|
||||
return false;
|
||||
}
|
||||
|
||||
return whichType != TX_NONSTANDARD;
|
||||
return whichType != TxnOutType::NonStandard;
|
||||
}
|
||||
|
||||
|
||||
@@ -1571,29 +1571,29 @@ bool IsMine(const CKeyStore &keystore, const CTxDestination &dest)
|
||||
bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
|
||||
CKeyID keyID;
|
||||
switch (whichType)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TxnOutType::NonStandard:
|
||||
return false;
|
||||
case TX_PUBKEY:
|
||||
case TxnOutType::PubKey:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
return keystore.HaveKey(keyID);
|
||||
case TX_PUBKEYHASH:
|
||||
case TxnOutType::PubKeyHash:
|
||||
keyID = CKeyID(uint160(vSolutions[0]));
|
||||
return keystore.HaveKey(keyID);
|
||||
case TX_SCRIPTHASH:
|
||||
case TxnOutType::ScriptHash:
|
||||
{
|
||||
CScript subscript;
|
||||
if (!keystore.GetCScript(CScriptID(uint160(vSolutions[0])), subscript))
|
||||
return false;
|
||||
return IsMine(keystore, subscript);
|
||||
}
|
||||
case TX_MULTISIG:
|
||||
case TxnOutType::MultiSig:
|
||||
{
|
||||
// Only consider transactions "mine" if we own ALL the
|
||||
// keys involved. multi-signature transactions that are
|
||||
@@ -1610,21 +1610,21 @@ bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
{
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
if (!Solver(scriptPubKey, whichType, vSolutions))
|
||||
return false;
|
||||
|
||||
if (whichType == TX_PUBKEY)
|
||||
if (whichType == TxnOutType::PubKey)
|
||||
{
|
||||
addressRet = CPubKey(vSolutions[0]).GetID();
|
||||
return true;
|
||||
}
|
||||
else if (whichType == TX_PUBKEYHASH)
|
||||
else if (whichType == TxnOutType::PubKeyHash)
|
||||
{
|
||||
addressRet = CKeyID(uint160(vSolutions[0]));
|
||||
return true;
|
||||
}
|
||||
else if (whichType == TX_SCRIPTHASH)
|
||||
else if (whichType == TxnOutType::ScriptHash)
|
||||
{
|
||||
addressRet = CScriptID(uint160(vSolutions[0]));
|
||||
return true;
|
||||
@@ -1642,7 +1642,7 @@ public:
|
||||
CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
|
||||
|
||||
void Process(const CScript &script) {
|
||||
txnouttype type;
|
||||
TxnOutType type;
|
||||
std::vector<CTxDestination> vDest;
|
||||
int nRequired;
|
||||
if (ExtractDestinations(script, type, vDest, nRequired)) {
|
||||
@@ -1671,15 +1671,15 @@ void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey,
|
||||
CAffectedKeysVisitor(keystore, vKeys).Process(scriptPubKey);
|
||||
}
|
||||
|
||||
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector<CTxDestination>& addressRet, int& nRequiredRet)
|
||||
bool ExtractDestinations(const CScript& scriptPubKey, TxnOutType& typeRet, vector<CTxDestination>& addressRet, int& nRequiredRet)
|
||||
{
|
||||
addressRet.clear();
|
||||
typeRet = TX_NONSTANDARD;
|
||||
typeRet = TxnOutType::NonStandard;
|
||||
vector<valtype> vSolutions;
|
||||
if (!Solver(scriptPubKey, typeRet, vSolutions))
|
||||
return false;
|
||||
|
||||
if (typeRet == TX_MULTISIG)
|
||||
if (typeRet == TxnOutType::MultiSig)
|
||||
{
|
||||
nRequiredRet = vSolutions.front()[0];
|
||||
for (unsigned int i = 1; i < vSolutions.size()-1; i++)
|
||||
@@ -1747,23 +1747,19 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CTransa
|
||||
// The checksig op will also drop the signatures from its hash.
|
||||
uint256 hash = SignatureHash(fromPubKey, txTo, nIn, nHashType);
|
||||
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
if (!Solver(keystore, fromPubKey, hash, nHashType, txin.scriptSig, whichType))
|
||||
return false;
|
||||
|
||||
if (whichType == TX_SCRIPTHASH)
|
||||
if (whichType == TxnOutType::ScriptHash)
|
||||
{
|
||||
// Solver returns the subscript that need to be evaluated;
|
||||
// the final scriptSig is the signatures from that
|
||||
// and then the serialized subscript:
|
||||
CScript subscript = txin.scriptSig;
|
||||
|
||||
// Recompute txn hash using subscript in place of scriptPubKey:
|
||||
uint256 hash2 = SignatureHash(subscript, txTo, nIn, nHashType);
|
||||
|
||||
txnouttype subType;
|
||||
TxnOutType subType;
|
||||
bool fSolved =
|
||||
Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TX_SCRIPTHASH;
|
||||
Solver(keystore, subscript, hash2, nHashType, txin.scriptSig, subType) && subType != TxnOutType::ScriptHash;
|
||||
// Append serialized subscript whether or not it is completely signed:
|
||||
txin.scriptSig << static_cast<valtype>(subscript);
|
||||
if (!fSolved) return false;
|
||||
@@ -1862,23 +1858,21 @@ static CScript CombineMultisig(CScript scriptPubKey, const CTransaction& txTo, u
|
||||
}
|
||||
|
||||
static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
||||
const txnouttype txType, const vector<valtype>& vSolutions,
|
||||
const TxnOutType txType, const vector<valtype>& vSolutions,
|
||||
vector<valtype>& sigs1, vector<valtype>& sigs2)
|
||||
{
|
||||
switch (txType)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
// Don't know anything about this, assume bigger one is correct:
|
||||
case TxnOutType::NonStandard:
|
||||
if (sigs1.size() >= sigs2.size())
|
||||
return PushAll(sigs1);
|
||||
return PushAll(sigs2);
|
||||
case TX_PUBKEY:
|
||||
case TX_PUBKEYHASH:
|
||||
// Signatures are bigger than placeholders or empty scripts:
|
||||
case TxnOutType::PubKey:
|
||||
case TxnOutType::PubKeyHash:
|
||||
if (sigs1.empty() || sigs1[0].empty())
|
||||
return PushAll(sigs2);
|
||||
return PushAll(sigs1);
|
||||
case TX_SCRIPTHASH:
|
||||
case TxnOutType::ScriptHash:
|
||||
if (sigs1.empty() || sigs1.back().empty())
|
||||
return PushAll(sigs2);
|
||||
else if (sigs2.empty() || sigs2.back().empty())
|
||||
@@ -1889,7 +1883,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo,
|
||||
valtype spk = sigs1.back();
|
||||
CScript pubKey2(spk.begin(), spk.end());
|
||||
|
||||
txnouttype txType2;
|
||||
TxnOutType txType2;
|
||||
vector<vector<unsigned char> > vSolutions2;
|
||||
Solver(pubKey2, txType2, vSolutions2);
|
||||
sigs1.pop_back();
|
||||
@@ -1898,7 +1892,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo,
|
||||
result << spk;
|
||||
return result;
|
||||
}
|
||||
case TX_MULTISIG:
|
||||
case TxnOutType::MultiSig:
|
||||
return CombineMultisig(scriptPubKey, txTo, nIn, vSolutions, sigs1, sigs2);
|
||||
}
|
||||
|
||||
@@ -1908,7 +1902,7 @@ static CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo,
|
||||
CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
||||
const CScript& scriptSig1, const CScript& scriptSig2)
|
||||
{
|
||||
txnouttype txType;
|
||||
TxnOutType txType;
|
||||
vector<vector<unsigned char> > vSolutions;
|
||||
Solver(scriptPubKey, txType, vSolutions);
|
||||
|
||||
|
||||
+20
-21
@@ -16,7 +16,7 @@
|
||||
#include "keystore.h"
|
||||
#include "bignum.h"
|
||||
|
||||
typedef std::vector<unsigned char> valtype;
|
||||
using valtype = std::vector<unsigned char>;
|
||||
|
||||
class CTransaction;
|
||||
|
||||
@@ -30,14 +30,13 @@ enum
|
||||
};
|
||||
|
||||
|
||||
enum txnouttype
|
||||
enum class TxnOutType
|
||||
{
|
||||
TX_NONSTANDARD,
|
||||
// 'standard' transaction types:
|
||||
TX_PUBKEY,
|
||||
TX_PUBKEYHASH,
|
||||
TX_SCRIPTHASH,
|
||||
TX_MULTISIG,
|
||||
NonStandard,
|
||||
PubKey,
|
||||
PubKeyHash,
|
||||
ScriptHash,
|
||||
MultiSig,
|
||||
};
|
||||
|
||||
class CNoDestination {
|
||||
@@ -52,9 +51,9 @@ public:
|
||||
* * CScriptID: TX_SCRIPTHASH destination
|
||||
* A CTxDestination is the internal data type encoded in a CTrianglesAddress
|
||||
*/
|
||||
typedef std::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
|
||||
using CTxDestination = std::variant<CNoDestination, CKeyID, CScriptID>;
|
||||
|
||||
const char* GetTxnOutputType(txnouttype t);
|
||||
const char* GetTxnOutputType(TxnOutType t);
|
||||
|
||||
/** Script opcodes */
|
||||
enum opcodetype
|
||||
@@ -267,7 +266,7 @@ protected:
|
||||
|
||||
public:
|
||||
CScript() { }
|
||||
CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { }
|
||||
CScript(const CScript& b) = default;
|
||||
CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { }
|
||||
#ifndef _MSC_VER
|
||||
CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { }
|
||||
@@ -590,19 +589,19 @@ public:
|
||||
|
||||
|
||||
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
|
||||
int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
|
||||
bool IsStandard(const CScript& scriptPubKey);
|
||||
bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
|
||||
bool IsMine(const CKeyStore& keystore, const CTxDestination &dest);
|
||||
bool Solver(const CScript& scriptPubKey, TxnOutType& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
|
||||
int ScriptSigArgsExpected(TxnOutType t, const std::vector<std::vector<unsigned char> >& vSolutions);
|
||||
[[nodiscard]] bool IsStandard(const CScript& scriptPubKey);
|
||||
[[nodiscard]] bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
|
||||
[[nodiscard]] bool IsMine(const CKeyStore& keystore, const CTxDestination &dest);
|
||||
void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector<CKeyID> &vKeys);
|
||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
|
||||
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
|
||||
bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
|
||||
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
|
||||
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
||||
bool ExtractDestinations(const CScript& scriptPubKey, TxnOutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
|
||||
[[nodiscard]] bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
|
||||
[[nodiscard]] bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
|
||||
[[nodiscard]] bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
|
||||
int nHashType);
|
||||
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
[[nodiscard]] bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType);
|
||||
|
||||
// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders,
|
||||
// combine them intelligently and return the result.
|
||||
|
||||
+32
-35
@@ -17,7 +17,7 @@
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include <boost/type_traits/is_fundamental.hpp>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
|
||||
#include "allocators.h"
|
||||
@@ -59,12 +59,11 @@ enum
|
||||
unsigned int GetSerializeSize(int nType, int nVersion) const \
|
||||
{ \
|
||||
CSerActionGetSerializeSize ser_action; \
|
||||
const bool fGetSize = true; \
|
||||
const bool fWrite = false; \
|
||||
const bool fRead = false; \
|
||||
[[maybe_unused]] const bool fGetSize = true; \
|
||||
[[maybe_unused]] const bool fWrite = false; \
|
||||
[[maybe_unused]] const bool fRead = false; \
|
||||
unsigned int nSerSize = 0; \
|
||||
ser_streamplaceholder s; \
|
||||
assert(fGetSize||fWrite||fRead); /* suppress warning */ \
|
||||
s.nType = nType; \
|
||||
s.nVersion = nVersion; \
|
||||
{statements} \
|
||||
@@ -74,22 +73,20 @@ enum
|
||||
void Serialize(Stream& s, int nType, int nVersion) const \
|
||||
{ \
|
||||
CSerActionSerialize ser_action; \
|
||||
const bool fGetSize = false; \
|
||||
const bool fWrite = true; \
|
||||
const bool fRead = false; \
|
||||
unsigned int nSerSize = 0; \
|
||||
assert(fGetSize||fWrite||fRead); /* suppress warning */ \
|
||||
[[maybe_unused]] const bool fGetSize = false; \
|
||||
[[maybe_unused]] const bool fWrite = true; \
|
||||
[[maybe_unused]] const bool fRead = false; \
|
||||
[[maybe_unused]] unsigned int nSerSize = 0; \
|
||||
{statements} \
|
||||
} \
|
||||
template<typename Stream> \
|
||||
void Unserialize(Stream& s, int nType, int nVersion) \
|
||||
{ \
|
||||
CSerActionUnserialize ser_action; \
|
||||
const bool fGetSize = false; \
|
||||
const bool fWrite = false; \
|
||||
const bool fRead = true; \
|
||||
unsigned int nSerSize = 0; \
|
||||
assert(fGetSize||fWrite||fRead); /* suppress warning */ \
|
||||
[[maybe_unused]] const bool fGetSize = false; \
|
||||
[[maybe_unused]] const bool fWrite = false; \
|
||||
[[maybe_unused]] const bool fRead = true; \
|
||||
[[maybe_unused]] unsigned int nSerSize = 0; \
|
||||
{statements} \
|
||||
}
|
||||
|
||||
@@ -288,14 +285,14 @@ template<typename Stream, typename C> void Serialize(Stream& os, const std::basi
|
||||
template<typename Stream, typename C> void Unserialize(Stream& is, std::basic_string<C>& str, int, int=0);
|
||||
|
||||
// vector
|
||||
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
|
||||
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
|
||||
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const std::true_type&);
|
||||
template<typename T, typename A> unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const std::false_type&);
|
||||
template<typename T, typename A> inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion);
|
||||
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
|
||||
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
|
||||
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const std::true_type&);
|
||||
template<typename Stream, typename T, typename A> void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const std::false_type&);
|
||||
template<typename Stream, typename T, typename A> inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion);
|
||||
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&);
|
||||
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&);
|
||||
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const std::true_type&);
|
||||
template<typename Stream, typename T, typename A> void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const std::false_type&);
|
||||
template<typename Stream, typename T, typename A> inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion);
|
||||
|
||||
// others derived from vector
|
||||
@@ -392,13 +389,13 @@ void Unserialize(Stream& is, std::basic_string<C>& str, int, int)
|
||||
// vector
|
||||
//
|
||||
template<typename T, typename A>
|
||||
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
|
||||
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const std::true_type&)
|
||||
{
|
||||
return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T, typename A>
|
||||
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
|
||||
unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nVersion, const std::false_type&)
|
||||
{
|
||||
unsigned int nSize = GetSizeOfCompactSize(v.size());
|
||||
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
|
||||
@@ -409,12 +406,12 @@ unsigned int GetSerializeSize_impl(const std::vector<T, A>& v, int nType, int nV
|
||||
template<typename T, typename A>
|
||||
inline unsigned int GetSerializeSize(const std::vector<T, A>& v, int nType, int nVersion)
|
||||
{
|
||||
return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental<T>());
|
||||
return GetSerializeSize_impl(v, nType, nVersion, std::is_fundamental<T>{});
|
||||
}
|
||||
|
||||
|
||||
template<typename Stream, typename T, typename A>
|
||||
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
|
||||
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const std::true_type&)
|
||||
{
|
||||
WriteCompactSize(os, v.size());
|
||||
if (!v.empty())
|
||||
@@ -422,7 +419,7 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVers
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, typename A>
|
||||
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
|
||||
void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVersion, const std::false_type&)
|
||||
{
|
||||
WriteCompactSize(os, v.size());
|
||||
for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)
|
||||
@@ -432,12 +429,12 @@ void Serialize_impl(Stream& os, const std::vector<T, A>& v, int nType, int nVers
|
||||
template<typename Stream, typename T, typename A>
|
||||
inline void Serialize(Stream& os, const std::vector<T, A>& v, int nType, int nVersion)
|
||||
{
|
||||
Serialize_impl(os, v, nType, nVersion, boost::is_fundamental<T>());
|
||||
Serialize_impl(os, v, nType, nVersion, std::is_fundamental<T>{});
|
||||
}
|
||||
|
||||
|
||||
template<typename Stream, typename T, typename A>
|
||||
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::true_type&)
|
||||
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const std::true_type&)
|
||||
{
|
||||
// Limit size per read so bogus size value won't cause out of memory
|
||||
v.clear();
|
||||
@@ -453,7 +450,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion,
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, typename A>
|
||||
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const boost::false_type&)
|
||||
void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion, const std::false_type&)
|
||||
{
|
||||
v.clear();
|
||||
unsigned int nSize = ReadCompactSize(is);
|
||||
@@ -473,7 +470,7 @@ void Unserialize_impl(Stream& is, std::vector<T, A>& v, int nType, int nVersion,
|
||||
template<typename Stream, typename T, typename A>
|
||||
inline void Unserialize(Stream& is, std::vector<T, A>& v, int nType, int nVersion)
|
||||
{
|
||||
Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental<T>());
|
||||
Unserialize_impl(is, v, nType, nVersion, std::is_fundamental<T>{});
|
||||
}
|
||||
|
||||
|
||||
@@ -705,7 +702,7 @@ struct ser_streamplaceholder
|
||||
|
||||
|
||||
|
||||
typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData;
|
||||
using CSerializeData = std::vector<char, zero_after_free_allocator<char>>;
|
||||
|
||||
/** Double ended buffer combining vector and stream-like interfaces.
|
||||
*
|
||||
@@ -1060,18 +1057,18 @@ public:
|
||||
|
||||
void fclose()
|
||||
{
|
||||
if (file != NULL && file != stdin && file != stdout && file != stderr)
|
||||
if (file != nullptr && file != stdin && file != stdout && file != stderr)
|
||||
::fclose(file);
|
||||
file = NULL;
|
||||
file = nullptr;
|
||||
}
|
||||
|
||||
FILE* release() { FILE* ret = file; file = NULL; return ret; }
|
||||
FILE* release() { FILE* ret = file; file = nullptr; return ret; }
|
||||
operator FILE*() { return file; }
|
||||
FILE* operator->() { return file; }
|
||||
FILE& operator*() { return *file; }
|
||||
FILE** operator&() { return &file; }
|
||||
FILE* operator=(FILE* pnew) { return file = pnew; }
|
||||
bool operator!() { return (file == NULL); }
|
||||
bool operator!() { return (file == nullptr); }
|
||||
|
||||
|
||||
//
|
||||
|
||||
+20
-22
@@ -47,8 +47,6 @@ Notes:
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#include <string>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
|
||||
#include "base58.h"
|
||||
#include "crypto_ecdh.h"
|
||||
@@ -99,7 +97,7 @@ uint32_t nPeerIdCounter = 1;
|
||||
CCriticalSection cs_smsg;
|
||||
CCriticalSection cs_smsgDB;
|
||||
|
||||
rocksdb::DB *smsgDB = NULL;
|
||||
rocksdb::DB *smsgDB = nullptr;
|
||||
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
@@ -292,12 +290,12 @@ bool SecureMsgAllDigits(const std::string& value)
|
||||
|
||||
bool SecureMsgParseBucketFilename(const std::string& fileName, int64_t& bucket, uint32_t& fileIndex, bool& fWalletLocked)
|
||||
{
|
||||
if (!boost::algorithm::ends_with(fileName, ".dat"))
|
||||
if (!fileName.ends_with(".dat"))
|
||||
return false;
|
||||
|
||||
std::string baseName = fileName.substr(0, fileName.size() - 4);
|
||||
fWalletLocked = false;
|
||||
if (boost::algorithm::ends_with(baseName, "_wl"))
|
||||
if (baseName.ends_with("_wl"))
|
||||
{
|
||||
fWalletLocked = true;
|
||||
baseName.erase(baseName.size() - 3);
|
||||
@@ -366,7 +364,7 @@ void SecureMsgGetBucketFiles(const fs::path& pathSmsgDir, int64_t bucket, bool f
|
||||
|| fFileWalletLocked != fWalletLocked)
|
||||
continue;
|
||||
|
||||
bucketFiles.push_back(std::make_pair(fileIndex, (*itd).path()));
|
||||
bucketFiles.push_back({fileIndex, (*itd).path()});
|
||||
};
|
||||
|
||||
std::sort(bucketFiles.begin(), bucketFiles.end(),
|
||||
@@ -471,7 +469,7 @@ bool SecMsgCrypter::Encrypt(unsigned char* chPlaintext, uint32_t nPlain, std::ve
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, &chKey[0], &chIV[0]);
|
||||
if (fOk) fOk = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, &chKey[0], &chIV[0]);
|
||||
if (fOk) fOk = EVP_EncryptUpdate(ctx, &vchCiphertext[0], &nCLen, chPlaintext, nLen);
|
||||
if (fOk) fOk = EVP_EncryptFinal_ex(ctx, (&vchCiphertext[0])+nCLen, &nFLen);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
@@ -500,7 +498,7 @@ bool SecMsgCrypter::Decrypt(unsigned char* chCiphertext, uint32_t nCipher, std::
|
||||
|
||||
bool fOk = true;
|
||||
|
||||
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, &chKey[0], &chIV[0]);
|
||||
if (fOk) fOk = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, &chKey[0], &chIV[0]);
|
||||
if (fOk) fOk = EVP_DecryptUpdate(ctx, &vchPlaintext[0], &nPLen, &chCiphertext[0], nCipher);
|
||||
if (fOk) fOk = EVP_DecryptFinal_ex(ctx, (&vchPlaintext[0])+nPLen, &nFLen);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
@@ -626,7 +624,7 @@ bool SecMsgDB::TxnCommit()
|
||||
writeOptions.sync = true;
|
||||
rocksdb::Status status = pdb->Write(writeOptions, activeBatch);
|
||||
delete activeBatch;
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
pendingBatch.clear();
|
||||
|
||||
if (!status.ok())
|
||||
@@ -641,7 +639,7 @@ bool SecMsgDB::TxnCommit()
|
||||
bool SecMsgDB::TxnAbort()
|
||||
{
|
||||
delete activeBatch;
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
pendingBatch.clear();
|
||||
return true;
|
||||
};
|
||||
@@ -1344,7 +1342,7 @@ int SecureMsgReadIni()
|
||||
continue;
|
||||
|
||||
if (!(pName = strtok(cLine, "="))
|
||||
|| !(pValue = strtok(NULL, "=")))
|
||||
|| !(pValue = strtok(nullptr, "=")))
|
||||
continue;
|
||||
|
||||
if (strcmp(pName, "newAddressRecv") == 0)
|
||||
@@ -1478,8 +1476,8 @@ bool SecureMsgStart(bool fDontStart, bool fScanChain)
|
||||
};
|
||||
|
||||
// -- start threads
|
||||
if (!NewThread(ThreadSecureMsg, NULL)
|
||||
|| !NewThread(ThreadSecureMsgPow, NULL))
|
||||
if (!NewThread(ThreadSecureMsg, nullptr)
|
||||
|| !NewThread(ThreadSecureMsgPow, nullptr))
|
||||
{
|
||||
printf("SecureMsg could not start threads, secure messaging disabled.\n");
|
||||
fSecMsgEnabled = false;
|
||||
@@ -1509,7 +1507,7 @@ bool SecureMsgShutdown()
|
||||
{
|
||||
LOCK(cs_smsgDB);
|
||||
delete smsgDB;
|
||||
smsgDB = NULL;
|
||||
smsgDB = nullptr;
|
||||
};
|
||||
|
||||
// -- main program will wait 5 seconds for threads to terminate.
|
||||
@@ -1553,8 +1551,8 @@ bool SecureMsgEnable()
|
||||
}; // LOCK(cs_smsg);
|
||||
|
||||
// -- start threads
|
||||
if (!NewThread(ThreadSecureMsg, NULL)
|
||||
|| !NewThread(ThreadSecureMsgPow, NULL))
|
||||
if (!NewThread(ThreadSecureMsg, nullptr)
|
||||
|| !NewThread(ThreadSecureMsgPow, nullptr))
|
||||
{
|
||||
printf("SecureMsgEnable could not start threads, secure messaging disabled.\n");
|
||||
fSecMsgEnabled = false;
|
||||
@@ -1624,7 +1622,7 @@ bool SecureMsgDisable()
|
||||
{
|
||||
LOCK(cs_smsgDB);
|
||||
delete smsgDB;
|
||||
smsgDB = NULL;
|
||||
smsgDB = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -2455,7 +2453,7 @@ bool SecureMsgScanBlockChain()
|
||||
if (lockMain)
|
||||
{
|
||||
CBlockIndex *pindexScan = pindexGenesisBlock;
|
||||
if (pindexScan == NULL)
|
||||
if (pindexScan == nullptr)
|
||||
{
|
||||
printf("Error: pindexGenesisBlock not set.\n");
|
||||
return false;
|
||||
@@ -3521,7 +3519,7 @@ int SecureMsgValidate(unsigned char *pHeader, unsigned char *pPayload, uint32_t
|
||||
HMAC_CTX *ctx = HMAC_CTX_new();
|
||||
|
||||
unsigned int nBytes;
|
||||
if (!HMAC_Init_ex(ctx, &civ[0], 32, EVP_sha256(), NULL)
|
||||
if (!HMAC_Init_ex(ctx, &civ[0], 32, EVP_sha256(), nullptr)
|
||||
|| !HMAC_Update(ctx, (unsigned char*) pHeader+4, SMSG_HDR_LEN-4)
|
||||
|| !HMAC_Update(ctx, (unsigned char*) pPayload, nPayload)
|
||||
|| !HMAC_Update(ctx, pPayload, nPayload)
|
||||
@@ -3598,7 +3596,7 @@ int SecureMsgSetHash(unsigned char *pHeader, unsigned char *pPayload, uint32_t n
|
||||
memcpy(civ+i, &nonse, 4);
|
||||
|
||||
unsigned int nBytes;
|
||||
if (!HMAC_Init_ex(ctx, &civ[0], 32, EVP_sha256(), NULL)
|
||||
if (!HMAC_Init_ex(ctx, &civ[0], 32, EVP_sha256(), nullptr)
|
||||
|| !HMAC_Update(ctx, (unsigned char*) pHeader+4, SMSG_HDR_LEN-4)
|
||||
|| !HMAC_Update(ctx, (unsigned char*) pPayload, nPayload)
|
||||
|| !HMAC_Update(ctx, pPayload, nPayload)
|
||||
@@ -3923,7 +3921,7 @@ int SecureMsgEncrypt(SecureMessage& smsg, std::string& addressFrom, std::string&
|
||||
unsigned int nBytes = 32;
|
||||
HMAC_CTX *ctx = HMAC_CTX_new();
|
||||
|
||||
if (!HMAC_Init_ex(ctx, &key_m[0], 32, EVP_sha256(), NULL)
|
||||
if (!HMAC_Init_ex(ctx, &key_m[0], 32, EVP_sha256(), nullptr)
|
||||
|| !HMAC_Update(ctx, (unsigned char*) &smsg.timestamp, sizeof(smsg.timestamp))
|
||||
|| !HMAC_Update(ctx, &vchCiphertext[0], vchCiphertext.size())
|
||||
|| !HMAC_Final(ctx, smsg.mac, &nBytes)
|
||||
@@ -4233,7 +4231,7 @@ int SecureMsgDecrypt(bool fTestOnly, std::string& address, unsigned char *pHeade
|
||||
unsigned int nBytes = 32;
|
||||
HMAC_CTX *ctx = HMAC_CTX_new();
|
||||
|
||||
if (!HMAC_Init_ex(ctx, &key_m[0], 32, EVP_sha256(), NULL)
|
||||
if (!HMAC_Init_ex(ctx, &key_m[0], 32, EVP_sha256(), nullptr)
|
||||
|| !HMAC_Update(ctx, (unsigned char*) &psmsg->timestamp, sizeof(psmsg->timestamp))
|
||||
|| !HMAC_Update(ctx, pPayload, nPayload)
|
||||
|| !HMAC_Final(ctx, MAC, &nBytes)
|
||||
|
||||
+3
-3
@@ -74,14 +74,14 @@ public:
|
||||
SecureMessage()
|
||||
{
|
||||
nPayload = 0;
|
||||
pPayload = NULL;
|
||||
pPayload = nullptr;
|
||||
};
|
||||
|
||||
~SecureMessage()
|
||||
{
|
||||
if (pPayload)
|
||||
delete[] pPayload;
|
||||
pPayload = NULL;
|
||||
pPayload = nullptr;
|
||||
};
|
||||
|
||||
unsigned char hash[4];
|
||||
@@ -294,7 +294,7 @@ class SecMsgDB
|
||||
public:
|
||||
SecMsgDB()
|
||||
{
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
};
|
||||
|
||||
~SecMsgDB()
|
||||
|
||||
+4
-4
@@ -46,7 +46,7 @@ private:
|
||||
int sourceLine;
|
||||
};
|
||||
|
||||
typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
|
||||
using LockStack = std::vector<std::pair<void*, CLockLocation>>;
|
||||
|
||||
static std::mutex dd_mutex;
|
||||
static std::map<std::pair<void*, void*>, LockStack> lockorders;
|
||||
@@ -80,18 +80,18 @@ static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
|
||||
if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
|
||||
dd_mutex.lock();
|
||||
|
||||
(*lockstack).push_back(std::make_pair(c, locklocation));
|
||||
(*lockstack).push_back({c, locklocation});
|
||||
|
||||
if (!fTry) {
|
||||
for (const auto& i : (*lockstack)) {
|
||||
if (i.first == c) break;
|
||||
|
||||
std::pair<void*, void*> p1 = std::make_pair(i.first, c);
|
||||
std::pair<void*, void*> p1 = {i.first, c};
|
||||
if (lockorders.count(p1))
|
||||
continue;
|
||||
lockorders[p1] = (*lockstack);
|
||||
|
||||
std::pair<void*, void*> p2 = std::make_pair(c, i.first);
|
||||
std::pair<void*, void*> p2 = {c, i.first};
|
||||
if (lockorders.count(p2))
|
||||
{
|
||||
potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
|
||||
|
||||
+5
-5
@@ -9,10 +9,10 @@
|
||||
#include <condition_variable>
|
||||
|
||||
/** Recursive mutex: supports recursive locking, but no waiting */
|
||||
typedef std::recursive_mutex CCriticalSection;
|
||||
using CCriticalSection = std::recursive_mutex;
|
||||
|
||||
/** Plain mutex: supports waiting but not recursive locking */
|
||||
typedef std::mutex CWaitableCriticalSection;
|
||||
using CWaitableCriticalSection = std::mutex;
|
||||
|
||||
#ifdef DEBUG_LOCKORDER
|
||||
void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
|
||||
@@ -26,7 +26,7 @@ void static inline LeaveCritical() {}
|
||||
void PrintLockContention(const char* pszName, const char* pszFile, int nLine);
|
||||
#endif
|
||||
|
||||
/** Wrapper around boost::unique_lock<Mutex> */
|
||||
/** Wrapper around std::unique_lock<Mutex> */
|
||||
template<typename Mutex>
|
||||
class CMutexLock
|
||||
{
|
||||
@@ -182,11 +182,11 @@ public:
|
||||
grant.Release();
|
||||
grant.sem = sem;
|
||||
grant.fHaveGrant = fHaveGrant;
|
||||
sem = NULL;
|
||||
sem = nullptr;
|
||||
fHaveGrant = false;
|
||||
}
|
||||
|
||||
CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {}
|
||||
CSemaphoreGrant() : sem(nullptr), fHaveGrant(false) {}
|
||||
|
||||
CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) {
|
||||
if (fTry)
|
||||
|
||||
@@ -0,0 +1,664 @@
|
||||
// Copyright (c) 2026 The Triangles developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "syncmanager.h"
|
||||
|
||||
#include "bignum.h"
|
||||
#include "checkpoints.h"
|
||||
#include "main.h"
|
||||
#include "net.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
struct CSyncManager::HeaderNode
|
||||
{
|
||||
CBlock header;
|
||||
int nHeight;
|
||||
uint256 nChainTrust;
|
||||
bool fRequested;
|
||||
int64_t nLastRequestTime;
|
||||
int64_t nFirstRequestTime;
|
||||
int64_t nInsertTime;
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
static const unsigned int MAX_HEADER_SYNC_CACHE = 15000;
|
||||
static const size_t HEADER_REDUNDANT_PEER_THRESHOLD = 4;
|
||||
static const int64_t HEADER_REQUEST_TIMEOUT_MICROS = 60 * 1000000;
|
||||
static const int64_t HEADER_REDUNDANT_REQUEST_MICROS = 5 * 1000000;
|
||||
static const int64_t HEADER_SYNC_TTL_MICROS = 15 * 60 * 1000000;
|
||||
|
||||
std::map<uint256, CSyncManager::HeaderNode> mapHeaders;
|
||||
uint256 hashBestHeader = 0;
|
||||
int64_t nLastNewHeaderTime = 0;
|
||||
}
|
||||
|
||||
CSyncManager g_syncManager;
|
||||
|
||||
bool CSyncManager::HaveHeader(const uint256& hash) const
|
||||
{
|
||||
return mapHeaders.count(hash) != 0;
|
||||
}
|
||||
|
||||
uint256 CSyncManager::GetBestHeader() const
|
||||
{
|
||||
return hashBestHeader;
|
||||
}
|
||||
|
||||
std::size_t CSyncManager::GetHeaderCount() const
|
||||
{
|
||||
return mapHeaders.size();
|
||||
}
|
||||
|
||||
uint256 CSyncManager::GetHeaderTrust(unsigned int nBits) const
|
||||
{
|
||||
CBigNum bnTarget;
|
||||
bnTarget.SetCompact(nBits);
|
||||
|
||||
if (bnTarget <= 0)
|
||||
return 0;
|
||||
|
||||
return ((CBigNum(1) << 256) / (bnTarget + 1)).getuint256();
|
||||
}
|
||||
|
||||
bool CSyncManager::GetKnownHeaderState(const uint256& hash, int& nHeight, uint256& nChainTrust) const
|
||||
{
|
||||
std::map<uint256, CBlockIndex*>::const_iterator miBlock = mapBlockIndex.find(hash);
|
||||
if (miBlock != mapBlockIndex.end())
|
||||
{
|
||||
nHeight = miBlock->second->nHeight;
|
||||
nChainTrust = miBlock->second->nChainTrust;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<uint256, HeaderNode>::const_iterator miHeader = mapHeaders.find(hash);
|
||||
if (miHeader != mapHeaders.end())
|
||||
{
|
||||
nHeight = miHeader->second.nHeight;
|
||||
nChainTrust = miHeader->second.nChainTrust;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CSyncManager::GetPrevHash(const uint256& hash, uint256& hashPrev) const
|
||||
{
|
||||
std::map<uint256, HeaderNode>::const_iterator miHeader = mapHeaders.find(hash);
|
||||
if (miHeader != mapHeaders.end())
|
||||
{
|
||||
hashPrev = miHeader->second.header.hashPrevBlock;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<uint256, CBlockIndex*>::const_iterator miBlock = mapBlockIndex.find(hash);
|
||||
if (miBlock != mapBlockIndex.end() && miBlock->second->pprev)
|
||||
{
|
||||
hashPrev = miBlock->second->pprev->GetBlockHash();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSyncManager::RecomputeBestHeader()
|
||||
{
|
||||
hashBestHeader = 0;
|
||||
uint256 nBestTrust = 0;
|
||||
|
||||
for (std::map<uint256, HeaderNode>::const_iterator it = mapHeaders.begin(); it != mapHeaders.end(); ++it)
|
||||
{
|
||||
if (hashBestHeader == 0 || it->second.nChainTrust > nBestTrust)
|
||||
{
|
||||
hashBestHeader = it->first;
|
||||
nBestTrust = it->second.nChainTrust;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSyncManager::PruneHeaders()
|
||||
{
|
||||
const int64_t nNow = GetTime() * 1000000;
|
||||
|
||||
if (mapHeaders.size() > MAX_HEADER_SYNC_CACHE / 2)
|
||||
{
|
||||
unsigned int nEvicted = 0;
|
||||
for (std::map<uint256, HeaderNode>::iterator it = mapHeaders.begin(); it != mapHeaders.end(); )
|
||||
{
|
||||
if (nNow - it->second.nInsertTime >= HEADER_SYNC_TTL_MICROS)
|
||||
{
|
||||
it = mapHeaders.erase(it);
|
||||
++nEvicted;
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
if (nEvicted > 0)
|
||||
{
|
||||
printf("IBD-DIAG: TTL-evicted %u stale sync headers, %u remain\n",
|
||||
nEvicted, (unsigned int)mapHeaders.size());
|
||||
RecomputeBestHeader();
|
||||
}
|
||||
}
|
||||
|
||||
if (mapHeaders.size() > MAX_HEADER_SYNC_CACHE)
|
||||
{
|
||||
printf("IBD-DIAG: sync header cache exceeded %u entries, evicting oldest\n", MAX_HEADER_SYNC_CACHE);
|
||||
while (mapHeaders.size() > MAX_HEADER_SYNC_CACHE * 3 / 4)
|
||||
{
|
||||
std::map<uint256, HeaderNode>::iterator oldest = mapHeaders.begin();
|
||||
for (std::map<uint256, HeaderNode>::iterator it = mapHeaders.begin(); it != mapHeaders.end(); ++it)
|
||||
{
|
||||
if (it->second.nInsertTime < oldest->second.nInsertTime)
|
||||
oldest = it;
|
||||
}
|
||||
mapHeaders.erase(oldest);
|
||||
}
|
||||
RecomputeBestHeader();
|
||||
}
|
||||
}
|
||||
|
||||
bool CSyncManager::AddHeaderNode(const CBlock& header, const uint256& hashHeader)
|
||||
{
|
||||
if (mapBlockIndex.count(hashHeader) || mapHeaders.count(hashHeader))
|
||||
return true;
|
||||
|
||||
if (!header.vtx.empty())
|
||||
{
|
||||
printf("IBD-DIAG: header rejected (has vtx) hash=%s\n", hashHeader.ToString().substr(0,20).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.GetBlockTime() > GetTime() + 15 * 60)
|
||||
{
|
||||
printf("IBD-DIAG: header rejected (future time) hash=%s time=%u\n",
|
||||
hashHeader.ToString().substr(0,20).c_str(), header.nTime);
|
||||
return false;
|
||||
}
|
||||
|
||||
int nPrevHeight = -1;
|
||||
uint256 nPrevChainTrust = 0;
|
||||
if (!GetKnownHeaderState(header.hashPrevBlock, nPrevHeight, nPrevChainTrust))
|
||||
{
|
||||
printf("IBD-DIAG: header rejected (prev unknown) hash=%s prevHash=%s\n",
|
||||
hashHeader.ToString().substr(0,20).c_str(),
|
||||
header.hashPrevBlock.ToString().substr(0,20).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const int nHeight = nPrevHeight + 1;
|
||||
if (nHeight <= CUTOFF_POW_BLOCK && !CheckProofOfWork(hashHeader, header.nBits))
|
||||
{
|
||||
printf("IBD-DIAG: header PoW FAILED at height %d hash=%s nBits=%08x prevHash=%s\n",
|
||||
nHeight, hashHeader.ToString().substr(0,20).c_str(), header.nBits,
|
||||
header.hashPrevBlock.ToString().substr(0,20).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
HeaderNode node;
|
||||
node.header = header;
|
||||
node.nHeight = nHeight;
|
||||
node.nChainTrust = nPrevChainTrust + GetHeaderTrust(header.nBits);
|
||||
node.fRequested = false;
|
||||
node.nLastRequestTime = 0;
|
||||
node.nFirstRequestTime = 0;
|
||||
node.nInsertTime = GetTime() * 1000000;
|
||||
|
||||
mapHeaders.insert({hashHeader, node});
|
||||
|
||||
if (hashBestHeader == 0 || node.nChainTrust > mapHeaders[hashBestHeader].nChainTrust)
|
||||
hashBestHeader = hashHeader;
|
||||
|
||||
PruneHeaders();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<uint256> CSyncManager::GetDownloadPath(uint256 hashTip) const
|
||||
{
|
||||
std::vector<uint256> vPath;
|
||||
|
||||
while (hashTip != 0 && !mapBlockIndex.count(hashTip))
|
||||
{
|
||||
std::map<uint256, HeaderNode>::const_iterator mi = mapHeaders.find(hashTip);
|
||||
if (mi == mapHeaders.end())
|
||||
break;
|
||||
|
||||
vPath.push_back(hashTip);
|
||||
hashTip = mi->second.header.hashPrevBlock;
|
||||
}
|
||||
|
||||
std::reverse(vPath.begin(), vPath.end());
|
||||
return vPath;
|
||||
}
|
||||
|
||||
unsigned int CSyncManager::CountInFlight() const
|
||||
{
|
||||
const int64_t nNow = GetTime() * 1000000;
|
||||
unsigned int nInFlight = 0;
|
||||
for (std::map<uint256, HeaderNode>::const_iterator it = mapHeaders.begin(); it != mapHeaders.end(); ++it)
|
||||
{
|
||||
if (it->second.fRequested && nNow - it->second.nLastRequestTime < HEADER_REQUEST_TIMEOUT_MICROS)
|
||||
++nInFlight;
|
||||
}
|
||||
return nInFlight;
|
||||
}
|
||||
|
||||
unsigned int CSyncManager::GetPlannerDepth() const
|
||||
{
|
||||
if (hashBestHeader == 0)
|
||||
return 0;
|
||||
|
||||
return (unsigned int)GetDownloadPath(hashBestHeader).size();
|
||||
}
|
||||
|
||||
int CSyncManager::GetPlannerHeight() const
|
||||
{
|
||||
if (hashBestHeader == 0)
|
||||
return pindexBest ? pindexBest->nHeight : -1;
|
||||
|
||||
std::map<uint256, HeaderNode>::const_iterator mi = mapHeaders.find(hashBestHeader);
|
||||
if (mi == mapHeaders.end())
|
||||
return pindexBest ? pindexBest->nHeight : -1;
|
||||
|
||||
return mi->second.nHeight;
|
||||
}
|
||||
|
||||
int64_t CSyncManager::GetRequestTime(const uint256& hashBlock) const
|
||||
{
|
||||
std::map<uint256, HeaderNode>::const_iterator mi = mapHeaders.find(hashBlock);
|
||||
if (mi == mapHeaders.end())
|
||||
return 0;
|
||||
return mi->second.nFirstRequestTime;
|
||||
}
|
||||
|
||||
void CSyncManager::BlockAccepted(const uint256& hashBlock)
|
||||
{
|
||||
std::map<uint256, HeaderNode>::iterator mi = mapHeaders.find(hashBlock);
|
||||
if (mi == mapHeaders.end())
|
||||
return;
|
||||
|
||||
mapHeaders.erase(mi);
|
||||
if (hashBestHeader == hashBlock)
|
||||
RecomputeBestHeader();
|
||||
}
|
||||
|
||||
void CSyncManager::ContinueHeaders(CNode* pfrom, const uint256& hashTip)
|
||||
{
|
||||
if (!pfrom || hashTip == 0)
|
||||
return;
|
||||
|
||||
std::vector<uint256> vHave;
|
||||
uint256 hashWalk = hashTip;
|
||||
int nStep = 1;
|
||||
|
||||
while (hashWalk != 0)
|
||||
{
|
||||
vHave.push_back(hashWalk);
|
||||
|
||||
for (int i = 0; i < nStep && hashWalk != 0; ++i)
|
||||
{
|
||||
uint256 hashPrev = 0;
|
||||
if (!GetPrevHash(hashWalk, hashPrev))
|
||||
hashWalk = 0;
|
||||
else
|
||||
hashWalk = hashPrev;
|
||||
}
|
||||
|
||||
if (vHave.size() > 10)
|
||||
nStep *= 2;
|
||||
}
|
||||
|
||||
vHave.push_back(!fTestNet ? hashGenesisBlockOfficial : hashGenesisBlockTestNet);
|
||||
pfrom->PushMessage("getheaders", CBlockLocator(vHave), uint256(0));
|
||||
}
|
||||
|
||||
bool CSyncManager::RequestRefill(CNode* pfrom, uint256 hashTip, int64_t nMinIntervalSeconds, const char* pszReason)
|
||||
{
|
||||
if (!pfrom || pfrom->fClient || pfrom->nVersion == 0 || !IsInitialBlockDownload())
|
||||
return false;
|
||||
|
||||
const int64_t nNowSec = GetTime();
|
||||
if (nMinIntervalSeconds > 0 &&
|
||||
nNowSec - pfrom->nLastIbdHeaderRequest < nMinIntervalSeconds)
|
||||
return false;
|
||||
|
||||
uint256 hashLocatorTip = hashTip;
|
||||
if (hashLocatorTip == 0 ||
|
||||
(!mapBlockIndex.count(hashLocatorTip) && !mapHeaders.count(hashLocatorTip)))
|
||||
{
|
||||
hashLocatorTip = hashBestHeader;
|
||||
}
|
||||
|
||||
if (hashLocatorTip != 0 && (!pindexBest || hashLocatorTip != pindexBest->GetBlockHash()))
|
||||
{
|
||||
ContinueHeaders(pfrom, hashLocatorTip);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pindexBest)
|
||||
return false;
|
||||
|
||||
pfrom->pindexLastGetHeadersBegin = NULL;
|
||||
pfrom->PushGetHeaders(pindexBest, uint256(0));
|
||||
hashLocatorTip = pindexBest->GetBlockHash();
|
||||
}
|
||||
|
||||
pfrom->nLastIbdHeaderRequest = nNowSec;
|
||||
printf("IBD-DIAG: %s getheaders to peer=%s locator=%s plannerDepth=%u inflight=%u\n",
|
||||
pszReason, pfrom->addr.ToString().c_str(),
|
||||
hashLocatorTip.ToString().substr(0,20).c_str(),
|
||||
GetPlannerDepth(), CountInFlight());
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int CSyncManager::RequestRefillAllPeers(uint256 hashTip, int64_t nMinIntervalSeconds, const char* pszReason)
|
||||
{
|
||||
std::vector<CNode*> vEligiblePeers;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (!pnode->fClient && pnode->nVersion != 0 && !pnode->fDisconnect)
|
||||
vEligiblePeers.push_back(pnode);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int nRequested = 0;
|
||||
for (CNode* pnode : vEligiblePeers)
|
||||
{
|
||||
if (RequestRefill(pnode, hashTip, nMinIntervalSeconds, pszReason))
|
||||
++nRequested;
|
||||
}
|
||||
|
||||
return nRequested;
|
||||
}
|
||||
|
||||
unsigned int CSyncManager::QueueBlocksParallel(unsigned int nWindow)
|
||||
{
|
||||
if (hashBestHeader == 0)
|
||||
return 0;
|
||||
|
||||
const std::vector<uint256> vPath = GetDownloadPath(hashBestHeader);
|
||||
if (vPath.empty())
|
||||
return 0;
|
||||
|
||||
std::vector<CNode*> vEligiblePeers;
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
for (CNode* pnode : vNodes)
|
||||
{
|
||||
if (!pnode->fClient && pnode->nVersion != 0 && !pnode->fDisconnect)
|
||||
vEligiblePeers.push_back(pnode);
|
||||
}
|
||||
}
|
||||
|
||||
if (vEligiblePeers.empty())
|
||||
return 0;
|
||||
|
||||
const int64_t nNow = GetTime() * 1000000;
|
||||
unsigned int nInFlight = CountInFlight();
|
||||
unsigned int nQueued = 0;
|
||||
unsigned int nPeerIndex = 0;
|
||||
|
||||
std::sort(vEligiblePeers.begin(), vEligiblePeers.end(),
|
||||
[](const CNode* a, const CNode* b) {
|
||||
return a->nBlocksDelivered > b->nBlocksDelivered;
|
||||
});
|
||||
|
||||
std::vector<CNode*> vWeightedPeers;
|
||||
for (size_t i = 0; i < vEligiblePeers.size(); i++)
|
||||
{
|
||||
int nWeight = (i == 0) ? 3 : (i == 1) ? 2 : 1;
|
||||
for (int w = 0; w < nWeight; w++)
|
||||
vWeightedPeers.push_back(vEligiblePeers[i]);
|
||||
}
|
||||
|
||||
int64_t nAdaptiveTimeout = HEADER_REQUEST_TIMEOUT_MICROS;
|
||||
{
|
||||
int64_t nTotalLatency = 0;
|
||||
int nPeersWithLatency = 0;
|
||||
for (const CNode* pnode : vEligiblePeers)
|
||||
{
|
||||
if (pnode->nAvgBlockLatencyUs > 0)
|
||||
{
|
||||
nTotalLatency += pnode->nAvgBlockLatencyUs;
|
||||
++nPeersWithLatency;
|
||||
}
|
||||
}
|
||||
if (nPeersWithLatency > 0)
|
||||
{
|
||||
int64_t nAvgLatency = nTotalLatency / nPeersWithLatency;
|
||||
nAdaptiveTimeout = std::max((int64_t)(10 * 1000000),
|
||||
std::min((int64_t)(60 * 1000000), nAvgLatency * 5));
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<uint256>::const_iterator it = vPath.begin(); it != vPath.end(); ++it)
|
||||
{
|
||||
if (nInFlight + nQueued >= nWindow)
|
||||
break;
|
||||
|
||||
std::map<uint256, HeaderNode>::iterator mi = mapHeaders.find(*it);
|
||||
if (mi == mapHeaders.end())
|
||||
continue;
|
||||
|
||||
bool fNeedsRequest = false;
|
||||
if (!mi->second.fRequested)
|
||||
fNeedsRequest = true;
|
||||
else if (nNow - mi->second.nLastRequestTime >= nAdaptiveTimeout)
|
||||
fNeedsRequest = true;
|
||||
else if (nNow - mi->second.nLastRequestTime >= HEADER_REDUNDANT_REQUEST_MICROS)
|
||||
fNeedsRequest = true;
|
||||
|
||||
if (!fNeedsRequest)
|
||||
continue;
|
||||
|
||||
CNode* pnode = vWeightedPeers[nPeerIndex % vWeightedPeers.size()];
|
||||
pnode->AskFor(CInv(MSG_BLOCK, *it));
|
||||
|
||||
if (IsInitialBlockDownload() &&
|
||||
vWeightedPeers.size() >= 2 &&
|
||||
vWeightedPeers.size() < HEADER_REDUNDANT_PEER_THRESHOLD &&
|
||||
!mi->second.fRequested)
|
||||
{
|
||||
CNode* pnode2 = vWeightedPeers[(nPeerIndex + 1) % vWeightedPeers.size()];
|
||||
if (pnode2 != pnode)
|
||||
pnode2->AskFor(CInv(MSG_BLOCK, *it));
|
||||
}
|
||||
|
||||
if (!mi->second.fRequested || nNow - mi->second.nLastRequestTime >= HEADER_REQUEST_TIMEOUT_MICROS)
|
||||
{
|
||||
if (!mi->second.fRequested)
|
||||
mi->second.nFirstRequestTime = nNow;
|
||||
mi->second.fRequested = true;
|
||||
mi->second.nLastRequestTime = nNow;
|
||||
}
|
||||
|
||||
++nQueued;
|
||||
++nPeerIndex;
|
||||
}
|
||||
|
||||
if (nQueued > 0)
|
||||
printf("IBD-DIAG: sync manager queued %u blocks across %zu peers (window=%u, inflight=%u)\n",
|
||||
nQueued, vEligiblePeers.size(), nWindow, nInFlight);
|
||||
|
||||
return nQueued;
|
||||
}
|
||||
|
||||
bool CSyncManager::ProcessHeaders(CNode* pfrom, const std::vector<CBlock>& vHeaders)
|
||||
{
|
||||
if (vHeaders.size() > 2000)
|
||||
{
|
||||
pfrom->Misbehaving(20);
|
||||
return error("message headers size() = %" PRIszu "", vHeaders.size());
|
||||
}
|
||||
|
||||
uint256 hashChainTip = 0;
|
||||
int nNewHeaders = 0;
|
||||
for (const CBlock& header : vHeaders)
|
||||
{
|
||||
if (!header.vtx.empty())
|
||||
{
|
||||
pfrom->Misbehaving(20);
|
||||
return error("headers message includes transactions");
|
||||
}
|
||||
|
||||
const uint256 hashHeader = header.GetHash();
|
||||
if (mapBlockIndex.count(hashHeader) || mapHeaders.count(hashHeader))
|
||||
{
|
||||
hashChainTip = hashHeader;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hashChainTip != 0)
|
||||
{
|
||||
if (header.hashPrevBlock != hashChainTip)
|
||||
{
|
||||
pfrom->Misbehaving(20);
|
||||
return error("non-continuous headers sequence");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(header.hashPrevBlock);
|
||||
if (miPrev == mapBlockIndex.end() && !mapHeaders.count(header.hashPrevBlock))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!AddHeaderNode(header, hashHeader))
|
||||
{
|
||||
pfrom->Misbehaving(20);
|
||||
return error("invalid header sequence");
|
||||
}
|
||||
|
||||
hashChainTip = hashHeader;
|
||||
nNewHeaders++;
|
||||
}
|
||||
|
||||
int nRequested = 0;
|
||||
if (hashBestHeader != 0)
|
||||
nRequested = QueueBlocksParallel(HEADER_DOWNLOAD_WINDOW);
|
||||
|
||||
if (nNewHeaders > 0)
|
||||
nLastNewHeaderTime = GetTime();
|
||||
|
||||
if (nNewHeaders > 0 || nRequested > 0)
|
||||
printf("IBD-DIAG: accepted %d new headers, queued %d blocks from %zu headers (peer=%s bestHeader=%s)\n",
|
||||
nNewHeaders, nRequested, vHeaders.size(), pfrom->addr.ToString().c_str(),
|
||||
hashBestHeader.ToString().substr(0,20).c_str());
|
||||
|
||||
if (vHeaders.size() >= 2000)
|
||||
{
|
||||
if (IsInitialBlockDownload() && hashChainTip != 0)
|
||||
ContinueHeaders(pfrom, hashChainTip);
|
||||
else
|
||||
pfrom->PushGetBlocks(pindexBest, uint256(0));
|
||||
}
|
||||
else if (IsInitialBlockDownload() && nNewHeaders > 0 && hashChainTip != 0)
|
||||
{
|
||||
ContinueHeaders(pfrom, hashChainTip);
|
||||
}
|
||||
else if (IsInitialBlockDownload())
|
||||
{
|
||||
const unsigned int nPlannerDepth = GetPlannerDepth();
|
||||
if (nPlannerDepth <= HEADER_SYNC_LOW_WATER)
|
||||
RequestRefill(
|
||||
pfrom, (hashChainTip != 0) ? hashChainTip : hashBestHeader,
|
||||
HEADER_SYNC_REFILL_MIN_INTERVAL_SECONDS,
|
||||
(nPlannerDepth == 0) ? "headers planner empty" : "headers planner low-water");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSyncManager::TrackBlockDelivery(CNode* pfrom, const uint256& hashBlock)
|
||||
{
|
||||
if (!pfrom)
|
||||
return;
|
||||
|
||||
pfrom->nBlocksDelivered++;
|
||||
if (nBestHeight > pfrom->nBestKnownHeight)
|
||||
pfrom->nBestKnownHeight = nBestHeight;
|
||||
|
||||
int64_t nRequestTime = GetRequestTime(hashBlock);
|
||||
if (nRequestTime > 0)
|
||||
{
|
||||
int64_t nLatency = GetTime() * 1000000 - nRequestTime;
|
||||
if (nLatency > 0)
|
||||
{
|
||||
if (pfrom->nAvgBlockLatencyUs == 0)
|
||||
pfrom->nAvgBlockLatencyUs = nLatency;
|
||||
else
|
||||
pfrom->nAvgBlockLatencyUs = (pfrom->nAvgBlockLatencyUs * 7 + nLatency) / 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSyncManager::Tick(CNode* pto, int nHighestInvWalk, const uint256& hashHighestInvWalk)
|
||||
{
|
||||
if (!pto || pto->fClient || pto->nVersion == 0 || !IsInitialBlockDownload())
|
||||
return;
|
||||
|
||||
const int64_t nNowSec = GetTime();
|
||||
const unsigned int nPlannerDepth = GetPlannerDepth();
|
||||
const unsigned int nInFlight = CountInFlight();
|
||||
static int64_t nLastHeaderPlannerControl = 0;
|
||||
static int64_t nLastHeaderWatchdog = 0;
|
||||
static int64_t nLastBlockPlannerControl = 0;
|
||||
|
||||
if (nLastNewHeaderTime == 0)
|
||||
nLastNewHeaderTime = nNowSec;
|
||||
|
||||
if (nNowSec - nLastHeaderPlannerControl >= HEADER_SYNC_CONTROL_INTERVAL_SECONDS &&
|
||||
nPlannerDepth < HEADER_SYNC_LOW_WATER &&
|
||||
nInFlight < HEADER_SYNC_TARGET_INFLIGHT)
|
||||
{
|
||||
const unsigned int nRefilled = RequestRefillAllPeers(
|
||||
hashBestHeader, HEADER_SYNC_REFILL_MIN_INTERVAL_SECONDS,
|
||||
"control-loop");
|
||||
if (nRefilled > 0)
|
||||
printf("IBD-DIAG: control-loop refill from %u peers (plannerDepth=%u inflight=%u target=%u)\n",
|
||||
nRefilled, nPlannerDepth, nInFlight, HEADER_SYNC_TARGET_INFLIGHT);
|
||||
nLastHeaderPlannerControl = nNowSec;
|
||||
}
|
||||
|
||||
if (nNowSec - nLastHeaderWatchdog >= HEADER_SYNC_CONTROL_INTERVAL_SECONDS &&
|
||||
nNowSec - nLastNewHeaderTime >= HEADER_SYNC_WATCHDOG_SECONDS)
|
||||
{
|
||||
const unsigned int nRefilled = RequestRefillAllPeers(
|
||||
hashBestHeader, HEADER_SYNC_REFILL_MIN_INTERVAL_SECONDS,
|
||||
"headers-watchdog");
|
||||
if (nRefilled > 0)
|
||||
printf("IBD-DIAG: headers watchdog refill from %u peers after %llds without new headers (plannerDepth=%u inflight=%u)\n",
|
||||
nRefilled,
|
||||
(long long)(nNowSec - nLastNewHeaderTime),
|
||||
nPlannerDepth,
|
||||
nInFlight);
|
||||
nLastHeaderWatchdog = nNowSec;
|
||||
}
|
||||
|
||||
const int64_t nMinInterval = (mapHeaders.size() < HEADER_DOWNLOAD_WINDOW) ? 15 : 60;
|
||||
if (nNowSec - pto->nLastIbdHeaderRequest >= nMinInterval)
|
||||
RequestRefill(pto, hashBestHeader, nMinInterval, "heartbeat");
|
||||
|
||||
if (nNowSec - nLastBlockPlannerControl >= HEADER_SYNC_CONTROL_INTERVAL_SECONDS &&
|
||||
hashBestHeader != 0 &&
|
||||
nPlannerDepth > 0)
|
||||
{
|
||||
const unsigned int nRequeued = QueueBlocksParallel(HEADER_DOWNLOAD_WINDOW);
|
||||
if (nRequeued > 0)
|
||||
printf("IBD-DIAG: block-planner control queued %u block requests (plannerDepth=%u inflight=%u)\n",
|
||||
nRequeued, nPlannerDepth, nInFlight);
|
||||
nLastBlockPlannerControl = nNowSec;
|
||||
}
|
||||
|
||||
if (hashBestHeader == 0 && nHighestInvWalk > nBestHeight &&
|
||||
hashHighestInvWalk != 0 && mapBlockIndex.count(hashHighestInvWalk))
|
||||
{
|
||||
RequestRefill(pto, hashHighestInvWalk, HEADER_SYNC_REFILL_MIN_INTERVAL_SECONDS, "inv-walk bridge");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2026 The Triangles developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef TRIANGLES_SYNCMANAGER_H
|
||||
#define TRIANGLES_SYNCMANAGER_H
|
||||
|
||||
#include "uint256.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
class CBlock;
|
||||
class CInv;
|
||||
class CNode;
|
||||
|
||||
class CSyncManager
|
||||
{
|
||||
public:
|
||||
struct HeaderNode;
|
||||
|
||||
static constexpr unsigned int HEADER_DOWNLOAD_WINDOW = 1024;
|
||||
static constexpr unsigned int HEADER_SYNC_LOW_WATER = HEADER_DOWNLOAD_WINDOW / 4;
|
||||
static constexpr unsigned int HEADER_SYNC_TARGET_INFLIGHT = HEADER_DOWNLOAD_WINDOW / 2;
|
||||
static constexpr int64_t HEADER_SYNC_REFILL_MIN_INTERVAL_SECONDS = 5;
|
||||
static constexpr int64_t HEADER_SYNC_CONTROL_INTERVAL_SECONDS = 5;
|
||||
static constexpr int64_t HEADER_SYNC_WATCHDOG_SECONDS = 25;
|
||||
|
||||
bool HaveHeader(const uint256& hash) const;
|
||||
uint256 GetBestHeader() const;
|
||||
std::size_t GetHeaderCount() const;
|
||||
unsigned int CountInFlight() const;
|
||||
unsigned int GetPlannerDepth() const;
|
||||
int GetPlannerHeight() const;
|
||||
int64_t GetRequestTime(const uint256& hashBlock) const;
|
||||
|
||||
bool RequestRefill(CNode* pfrom, uint256 hashTip, int64_t nMinIntervalSeconds, const char* pszReason);
|
||||
unsigned int RequestRefillAllPeers(uint256 hashTip, int64_t nMinIntervalSeconds, const char* pszReason);
|
||||
unsigned int QueueBlocksParallel(unsigned int nWindow = HEADER_DOWNLOAD_WINDOW);
|
||||
bool ProcessHeaders(CNode* pfrom, const std::vector<CBlock>& vHeaders);
|
||||
void BlockAccepted(const uint256& hashBlock);
|
||||
void TrackBlockDelivery(CNode* pfrom, const uint256& hashBlock);
|
||||
void Tick(CNode* pto, int nHighestInvWalk, const uint256& hashHighestInvWalk);
|
||||
|
||||
private:
|
||||
uint256 GetHeaderTrust(unsigned int nBits) const;
|
||||
bool GetKnownHeaderState(const uint256& hash, int& nHeight, uint256& nChainTrust) const;
|
||||
bool GetPrevHash(const uint256& hash, uint256& hashPrev) const;
|
||||
void RecomputeBestHeader();
|
||||
void PruneHeaders();
|
||||
bool AddHeaderNode(const CBlock& header, const uint256& hashHeader);
|
||||
std::vector<uint256> GetDownloadPath(uint256 hashTip) const;
|
||||
void ContinueHeaders(CNode* pfrom, const uint256& hashTip);
|
||||
};
|
||||
|
||||
extern CSyncManager g_syncManager;
|
||||
|
||||
#endif // TRIANGLES_SYNCMANAGER_H
|
||||
@@ -13,7 +13,7 @@ GetResults(CWalletDB& walletdb, std::map<int64_t, CAccountingEntry>& results)
|
||||
std::list<CAccountingEntry> aes;
|
||||
|
||||
results.clear();
|
||||
BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain) == DB_LOAD_OK);
|
||||
BOOST_CHECK(walletdb.ReorderTransactions(pwalletMain.get()) == DB_LOAD_OK);
|
||||
walletdb.ListAccountCreditDebit("", aes);
|
||||
for (CAccountingEntry& ae : aes)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ struct {
|
||||
// NOTE: These tests rely on CreateNewBlock doing its own self-validation!
|
||||
BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
{
|
||||
CReserveKey reservekey(pwalletMain);
|
||||
CReserveKey reservekey(pwalletMain.get());
|
||||
CBlock *pblock;
|
||||
CTransaction tx;
|
||||
CScript script;
|
||||
|
||||
@@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||
|
||||
{
|
||||
vector<valtype> solutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
CScript s;
|
||||
s << key[0].GetPubKey() << OP_CHECKSIG;
|
||||
BOOST_CHECK(Solver(s, whichType, solutions));
|
||||
@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||
}
|
||||
{
|
||||
vector<valtype> solutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
CScript s;
|
||||
s << OP_DUP << OP_HASH160 << key[0].GetPubKey().GetID() << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
BOOST_CHECK(Solver(s, whichType, solutions));
|
||||
@@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||
}
|
||||
{
|
||||
vector<valtype> solutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
CScript s;
|
||||
s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
|
||||
BOOST_CHECK(Solver(s, whichType, solutions));
|
||||
@@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||
}
|
||||
{
|
||||
vector<valtype> solutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
CScript s;
|
||||
s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
|
||||
BOOST_CHECK(Solver(s, whichType, solutions));
|
||||
@@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
|
||||
}
|
||||
{
|
||||
vector<valtype> solutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
CScript s;
|
||||
s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
|
||||
BOOST_CHECK(Solver(s, whichType, solutions));
|
||||
|
||||
@@ -54,7 +54,8 @@
|
||||
#endif
|
||||
|
||||
// Ensure we have the global wallet pointer
|
||||
extern CWallet* pwalletMain;
|
||||
#include <memory>
|
||||
extern std::unique_ptr<CWallet> pwalletMain;
|
||||
|
||||
// Static instance
|
||||
CTorV3Manager* CTorV3Manager::instance = nullptr;
|
||||
@@ -997,7 +998,7 @@ bool CTorV3Service::ValidateOnionAddress(const std::string& address)
|
||||
bool CTorV3Service::ExtractKeysFromHex(const std::string& privKeyHex, unsigned char* privKey, unsigned char* pubKey)
|
||||
{
|
||||
if (!privKey || !pubKey) {
|
||||
printf("ERROR: NULL pointers passed to ExtractKeysFromHex\n");
|
||||
printf("ERROR: nullptr pointers passed to ExtractKeysFromHex\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1063,7 +1064,7 @@ bool CTorV3Service::ExtractKeysFromHex(const std::string& privKeyHex, unsigned c
|
||||
bool CTorV3Service::DerivePublicKeyFromPrivate(const unsigned char* privateKey, unsigned char* publicKey)
|
||||
{
|
||||
if (!privateKey || !publicKey) {
|
||||
printf("ERROR: NULL pointer passed to DerivePublicKeyFromPrivate\n");
|
||||
printf("ERROR: nullptr pointer passed to DerivePublicKeyFromPrivate\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -75,8 +75,8 @@ CTorProcess::CTorProcess()
|
||||
, hiddenServiceEnabled(true)
|
||||
, running(false)
|
||||
#ifdef WIN32
|
||||
, hProcess(NULL)
|
||||
, hJob(NULL)
|
||||
, hProcess(nullptr)
|
||||
, hJob(nullptr)
|
||||
, processId(0)
|
||||
#else
|
||||
, processId(0)
|
||||
@@ -97,7 +97,7 @@ std::string CTorProcess::FindTorBinary()
|
||||
#ifdef WIN32
|
||||
// Same directory as the wallet executable
|
||||
char exePath[MAX_PATH];
|
||||
if (GetModuleFileNameA(NULL, exePath, MAX_PATH)) {
|
||||
if (GetModuleFileNameA(nullptr, exePath, MAX_PATH)) {
|
||||
fs::path exeDir = fs::path(exePath).parent_path();
|
||||
candidates.push_back((exeDir / "tor.exe").string());
|
||||
candidates.push_back((exeDir / "tor" / "tor.exe").string());
|
||||
@@ -405,12 +405,12 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
std::string cmdLine = "\"" + torBinaryPath + "\" -f \"" + torrcPath + "\"";
|
||||
|
||||
if (!CreateProcessA(
|
||||
NULL,
|
||||
nullptr,
|
||||
(LPSTR)cmdLine.c_str(),
|
||||
NULL, NULL,
|
||||
nullptr, nullptr,
|
||||
FALSE,
|
||||
CREATE_NO_WINDOW,
|
||||
NULL, NULL,
|
||||
nullptr, nullptr,
|
||||
&si, &pi))
|
||||
{
|
||||
DWORD err = ::GetLastError();
|
||||
@@ -427,7 +427,7 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
// killed via Task Manager. JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE means
|
||||
// all processes in the job die when the last handle to the job closes
|
||||
// (i.e. when our process exits for any reason).
|
||||
hJob = CreateJobObject(NULL, NULL);
|
||||
hJob = CreateJobObject(nullptr, nullptr);
|
||||
if (hJob) {
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = {};
|
||||
jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
@@ -452,7 +452,7 @@ bool CTorProcess::Start(const std::string& dataDir, int socks, int hsPort, bool
|
||||
freopen("/dev/null", "w", stdout);
|
||||
freopen("/dev/null", "w", stderr);
|
||||
execl(torBinaryPath.c_str(), torBinaryPath.c_str(),
|
||||
"-f", torrcPath.c_str(), (char*)NULL);
|
||||
"-f", torrcPath.c_str(), (char*)nullptr);
|
||||
// If exec fails, exit child
|
||||
_exit(1);
|
||||
}
|
||||
@@ -514,16 +514,16 @@ void CTorProcess::Stop()
|
||||
if (!running) return;
|
||||
|
||||
#ifdef WIN32
|
||||
if (hProcess != NULL) {
|
||||
if (hProcess != nullptr) {
|
||||
printf("Stopping Tor process (PID %lu)...\n", processId);
|
||||
TerminateProcess(hProcess, 0);
|
||||
WaitForSingleObject(hProcess, 5000);
|
||||
CloseHandle(hProcess);
|
||||
hProcess = NULL;
|
||||
hProcess = nullptr;
|
||||
}
|
||||
if (hJob != NULL) {
|
||||
if (hJob != nullptr) {
|
||||
CloseHandle(hJob);
|
||||
hJob = NULL;
|
||||
hJob = nullptr;
|
||||
}
|
||||
#else
|
||||
if (processId > 0) {
|
||||
@@ -538,7 +538,7 @@ void CTorProcess::Stop()
|
||||
}
|
||||
// Force kill if still running
|
||||
kill(processId, SIGKILL);
|
||||
waitpid(processId, NULL, 0);
|
||||
waitpid(processId, nullptr, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -552,7 +552,7 @@ bool CTorProcess::IsRunning()
|
||||
if (!running) return false;
|
||||
|
||||
#ifdef WIN32
|
||||
if (hProcess == NULL) return false;
|
||||
if (hProcess == nullptr) return false;
|
||||
DWORD exitCode;
|
||||
if (GetExitCodeProcess(hProcess, &exitCode)) {
|
||||
return (exitCode == STILL_ACTIVE);
|
||||
|
||||
+45
-50
@@ -22,7 +22,6 @@
|
||||
#include <filesystem>
|
||||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#include <fstream>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@@ -44,7 +43,7 @@ static std::string strRPCUserColonPass;
|
||||
|
||||
const Object emptyobj;
|
||||
|
||||
CNotificationQueue* pNotificationQueue = NULL;
|
||||
CNotificationQueue* pNotificationQueue = nullptr;
|
||||
|
||||
void ThreadRPCServer3(void* parg);
|
||||
|
||||
@@ -367,7 +366,7 @@ const CRPCCommand *CRPCTable::operator[](string name) const
|
||||
{
|
||||
map<string, const CRPCCommand*>::const_iterator it = mapCommands.find(name);
|
||||
if (it == mapCommands.end())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
@@ -401,7 +400,7 @@ string rfc1123Time()
|
||||
time_t now;
|
||||
time(&now);
|
||||
struct tm* now_gmt = gmtime(&now);
|
||||
string locale(setlocale(LC_TIME, NULL));
|
||||
string locale(setlocale(LC_TIME, nullptr));
|
||||
setlocale(LC_TIME, "C"); // we want POSIX (aka "C") weekday/month strings
|
||||
strftime(buffer, sizeof(buffer), "%a, %d %b %Y %H:%M:%S +0000", now_gmt);
|
||||
setlocale(LC_TIME, locale.c_str());
|
||||
@@ -460,13 +459,12 @@ int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto,
|
||||
// Trim trailing \r
|
||||
if (!str.empty() && str[str.size()-1] == '\r')
|
||||
str.resize(str.size()-1);
|
||||
vector<string> vWords;
|
||||
boost::split(vWords, str, boost::is_any_of(" "));
|
||||
auto vWords = SplitString(str, ' ');
|
||||
if (vWords.size() < 2)
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
proto = 0;
|
||||
const char *ver = strstr(str.c_str(), "HTTP/1.");
|
||||
if (ver != NULL)
|
||||
if (ver != nullptr)
|
||||
proto = atoi(ver+7);
|
||||
|
||||
// Detect request line (GET/POST/...) vs response line (HTTP/1.x ...)
|
||||
@@ -493,10 +491,10 @@ int ReadHTTPHeader(std::basic_istream<char>& stream, map<string, string>& mapHea
|
||||
if (nColon != string::npos)
|
||||
{
|
||||
string strHeader = str.substr(0, nColon);
|
||||
boost::trim(strHeader);
|
||||
boost::to_lower(strHeader);
|
||||
strHeader = TrimString(strHeader);
|
||||
strHeader = ToLower(strHeader);
|
||||
string strValue = str.substr(nColon+1);
|
||||
boost::trim(strValue);
|
||||
strValue = TrimString(strValue);
|
||||
mapHeadersRet[strHeader] = strValue;
|
||||
if (strHeader == "content-length")
|
||||
nLen = atoi(strValue.c_str());
|
||||
@@ -550,7 +548,7 @@ bool HTTPAuthorized(map<string, string>& mapHeaders)
|
||||
string strAuth = mapHeaders["authorization"];
|
||||
if (strAuth.size() < 6 || strAuth.substr(0,6) != "Basic ")
|
||||
return false;
|
||||
string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
|
||||
string strUserPass64 = strAuth.substr(6); strUserPass64 = TrimString(strUserPass64);
|
||||
if (strUserPass64.empty())
|
||||
return false;
|
||||
string strUserPass;
|
||||
@@ -748,7 +746,7 @@ void ThreadRPCServer(void* parg)
|
||||
PrintException(&e, "ThreadRPCServer()");
|
||||
} catch (...) {
|
||||
vnThreadsRunning[THREAD_RPCLISTENER]--;
|
||||
PrintException(NULL, "ThreadRPCServer()");
|
||||
PrintException(nullptr, "ThreadRPCServer()");
|
||||
}
|
||||
printf("ThreadRPCServer exited\n");
|
||||
}
|
||||
@@ -775,12 +773,9 @@ static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketA
|
||||
acceptor->async_accept(
|
||||
conn->sslStream.lowest_layer(),
|
||||
conn->peer,
|
||||
boost::bind(&RPCAcceptHandler<Protocol, SocketAcceptorService>,
|
||||
acceptor,
|
||||
boost::ref(context),
|
||||
fUseSSL,
|
||||
conn,
|
||||
boost::asio::placeholders::error));
|
||||
[acceptor, &context, fUseSSL, conn](const boost::system::error_code& error) {
|
||||
RPCAcceptHandler(acceptor, context, fUseSSL, conn, error);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -892,17 +887,17 @@ void ThreadRPCServer2(void* parg)
|
||||
{
|
||||
context.set_options(ssl::context::no_sslv2);
|
||||
|
||||
fs::path pathCertFile(GetArg("-rpcsslcertificatechainfile", "server.cert"));
|
||||
fs::path pathCertFile(GetArg(std::string_view{"-rpcsslcertificatechainfile"}, std::string_view{"server.cert"}));
|
||||
if (!pathCertFile.is_absolute()) pathCertFile = fs::path(GetDataDir()) / pathCertFile;
|
||||
if (fs::exists(pathCertFile)) context.use_certificate_chain_file(pathCertFile.string());
|
||||
else printf("ThreadRPCServer ERROR: missing server certificate file %s\n", pathCertFile.string().c_str());
|
||||
|
||||
fs::path pathPKFile(GetArg("-rpcsslprivatekeyfile", "server.pem"));
|
||||
fs::path pathPKFile(GetArg(std::string_view{"-rpcsslprivatekeyfile"}, std::string_view{"server.pem"}));
|
||||
if (!pathPKFile.is_absolute()) pathPKFile = fs::path(GetDataDir()) / pathPKFile;
|
||||
if (fs::exists(pathPKFile)) context.use_private_key_file(pathPKFile.string(), ssl::context::pem);
|
||||
else printf("ThreadRPCServer ERROR: missing server private key file %s\n", pathPKFile.string().c_str());
|
||||
|
||||
string strCiphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
|
||||
string strCiphers = GetArg(std::string_view{"-rpcsslciphers"}, std::string_view{"TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH"});
|
||||
SSL_CTX_set_cipher_list(context.native_handle(), strCiphers.c_str());
|
||||
}
|
||||
|
||||
@@ -1341,7 +1336,7 @@ Object CallRPC(const string& strMethod, const Array& params)
|
||||
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
|
||||
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
|
||||
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
|
||||
if (!d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(GetDefaultRPCPort()))))
|
||||
if (!d.connect(GetArg(std::string_view{"-rpcconnect"}, std::string_view{"127.0.0.1"}), GetArg(std::string_view{"-rpcport"}, itostr(GetDefaultRPCPort()))))
|
||||
throw runtime_error("couldn't connect to server");
|
||||
|
||||
// HTTP basic authentication
|
||||
@@ -1415,45 +1410,45 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
||||
if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
|
||||
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
|
||||
if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
|
||||
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
|
||||
if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
|
||||
if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "getbalance" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "getblock" && n > 1) ConvertTo<bool>(params[1]);
|
||||
if (strMethod == "getblockbynumber" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "getblockbynumber" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "getblockbynumber" && n > 1) ConvertTo<bool>(params[1]);
|
||||
if (strMethod == "getblockhash" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "getblockhash" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
|
||||
if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
||||
if (strMethod == "move" && n > 3) ConvertTo<int64_t>(params[3]);
|
||||
if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
|
||||
if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
|
||||
if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
|
||||
if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "sendfrom" && n > 3) ConvertTo<int64_t>(params[3]);
|
||||
if (strMethod == "listtransactions" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "listtransactions" && n > 2) ConvertTo<int64_t>(params[2]);
|
||||
if (strMethod == "listaccounts" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "walletpassphrase" && n > 2) ConvertTo<bool>(params[2]);
|
||||
if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "listsinceblock" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
|
||||
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
|
||||
if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
|
||||
if (strMethod == "sendmany" && n > 2) ConvertTo<int64_t>(params[2]);
|
||||
if (strMethod == "reservebalance" && n > 0) ConvertTo<bool>(params[0]);
|
||||
if (strMethod == "reservebalance" && n > 1) ConvertTo<double>(params[1]);
|
||||
if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
|
||||
if (strMethod == "listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "listunspent" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "listunspent" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
|
||||
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
|
||||
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
|
||||
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
|
||||
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
|
||||
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
|
||||
if (strMethod == "keypoolrefill" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "keypoolrefill" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "getblockheader" && n > 1) ConvertTo<bool>(params[1]);
|
||||
if (strMethod == "estimatefee" && n > 0) ConvertTo<boost::int64_t>(params[0]);
|
||||
if (strMethod == "estimatefee" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "getaddressbalance" && n > 0) ConvertTo<Object>(params[0]);
|
||||
if (strMethod == "getaddressutxos" && n > 0) ConvertTo<Object>(params[0]);
|
||||
if (strMethod == "getaddresstxids" && n > 0) ConvertTo<Object>(params[0]);
|
||||
@@ -1515,7 +1510,7 @@ int CommandLineRPC(int argc, char *argv[])
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
PrintException(NULL, "CommandLineRPC()");
|
||||
PrintException(nullptr, "CommandLineRPC()");
|
||||
}
|
||||
|
||||
if (strPrint != "")
|
||||
@@ -1534,18 +1529,18 @@ int main(int argc, char *argv[])
|
||||
#ifdef _MSC_VER
|
||||
// Turn off Microsoft heap dump noise
|
||||
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
|
||||
_CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0));
|
||||
#endif
|
||||
setbuf(stdin, NULL);
|
||||
setbuf(stdout, NULL);
|
||||
setbuf(stderr, NULL);
|
||||
setbuf(stdin, nullptr);
|
||||
setbuf(stdout, nullptr);
|
||||
setbuf(stderr, nullptr);
|
||||
|
||||
try
|
||||
{
|
||||
if (argc >= 2 && string(argv[1]) == "-server")
|
||||
{
|
||||
printf("server ready\n");
|
||||
ThreadRPCServer(NULL);
|
||||
ThreadRPCServer(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1555,7 +1550,7 @@ int main(int argc, char *argv[])
|
||||
catch (std::exception& e) {
|
||||
PrintException(&e, "main()");
|
||||
} catch (...) {
|
||||
PrintException(NULL, "main()");
|
||||
PrintException(nullptr, "main()");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ extern const CRPCTable tableRPC;
|
||||
extern int64_t nWalletUnlockTime;
|
||||
extern int64_t AmountFromValue(const json_spirit::Value& value);
|
||||
extern json_spirit::Value ValueFromAmount(int64_t amount);
|
||||
extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern double GetDifficulty(const CBlockIndex* blockindex = nullptr);
|
||||
|
||||
extern double GetPoWMHashPS();
|
||||
extern double GetPoSKernelPS();
|
||||
|
||||
+13
-13
@@ -70,7 +70,7 @@ void init_blockindex(leveldb::Options& options, bool fRemoveOld = false) {
|
||||
CTxDB::CTxDB(const char* pszMode)
|
||||
{
|
||||
assert(pszMode);
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
||||
|
||||
if (txdb) {
|
||||
@@ -97,9 +97,9 @@ CTxDB::CTxDB(const char* pszMode)
|
||||
printf("Required index version is %d, removing old database\n", DATABASE_VERSION);
|
||||
|
||||
delete txdb;
|
||||
txdb = pdb = NULL;
|
||||
txdb = pdb = nullptr;
|
||||
delete activeBatch;
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
|
||||
init_blockindex(options, true);
|
||||
pdb = txdb;
|
||||
@@ -124,13 +124,13 @@ CTxDB::CTxDB(const char* pszMode)
|
||||
void CTxDB::Close()
|
||||
{
|
||||
delete txdb;
|
||||
txdb = pdb = NULL;
|
||||
txdb = pdb = nullptr;
|
||||
delete options.filter_policy;
|
||||
options.filter_policy = NULL;
|
||||
options.filter_policy = nullptr;
|
||||
delete options.block_cache;
|
||||
options.block_cache = NULL;
|
||||
options.block_cache = nullptr;
|
||||
delete activeBatch;
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
}
|
||||
|
||||
bool CTxDB::TxnBegin()
|
||||
@@ -149,7 +149,7 @@ bool CTxDB::TxnCommit()
|
||||
assert(activeBatch);
|
||||
leveldb::Status status = pdb->Write(leveldb::WriteOptions(), activeBatch);
|
||||
delete activeBatch;
|
||||
activeBatch = NULL;
|
||||
activeBatch = nullptr;
|
||||
if (!status.ok()) {
|
||||
printf("ERROR: LevelDB batch commit failure: %s\n", status.ToString().c_str());
|
||||
printf("ERROR: This may indicate disk full, corruption, or permissions issue.\n");
|
||||
@@ -291,7 +291,7 @@ std::unique_ptr<CTxDBIteratorBase> CTxDB::NewIterator() const
|
||||
static CBlockIndex *InsertBlockIndex(uint256 hash)
|
||||
{
|
||||
if (hash == 0)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash);
|
||||
if (mi != mapBlockIndex.end())
|
||||
@@ -372,7 +372,7 @@ bool CTxDB::LoadBlockIndex()
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
pindexNew->nChainTrust = diskindex.nChainTrust;
|
||||
|
||||
if (pindexGenesisBlock == NULL && blockHash == (!fTestNet ? hashGenesisBlockOfficial : hashGenesisBlockTestNet))
|
||||
if (pindexGenesisBlock == nullptr && blockHash == (!fTestNet ? hashGenesisBlockOfficial : hashGenesisBlockTestNet))
|
||||
pindexGenesisBlock = pindexNew;
|
||||
|
||||
if (!pindexNew->CheckIndex()) {
|
||||
@@ -504,7 +504,7 @@ bool CTxDB::LoadBlockIndex()
|
||||
nPhaseStart = GetTimeMillis();
|
||||
if (!ReadHashBestChain(hashBestChain))
|
||||
{
|
||||
if (pindexGenesisBlock == NULL)
|
||||
if (pindexGenesisBlock == nullptr)
|
||||
return true;
|
||||
return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded");
|
||||
}
|
||||
@@ -539,7 +539,7 @@ bool CTxDB::LoadBlockIndex()
|
||||
|
||||
// Re-evaluate best chain: scan for competing tips with equal or greater trust.
|
||||
{
|
||||
CBlockIndex* pindexBetter = NULL;
|
||||
CBlockIndex* pindexBetter = nullptr;
|
||||
for (const auto& item : mapBlockIndex)
|
||||
{
|
||||
CBlockIndex* pindex = item.second;
|
||||
@@ -602,7 +602,7 @@ bool CTxDB::LoadBlockIndex()
|
||||
if (nCheckDepth > nBestHeight)
|
||||
nCheckDepth = nBestHeight;
|
||||
printf("Verifying last %i blocks at level %i\n", nCheckDepth, nCheckLevel);
|
||||
CBlockIndex* pindexFork = NULL;
|
||||
CBlockIndex* pindexFork = nullptr;
|
||||
map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos;
|
||||
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
|
||||
{
|
||||
|
||||
+2
-1
@@ -42,12 +42,13 @@ public:
|
||||
|
||||
bool LoadBlockIndex() override;
|
||||
|
||||
std::unique_ptr<CTxDBIteratorBase> NewIterator() const override;
|
||||
|
||||
protected:
|
||||
bool ReadRaw(const std::string& key, std::string& value) const override;
|
||||
bool WriteRaw(const std::string& key, const std::string& value) override;
|
||||
bool EraseRaw(const std::string& key) override;
|
||||
bool ExistsRaw(const std::string& key) const override;
|
||||
std::unique_ptr<CTxDBIteratorBase> NewIterator() const override;
|
||||
|
||||
private:
|
||||
leveldb::DB* pdb; // Points to the global instance.
|
||||
|
||||
+11
-1
@@ -38,12 +38,22 @@ public:
|
||||
|
||||
bool LoadBlockIndex() override;
|
||||
|
||||
// Write a raw serialized key/value pair, bypassing the typed Write<>()
|
||||
// overloads. Intended for the chaindb migration utility, which carries
|
||||
// bytes directly across from a CTxDB (LevelDB) iterator. Honors the
|
||||
// active write batch if one is open.
|
||||
bool WriteRawRecordForMigration(const std::string& key, const std::string& value)
|
||||
{
|
||||
return WriteRaw(key, value);
|
||||
}
|
||||
|
||||
std::unique_ptr<CTxDBIteratorBase> NewIterator() const override;
|
||||
|
||||
protected:
|
||||
bool ReadRaw(const std::string& key, std::string& value) const override;
|
||||
bool WriteRaw(const std::string& key, const std::string& value) override;
|
||||
bool EraseRaw(const std::string& key) override;
|
||||
bool ExistsRaw(const std::string& key) const override;
|
||||
std::unique_ptr<CTxDBIteratorBase> NewIterator() const override;
|
||||
|
||||
private:
|
||||
rocksdb::DB* pdb; // Points to the global instance.
|
||||
|
||||
+64
-21
@@ -40,7 +40,6 @@
|
||||
#include "strlcpy.h"
|
||||
#include "version.h"
|
||||
#include "ui_interface.h"
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
// Work around clang compilation problem in Boost 1.46:
|
||||
// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
|
||||
@@ -127,7 +126,7 @@ public:
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
// Shutdown OpenSSL library multithreading support (pre-1.1.0 only)
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
CRYPTO_set_locking_callback(nullptr);
|
||||
for (int i = 0; i < CRYPTO_num_locks(); i++)
|
||||
delete ppmutexOpenSSL[i];
|
||||
OPENSSL_free(ppmutexOpenSSL);
|
||||
@@ -148,7 +147,7 @@ void RandAddSeed()
|
||||
// Seed with CPU performance counter
|
||||
int64_t nCounter = GetPerformanceCounter();
|
||||
RAND_add(&nCounter, sizeof(nCounter), 1.5);
|
||||
memset(&nCounter, 0, sizeof(nCounter));
|
||||
OPENSSL_cleanse(&nCounter, sizeof(nCounter));
|
||||
}
|
||||
|
||||
void RandAddSeedPerfmon()
|
||||
@@ -167,12 +166,12 @@ void RandAddSeedPerfmon()
|
||||
unsigned char pdata[250000];
|
||||
memset(pdata, 0, sizeof(pdata));
|
||||
unsigned long nSize = sizeof(pdata);
|
||||
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize);
|
||||
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", nullptr, nullptr, pdata, &nSize);
|
||||
RegCloseKey(HKEY_PERFORMANCE_DATA);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
RAND_add(pdata, nSize, nSize/100.0);
|
||||
memset(pdata, 0, nSize);
|
||||
OPENSSL_cleanse(pdata, nSize);
|
||||
printf("RandAddSeed() %lu bytes\n", nSize);
|
||||
}
|
||||
#endif
|
||||
@@ -210,7 +209,7 @@ uint256 GetRandHash()
|
||||
|
||||
|
||||
|
||||
static FILE* fileout = NULL;
|
||||
static FILE* fileout = nullptr;
|
||||
|
||||
inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
{
|
||||
@@ -231,7 +230,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
{
|
||||
std::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
||||
fileout = fopen(pathDebug.string().c_str(), "a");
|
||||
if (fileout) setbuf(fileout, NULL); // unbuffered
|
||||
if (fileout) setbuf(fileout, nullptr); // unbuffered
|
||||
}
|
||||
if (fileout)
|
||||
{
|
||||
@@ -241,22 +240,22 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
|
||||
// Since the order of destruction of static/global objects is undefined,
|
||||
// allocate mutexDebugLog on the heap the first time this routine
|
||||
// is called to avoid crashes during shutdown.
|
||||
static std::mutex* mutexDebugLog = NULL;
|
||||
if (mutexDebugLog == NULL) mutexDebugLog = new std::mutex();
|
||||
static std::mutex* mutexDebugLog = nullptr;
|
||||
if (mutexDebugLog == nullptr) mutexDebugLog = new std::mutex();
|
||||
std::lock_guard<std::mutex> scoped_lock(*mutexDebugLog);
|
||||
|
||||
// reopen the log file, if requested
|
||||
if (fReopenDebugLog) {
|
||||
fReopenDebugLog = false;
|
||||
std::filesystem::path pathDebug = GetDataDir() / "debug.log";
|
||||
if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
|
||||
setbuf(fileout, NULL); // unbuffered
|
||||
if (freopen(pathDebug.string().c_str(),"a",fileout) != nullptr)
|
||||
setbuf(fileout, nullptr); // unbuffered
|
||||
}
|
||||
|
||||
// Debug print useful for profiling
|
||||
if (fLogTimestamps && fStartedNewLine)
|
||||
fprintf(fileout, "%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
|
||||
if (pszFormat[strlen(pszFormat) - 1] == '\n')
|
||||
if (pszFormat[0] != '\0' && pszFormat[strlen(pszFormat) - 1] == '\n')
|
||||
fStartedNewLine = true;
|
||||
else
|
||||
fStartedNewLine = false;
|
||||
@@ -318,7 +317,7 @@ string vstrprintf(const char *format, va_list ap)
|
||||
delete[] p;
|
||||
limit *= 2;
|
||||
p = new char[limit];
|
||||
if (p == NULL)
|
||||
if (p == nullptr)
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
string str(p, p+ret);
|
||||
@@ -464,7 +463,7 @@ static const signed char phexdigit[256] =
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
|
||||
|
||||
bool IsHex(const string& str)
|
||||
bool IsHex(std::string_view str)
|
||||
{
|
||||
for (unsigned char c : str)
|
||||
{
|
||||
@@ -601,6 +600,37 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue)
|
||||
return SoftSetArg(strArg, std::string("0"));
|
||||
}
|
||||
|
||||
// C++20 modernization: std::string_view overloads delegating to std::string implementations
|
||||
std::string GetArg(std::string_view strArg, std::string_view strDefault)
|
||||
{
|
||||
return GetArg(std::string(strArg), std::string(strDefault));
|
||||
}
|
||||
|
||||
int64_t GetArg(std::string_view strArg, int64_t nDefault)
|
||||
{
|
||||
return GetArg(std::string(strArg), nDefault);
|
||||
}
|
||||
|
||||
bool GetBoolArg(std::string_view strArg, bool fDefault)
|
||||
{
|
||||
return GetBoolArg(std::string(strArg), fDefault);
|
||||
}
|
||||
|
||||
bool SoftSetArg(std::string_view strArg, std::string_view strValue)
|
||||
{
|
||||
return SoftSetArg(std::string(strArg), std::string(strValue));
|
||||
}
|
||||
|
||||
bool SoftSetBoolArg(std::string_view strArg, bool fValue)
|
||||
{
|
||||
return SoftSetBoolArg(std::string(strArg), fValue);
|
||||
}
|
||||
|
||||
bool WildcardMatch(std::string_view str, std::string_view mask)
|
||||
{
|
||||
return WildcardMatch(std::string(str), std::string(mask));
|
||||
}
|
||||
|
||||
|
||||
string EncodeBase64(const unsigned char* pch, size_t len)
|
||||
{
|
||||
@@ -970,7 +1000,7 @@ static std::string FormatException(std::exception* pex, const char* pszThread)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char pszModule[MAX_PATH] = "";
|
||||
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
|
||||
GetModuleFileNameA(nullptr, pszModule, sizeof(pszModule));
|
||||
#else
|
||||
const char* pszModule = "Triangles";
|
||||
#endif
|
||||
@@ -1031,7 +1061,7 @@ std::filesystem::path GetDefaultDataDir()
|
||||
#else
|
||||
fs::path pathRet;
|
||||
char* pszHome = getenv("HOME");
|
||||
if (pszHome == NULL || strlen(pszHome) == 0)
|
||||
if (pszHome == nullptr || strlen(pszHome) == 0)
|
||||
pathRet = fs::path("/");
|
||||
else
|
||||
pathRet = fs::path(pszHome);
|
||||
@@ -1084,7 +1114,7 @@ const std::filesystem::path &GetDataDir(bool fNetSpecific)
|
||||
|
||||
std::filesystem::path GetConfigFile()
|
||||
{
|
||||
std::filesystem::path pathConfigFile(GetArg("-conf", "triangles.conf"));
|
||||
std::filesystem::path pathConfigFile(GetArg(std::string_view{"-conf"}, std::string_view{"triangles.conf"}));
|
||||
if (!pathConfigFile.is_absolute()) pathConfigFile = GetDataDir(false) / pathConfigFile;
|
||||
return pathConfigFile;
|
||||
}
|
||||
@@ -1115,7 +1145,7 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
|
||||
|
||||
std::filesystem::path GetPidFile()
|
||||
{
|
||||
std::filesystem::path pathPidFile(GetArg("-pid", "trianglesd.pid"));
|
||||
std::filesystem::path pathPidFile(GetArg(std::string_view{"-pid"}, std::string_view{"trianglesd.pid"}));
|
||||
if (!pathPidFile.is_absolute()) pathPidFile = GetDataDir() / pathPidFile;
|
||||
return pathPidFile;
|
||||
}
|
||||
@@ -1188,7 +1218,7 @@ int64_t GetTime()
|
||||
{
|
||||
if (nMockTime) return nMockTime;
|
||||
|
||||
return time(NULL);
|
||||
return time(nullptr);
|
||||
}
|
||||
|
||||
void SetMockTime(int64_t nMockTimeIn)
|
||||
@@ -1288,7 +1318,7 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
|
||||
ss << "/";
|
||||
ss << name << ":" << FormatVersion(nClientVersion);
|
||||
if (!comments.empty())
|
||||
ss << "(" << boost::algorithm::join(comments, "; ") << ")";
|
||||
ss << "(" << JoinStrings(comments, "; ") << ")";
|
||||
ss << "/";
|
||||
return ss.str();
|
||||
}
|
||||
@@ -1300,7 +1330,7 @@ std::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
|
||||
|
||||
char pszPath[MAX_PATH] = "";
|
||||
|
||||
if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
|
||||
if(SHGetSpecialFolderPathA(nullptr, pszPath, nFolder, fCreate))
|
||||
{
|
||||
return fs::path(pszPath);
|
||||
}
|
||||
@@ -1349,3 +1379,16 @@ bool NewThread(void(*pfn)(void*), void* parg)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Callable, typename... Args>
|
||||
bool NewThreadT(Callable&& fn, Args&&... args)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::thread(std::forward<Callable>(fn), std::forward<Args>(args)...).detach();
|
||||
} catch(const std::system_error& e) {
|
||||
printf("Error creating thread: %s\n", e.what());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+98
-18
@@ -17,6 +17,10 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
@@ -24,6 +28,18 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ripemd.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#define TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
#define TRI_OPENSSL_SUPPRESS_DEPRECATED_END \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
#define TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
#endif
|
||||
|
||||
#include "netbase.h" // for AddTimeData
|
||||
|
||||
@@ -33,8 +49,8 @@
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
static const int64_t COIN = 1000000;
|
||||
static const int64_t CENT = 10000;
|
||||
constexpr int64_t COIN = 1000000;
|
||||
constexpr int64_t CENT = 10000;
|
||||
|
||||
#define BEGIN(a) ((char*)&(a))
|
||||
#define END(a) ((char*)&((&(a))[1]))
|
||||
@@ -175,26 +191,29 @@ bool ATTR_WARN_PRINTF(1,2) error(const char *format, ...);
|
||||
#define printf OutputDebugStringF
|
||||
|
||||
void LogException(std::exception* pex, const char* pszThread);
|
||||
|
||||
// LogPrintf - variadic macro for logging to stderr (C++20 modernization: restored from removed definition)
|
||||
#define LogPrintf(...) fprintf(stderr, __VA_ARGS__)
|
||||
void PrintException(std::exception* pex, const char* pszThread);
|
||||
void PrintExceptionContinue(std::exception* pex, const char* pszThread);
|
||||
void ParseString(const std::string& str, char c, std::vector<std::string>& v);
|
||||
void ParseString(std::string_view str, char c, std::vector<std::string>& v);
|
||||
std::string FormatMoney(int64_t n, bool fPlus=false);
|
||||
bool ParseMoney(const std::string& str, int64_t& nRet);
|
||||
bool ParseMoney(const char* pszIn, int64_t& nRet);
|
||||
std::vector<unsigned char> ParseHex(const char* psz);
|
||||
std::vector<unsigned char> ParseHex(const std::string& str);
|
||||
bool IsHex(const std::string& str);
|
||||
std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
|
||||
bool IsHex(std::string_view str);
|
||||
std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = nullptr);
|
||||
std::string DecodeBase64(const std::string& str);
|
||||
std::string EncodeBase64(const unsigned char* pch, size_t len);
|
||||
std::string EncodeBase64(const std::string& str);
|
||||
std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
|
||||
std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = nullptr);
|
||||
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 ParseParameters(int argc, const char*const argv[]);
|
||||
bool WildcardMatch(const char* psz, const char* mask);
|
||||
bool WildcardMatch(const std::string& str, const std::string& mask);
|
||||
bool WildcardMatch(std::string_view str, std::string_view mask);
|
||||
void FileCommit(FILE *fileout);
|
||||
bool RenameOver(std::filesystem::path src, std::filesystem::path dest);
|
||||
std::filesystem::path GetDefaultDataDir();
|
||||
@@ -244,7 +263,7 @@ inline int64_t atoi64(const char* psz)
|
||||
#ifdef _MSC_VER
|
||||
return _atoi64(psz);
|
||||
#else
|
||||
return strtoll(psz, NULL, 10);
|
||||
return strtoll(psz, nullptr, 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -253,7 +272,7 @@ inline int64_t atoi64(const std::string& str)
|
||||
#ifdef _MSC_VER
|
||||
return _atoi64(str.c_str());
|
||||
#else
|
||||
return strtoll(str.c_str(), NULL, 10);
|
||||
return strtoll(str.c_str(), nullptr, 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -287,11 +306,57 @@ inline std::string leftTrim(std::string src, char chr)
|
||||
return src;
|
||||
}
|
||||
|
||||
inline std::string TrimString(std::string str)
|
||||
{
|
||||
auto start = str.find_first_not_of(" \t\r\n");
|
||||
if (start == std::string::npos) return {};
|
||||
auto end = str.find_last_not_of(" \t\r\n");
|
||||
return str.substr(start, end - start + 1);
|
||||
}
|
||||
|
||||
inline std::string ToLower(std::string str)
|
||||
{
|
||||
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
return str;
|
||||
}
|
||||
|
||||
inline void ReplaceAll(std::string& str, const std::string& from, const std::string& to)
|
||||
{
|
||||
if (from.empty()) return;
|
||||
size_t pos = 0;
|
||||
while ((pos = str.find(from, pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(pos, from.length(), to);
|
||||
pos += to.length();
|
||||
}
|
||||
}
|
||||
|
||||
inline std::vector<std::string> SplitString(const std::string& str, char delim)
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
std::istringstream iss(str);
|
||||
std::string token;
|
||||
while (std::getline(iss, token, delim))
|
||||
tokens.push_back(token);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
inline std::string JoinStrings(const std::vector<std::string>& parts, const std::string& sep)
|
||||
{
|
||||
std::string result;
|
||||
for (size_t i = 0; i < parts.size(); ++i)
|
||||
{
|
||||
if (i > 0) result += sep;
|
||||
result += parts[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
||||
{
|
||||
std::string rv;
|
||||
static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
static constexpr char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
rv.reserve((itend-itbegin)*3);
|
||||
for(T it = itbegin; it < itend; ++it)
|
||||
@@ -329,7 +394,7 @@ inline int64_t GetPerformanceCounter()
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
|
||||
#else
|
||||
timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
gettimeofday(&t, nullptr);
|
||||
nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec;
|
||||
#endif
|
||||
return nCounter;
|
||||
@@ -356,10 +421,10 @@ inline std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
|
||||
return pszTime;
|
||||
}
|
||||
|
||||
static const std::string strTimestampFormat = "%Y-%m-%d %H:%M:%S UTC";
|
||||
constexpr const char strTimestampFormat[] = "%Y-%m-%d %H:%M:%S UTC";
|
||||
inline std::string DateTimeStrFormat(int64_t nTime)
|
||||
{
|
||||
return DateTimeStrFormat(strTimestampFormat.c_str(), nTime);
|
||||
return DateTimeStrFormat(strTimestampFormat, nTime);
|
||||
}
|
||||
|
||||
|
||||
@@ -386,7 +451,7 @@ inline bool IsSwitchChar(char c)
|
||||
* @param default (e.g. "1")
|
||||
* @return command-line argument or default value
|
||||
*/
|
||||
std::string GetArg(const std::string& strArg, const std::string& strDefault);
|
||||
std::string GetArg(std::string_view strArg, std::string_view strDefault);
|
||||
|
||||
/**
|
||||
* Return integer argument or default value
|
||||
@@ -395,7 +460,7 @@ std::string GetArg(const std::string& strArg, const std::string& strDefault);
|
||||
* @param default (e.g. 1)
|
||||
* @return command-line argument (0 if invalid number) or default value
|
||||
*/
|
||||
int64_t GetArg(const std::string& strArg, int64_t nDefault);
|
||||
int64_t GetArg(std::string_view strArg, int64_t nDefault);
|
||||
|
||||
/**
|
||||
* Return boolean argument or default value
|
||||
@@ -404,7 +469,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault);
|
||||
* @param default (true or false)
|
||||
* @return command-line argument or default value
|
||||
*/
|
||||
bool GetBoolArg(const std::string& strArg, bool fDefault=false);
|
||||
bool GetBoolArg(std::string_view strArg, bool fDefault=false);
|
||||
|
||||
/**
|
||||
* Set an argument if it doesn't already have a value
|
||||
@@ -413,7 +478,7 @@ bool GetBoolArg(const std::string& strArg, bool fDefault=false);
|
||||
* @param strValue Value (e.g. "1")
|
||||
* @return true if argument gets set, false if it already had a value
|
||||
*/
|
||||
bool SoftSetArg(const std::string& strArg, const std::string& strValue);
|
||||
bool SoftSetArg(std::string_view strArg, std::string_view strValue);
|
||||
|
||||
/**
|
||||
* Set a boolean argument if it doesn't already have a value
|
||||
@@ -422,7 +487,7 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue);
|
||||
* @param fValue Value (e.g. false)
|
||||
* @return true if argument gets set, false if it already had a value
|
||||
*/
|
||||
bool SoftSetBoolArg(const std::string& strArg, bool fValue);
|
||||
bool SoftSetBoolArg(std::string_view strArg, bool fValue);
|
||||
|
||||
|
||||
|
||||
@@ -453,7 +518,9 @@ public:
|
||||
int nVersion;
|
||||
|
||||
void Init() {
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
SHA256_Init(&ctx);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {
|
||||
@@ -461,14 +528,18 @@ public:
|
||||
}
|
||||
|
||||
CHashWriter& write(const char *pch, size_t size) {
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
SHA256_Update(&ctx, pch, size);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// invalidates the object
|
||||
uint256 GetHash() {
|
||||
uint256 hash1;
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
@@ -490,10 +561,12 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end,
|
||||
static unsigned char pblank[1];
|
||||
uint256 hash1;
|
||||
SHA256_CTX ctx;
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
|
||||
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
|
||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
@@ -507,11 +580,13 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end,
|
||||
static unsigned char pblank[1];
|
||||
uint256 hash1;
|
||||
SHA256_CTX ctx;
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
|
||||
SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
|
||||
SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
|
||||
SHA256_Final((unsigned char*)&hash1, &ctx);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
uint256 hash2;
|
||||
SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
return hash2;
|
||||
@@ -530,7 +605,9 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch)
|
||||
uint256 hash1;
|
||||
SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
|
||||
uint160 hash2;
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_BEGIN
|
||||
RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
|
||||
TRI_OPENSSL_SUPPRESS_DEPRECATED_END
|
||||
return hash2;
|
||||
}
|
||||
|
||||
@@ -607,6 +684,9 @@ public:
|
||||
|
||||
bool NewThread(void(*pfn)(void*), void* parg);
|
||||
|
||||
template<typename Callable, typename... Args>
|
||||
bool NewThreadT(Callable&& fn, Args&&... args);
|
||||
|
||||
#ifdef WIN32
|
||||
inline void SetThreadPriority(int nPriority)
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@ bool DumpSnapshot(const fs::path& destPath,
|
||||
unsigned int nCollected = 0;
|
||||
while (pindex && nCollected < nHeaders) {
|
||||
CDiskBlockIndex diskindex(pindex);
|
||||
vHeaders.push_back(std::make_pair(*pindex->phashBlock, diskindex));
|
||||
vHeaders.push_back({*pindex->phashBlock, diskindex});
|
||||
pindex = pindex->pprev;
|
||||
nCollected++;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ bool DumpSnapshot(const fs::path& destPath,
|
||||
// documented on CTxDBIteratorBase guarantees a stable view of committed state.
|
||||
{
|
||||
CDataStream ssKeyPrefix(SER_DISK, CLIENT_VERSION);
|
||||
ssKeyPrefix << std::make_pair(std::string("u"), std::make_pair(uint256(0), (unsigned int)0));
|
||||
ssKeyPrefix << std::pair{std::string("u"), std::pair{uint256(0), (unsigned int)0}};
|
||||
std::string strPrefixBegin = ssKeyPrefix.str();
|
||||
|
||||
auto it = txdbRead.NewIterator();
|
||||
|
||||
+11
-11
@@ -11,7 +11,7 @@
|
||||
// client versioning
|
||||
//
|
||||
|
||||
static const int CLIENT_VERSION =
|
||||
constexpr int CLIENT_VERSION =
|
||||
1000000 * CLIENT_VERSION_MAJOR
|
||||
+ 10000 * CLIENT_VERSION_MINOR
|
||||
+ 100 * CLIENT_VERSION_REVISION
|
||||
@@ -24,35 +24,35 @@ extern const std::string CLIENT_DATE;
|
||||
//
|
||||
// database format versioning
|
||||
//
|
||||
static const int DATABASE_VERSION = 70509;
|
||||
constexpr int DATABASE_VERSION = 70509;
|
||||
|
||||
//
|
||||
// network protocol versioning
|
||||
//
|
||||
|
||||
static const int PROTOCOL_VERSION = 70206;
|
||||
constexpr int PROTOCOL_VERSION = 70206;
|
||||
|
||||
// v5 hard fork: require new protocol version (disconnects old nodes)
|
||||
static const int MIN_PROTO_VERSION = 70205;
|
||||
constexpr int MIN_PROTO_VERSION = 70205;
|
||||
|
||||
// Peers >= this version support the P2P UTXO snapshot protocol
|
||||
// (getsnap/snap/getsnapchunk/snapchunk and the NODE_SNAPSHOT service flag).
|
||||
static const int SNAPSHOT_PROTO_VERSION = 70206;
|
||||
constexpr int SNAPSHOT_PROTO_VERSION = 70206;
|
||||
|
||||
static const int INIT_PROTO_VERSION = 209;
|
||||
constexpr int INIT_PROTO_VERSION = 209;
|
||||
|
||||
// nTime field added to CAddress, starting with this version;
|
||||
// if possible, avoid requesting addresses nodes older than this
|
||||
static const int CADDR_TIME_VERSION = 70200;
|
||||
constexpr int CADDR_TIME_VERSION = 70200;
|
||||
|
||||
// only request blocks from nodes outside this range of versions
|
||||
static const int NOBLKS_VERSION_START = 0;
|
||||
static const int NOBLKS_VERSION_END = 70203;
|
||||
constexpr int NOBLKS_VERSION_START = 0;
|
||||
constexpr int NOBLKS_VERSION_END = 70203;
|
||||
|
||||
// BIP 0031, pong message, is enabled for all versions AFTER this one
|
||||
static const int BIP0031_VERSION = 60000;
|
||||
constexpr int BIP0031_VERSION = 60000;
|
||||
|
||||
// "mempool" command, enhanced "getdata" behavior starts with this version:
|
||||
static const int MEMPOOL_GD_VERSION = 60002;
|
||||
constexpr int MEMPOOL_GD_VERSION = 60002;
|
||||
|
||||
#endif
|
||||
|
||||
+132
-154
@@ -12,8 +12,8 @@
|
||||
#include "kernel.h"
|
||||
#include "coincontrol.h"
|
||||
#include "addressindex.h"
|
||||
#include "util.h"
|
||||
#include <memory>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <deque>
|
||||
@@ -54,15 +54,19 @@ static CBlockIndex* GetWalletRescanStart(const CWallet& wallet)
|
||||
}
|
||||
}
|
||||
|
||||
if (wallet.nTimeFirstKey > 1 && pindexBest)
|
||||
if (wallet.nTimeFirstKey > 1)
|
||||
{
|
||||
int64_t nTimeWindowStart = wallet.nTimeFirstKey - 7200;
|
||||
CBlockIndex* pindexBirthday = pindexBest;
|
||||
while (pindexBirthday->pprev && pindexBirthday->GetBlockTime() > nTimeWindowStart)
|
||||
pindexBirthday = pindexBirthday->pprev;
|
||||
LOCK(cs_main);
|
||||
if (pindexBest)
|
||||
{
|
||||
int64_t nTimeWindowStart = wallet.nTimeFirstKey - 7200;
|
||||
CBlockIndex* pindexBirthday = pindexBest;
|
||||
while (pindexBirthday->pprev && pindexBirthday->GetBlockTime() > nTimeWindowStart)
|
||||
pindexBirthday = pindexBirthday->pprev;
|
||||
|
||||
if (!pindexStart || pindexBirthday->nHeight < pindexStart->nHeight)
|
||||
pindexStart = pindexBirthday;
|
||||
if (!pindexStart || pindexBirthday->nHeight < pindexStart->nHeight)
|
||||
pindexStart = pindexBirthday;
|
||||
}
|
||||
}
|
||||
|
||||
return pindexStart ? pindexStart : pindexGenesisBlock;
|
||||
@@ -94,11 +98,11 @@ static bool GetIndexedWalletTxHeight(const CTxIndex& txindex, int& nHeight)
|
||||
if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
|
||||
return false;
|
||||
|
||||
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash());
|
||||
auto mi = mapBlockIndex.find(block.GetHash());
|
||||
if (mi == mapBlockIndex.end())
|
||||
return false;
|
||||
|
||||
nHeight = (*mi).second->nHeight;
|
||||
nHeight = mi->second->nHeight;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -121,7 +125,7 @@ static bool ReadIndexedWalletTransaction(CTxDBBase& txdb, const CDiskTxPos& txPo
|
||||
|
||||
CPubKey CWallet::GenerateNewKey()
|
||||
{
|
||||
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
||||
bool fCompressed = CanSupportFeature(WalletFeature::ComprPubKey); // default to compressed public keys if we want 0.6.0 wallets
|
||||
|
||||
RandAddSeedPerfmon();
|
||||
CKey key;
|
||||
@@ -129,7 +133,7 @@ CPubKey CWallet::GenerateNewKey()
|
||||
|
||||
// Compressed public keys were introduced in version 0.6.0
|
||||
if (fCompressed)
|
||||
SetMinVersion(FEATURE_COMPRPUBKEY);
|
||||
SetMinVersion(WalletFeature::ComprPubKey);
|
||||
|
||||
CPubKey pubkey = key.GetPubKey();
|
||||
|
||||
@@ -165,12 +169,8 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char
|
||||
return true;
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (pwalletdbEncryption)
|
||||
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
|
||||
else
|
||||
return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
|
||||
return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
|
||||
@@ -309,19 +309,19 @@ public:
|
||||
)
|
||||
};
|
||||
|
||||
bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
|
||||
bool CWallet::SetMinVersion(WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
|
||||
{
|
||||
if (nWalletVersion >= nVersion)
|
||||
if (nWalletVersion >= static_cast<int>(nVersion))
|
||||
return true;
|
||||
|
||||
// when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
|
||||
if (fExplicit && nVersion > nWalletMaxVersion)
|
||||
nVersion = FEATURE_LATEST;
|
||||
if (fExplicit && static_cast<int>(nVersion) > nWalletMaxVersion)
|
||||
nVersion = WalletFeature::Latest;
|
||||
|
||||
nWalletVersion = nVersion;
|
||||
nWalletVersion = static_cast<int>(nVersion);
|
||||
|
||||
if (nVersion > nWalletMaxVersion)
|
||||
nWalletMaxVersion = nVersion;
|
||||
if (static_cast<int>(nVersion) > nWalletMaxVersion)
|
||||
nWalletMaxVersion = static_cast<int>(nVersion);
|
||||
|
||||
if (fFileBacked)
|
||||
{
|
||||
@@ -396,29 +396,21 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
|
||||
if (fFileBacked)
|
||||
{
|
||||
pwalletdbEncryption = new CWalletDB(strWalletFile);
|
||||
if (!pwalletdbEncryption->TxnBegin())
|
||||
std::unique_ptr<CWalletDB> dbEnc(new CWalletDB(strWalletFile));
|
||||
if (!dbEnc->TxnBegin())
|
||||
return false;
|
||||
pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
|
||||
}
|
||||
dbEnc->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
|
||||
|
||||
if (!EncryptKeys(vMasterKey))
|
||||
{
|
||||
if (fFileBacked)
|
||||
pwalletdbEncryption->TxnAbort();
|
||||
exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
|
||||
}
|
||||
if (!EncryptKeys(vMasterKey))
|
||||
{
|
||||
dbEnc->TxnAbort();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Encryption was introduced in version 0.4.0
|
||||
SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
|
||||
SetMinVersion(WalletFeature::WalletCrypt, dbEnc.get(), true);
|
||||
|
||||
if (fFileBacked)
|
||||
{
|
||||
if (!pwalletdbEncryption->TxnCommit())
|
||||
exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
|
||||
|
||||
delete pwalletdbEncryption;
|
||||
pwalletdbEncryption = NULL;
|
||||
if (!dbEnc->TxnCommit())
|
||||
return false;
|
||||
}
|
||||
|
||||
Lock();
|
||||
@@ -456,10 +448,9 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries,
|
||||
|
||||
// Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
|
||||
// would make this much faster for applications that do this a lot.
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
CWalletTx* wtx = &((*it).second);
|
||||
txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
|
||||
txOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
|
||||
}
|
||||
acentries.clear();
|
||||
walletdb.ListAccountCreditDebit(strAccount, acentries);
|
||||
@@ -480,10 +471,9 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock)
|
||||
LOCK(cs_wallet);
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
if (auto mi = mapWallet.find(txin.prevout.hash); mi != mapWallet.end())
|
||||
{
|
||||
CWalletTx& wtx = (*mi).second;
|
||||
auto& [hash, wtx] = *mi;
|
||||
if (txin.prevout.n >= wtx.vout.size())
|
||||
printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
|
||||
else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
|
||||
@@ -494,7 +484,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock)
|
||||
if (!IsInitialBlockDownload())
|
||||
{
|
||||
try { NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); }
|
||||
catch (...) { }
|
||||
catch (...) { printf("WARNING: NotifyTransactionChanged exception in WalletUpdateSpent\n"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -515,7 +505,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock)
|
||||
if (!IsInitialBlockDownload())
|
||||
{
|
||||
try { NotifyTransactionChanged(this, hash, CT_UPDATED); }
|
||||
catch (...) { }
|
||||
catch (...) { printf("WARNING: NotifyTransactionChanged exception in WalletUpdateSpent\n"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -662,7 +652,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
|
||||
|
||||
if ( !strCmd.empty())
|
||||
{
|
||||
boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
|
||||
ReplaceAll(strCmd, "%s", wtxIn.GetHash().GetHex());
|
||||
std::thread(runCommand, strCmd).detach(); // thread runs free
|
||||
}
|
||||
|
||||
@@ -718,10 +708,9 @@ bool CWallet::IsMine(const CTxIn &txin) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
if (auto mi = mapWallet.find(txin.prevout.hash); mi != mapWallet.end())
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
const auto& [hash, prev] = *mi;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
if (IsMine(prev.vout[txin.prevout.n]))
|
||||
return true;
|
||||
@@ -734,10 +723,9 @@ int64_t CWallet::GetDebit(const CTxIn &txin) const
|
||||
{
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
if (auto mi = mapWallet.find(txin.prevout.hash); mi != mapWallet.end())
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
const auto& [hash, prev] = *mi;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
if (IsMine(prev.vout[txin.prevout.n]))
|
||||
return prev.vout[txin.prevout.n].nValue;
|
||||
@@ -783,27 +771,22 @@ int CWalletTx::GetRequestCount() const
|
||||
// Generated block
|
||||
if (hashBlock != 0)
|
||||
{
|
||||
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
|
||||
if (mi != pwallet->mapRequestCount.end())
|
||||
nRequests = (*mi).second;
|
||||
if (auto mi = pwallet->mapRequestCount.find(hashBlock); mi != pwallet->mapRequestCount.end())
|
||||
nRequests = mi->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Did anyone request this transaction?
|
||||
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
|
||||
if (mi != pwallet->mapRequestCount.end())
|
||||
if (auto mi = pwallet->mapRequestCount.find(GetHash()); mi != pwallet->mapRequestCount.end())
|
||||
{
|
||||
nRequests = (*mi).second;
|
||||
nRequests = mi->second;
|
||||
|
||||
// How about the block it's in?
|
||||
if (nRequests == 0 && hashBlock != 0)
|
||||
{
|
||||
map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
|
||||
if (mi != pwallet->mapRequestCount.end())
|
||||
nRequests = (*mi).second;
|
||||
if (auto mi2 = pwallet->mapRequestCount.find(hashBlock); mi2 != pwallet->mapRequestCount.end())
|
||||
nRequests = mi2->second;
|
||||
else
|
||||
nRequests = 1; // If it's in someone else's block it must have got out
|
||||
nRequests = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -891,8 +874,7 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
|
||||
{
|
||||
if (pwallet->mapAddressBook.count(r.first))
|
||||
{
|
||||
map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
|
||||
if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
|
||||
if (auto mi = pwallet->mapAddressBook.find(r.first); mi != pwallet->mapAddressBook.end() && mi->second == strAccount)
|
||||
nReceived += r.second;
|
||||
}
|
||||
else if (strAccount.empty())
|
||||
@@ -927,11 +909,10 @@ void CWalletTx::AddSupportingTransactions(CTxDBBase& txdb)
|
||||
setAlreadyDone.insert(hash);
|
||||
|
||||
CMerkleTx tx;
|
||||
map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
|
||||
if (mi != pwallet->mapWallet.end())
|
||||
if (auto mi = pwallet->mapWallet.find(hash); mi != pwallet->mapWallet.end())
|
||||
{
|
||||
tx = (*mi).second;
|
||||
for (const CMerkleTx& txWalletPrev : (*mi).second.vtxPrev)
|
||||
tx = mi->second;
|
||||
for (const CMerkleTx& txWalletPrev : mi->second.vtxPrev)
|
||||
mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
|
||||
}
|
||||
else if (mapWalletPrev.count(hash))
|
||||
@@ -1026,8 +1007,11 @@ bool CWallet::ScanForWalletTransactionsFromIndex(CBlockIndex* pindexStart, bool
|
||||
int nFound = 0;
|
||||
if (pnFound)
|
||||
*pnFound = 0;
|
||||
if (!pindexBest)
|
||||
return false;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (!pindexBest)
|
||||
return false;
|
||||
}
|
||||
|
||||
const int nStartHeight = pindexStart ? pindexStart->nHeight : 0;
|
||||
|
||||
@@ -1037,8 +1021,8 @@ bool CWallet::ScanForWalletTransactionsFromIndex(CBlockIndex* pindexStart, bool
|
||||
set<CScriptID> setScripts;
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
for (ScriptMap::const_iterator it = mapScripts.begin(); it != mapScripts.end(); ++it)
|
||||
setScripts.insert((*it).first);
|
||||
for (const auto& [scriptId, script] : mapScripts)
|
||||
setScripts.insert(scriptId);
|
||||
}
|
||||
|
||||
auto txdb_holder = MakeChainDB("r"); CTxDBBase& txdb = *txdb_holder;
|
||||
@@ -1114,10 +1098,10 @@ bool CWallet::ScanForWalletTransactionsFromIndex(CBlockIndex* pindexStart, bool
|
||||
CWalletTx wtx;
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
|
||||
auto mi = mapWallet.find(hashTx);
|
||||
if (mi == mapWallet.end())
|
||||
continue;
|
||||
wtx = (*mi).second;
|
||||
wtx = mi->second;
|
||||
}
|
||||
|
||||
// Check UTXO existence to update spent status.
|
||||
@@ -1144,7 +1128,10 @@ bool CWallet::ScanForWalletTransactionsFromIndex(CBlockIndex* pindexStart, bool
|
||||
}
|
||||
}
|
||||
|
||||
SetBestChain(CBlockLocator(pindexBest));
|
||||
{
|
||||
LOCK(cs_main);
|
||||
SetBestChain(CBlockLocator(pindexBest));
|
||||
}
|
||||
|
||||
if (pnFound)
|
||||
*pnFound = nFound;
|
||||
@@ -1155,7 +1142,7 @@ int CWallet::ScanForWalletTransaction(const uint256& hashTx)
|
||||
{
|
||||
CTransaction tx;
|
||||
tx.ReadFromDisk(COutPoint(hashTx, 0));
|
||||
if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
|
||||
if (AddToWalletIfInvolvingMe(tx, nullptr, true, true))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1318,11 +1305,10 @@ int64_t CWallet::GetBalance() const
|
||||
int64_t nTotal = 0;
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
if (pcoin->IsTrusted())
|
||||
nTotal += pcoin->GetAvailableCredit();
|
||||
if (wtx.IsTrusted())
|
||||
nTotal += wtx.GetAvailableCredit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1334,11 +1320,10 @@ int64_t CWallet::GetUnconfirmedBalance() const
|
||||
int64_t nTotal = 0;
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
if (!pcoin->IsFinal() || !pcoin->IsTrusted())
|
||||
nTotal += pcoin->GetAvailableCredit();
|
||||
if (!wtx.IsFinal() || !wtx.IsTrusted())
|
||||
nTotal += wtx.GetAvailableCredit();
|
||||
}
|
||||
}
|
||||
return nTotal;
|
||||
@@ -1349,11 +1334,10 @@ int64_t CWallet::GetImmatureBalance() const
|
||||
int64_t nTotal = 0;
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx& pcoin = (*it).second;
|
||||
if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.IsInMainChain())
|
||||
nTotal += GetCredit(pcoin);
|
||||
if (wtx.IsCoinBase() && wtx.GetBlocksToMaturity() > 0 && wtx.IsInMainChain())
|
||||
nTotal += GetCredit(wtx);
|
||||
}
|
||||
}
|
||||
return nTotal;
|
||||
@@ -1366,9 +1350,9 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
|
||||
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
const CWalletTx* pcoin = &wtx;
|
||||
|
||||
if (!pcoin->IsFinal())
|
||||
continue;
|
||||
@@ -1388,7 +1372,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
|
||||
|
||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
|
||||
if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue &&
|
||||
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
|
||||
(!coinControl || !coinControl->HasSelected() || coinControl->IsSelected(hash, i)))
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth));
|
||||
|
||||
}
|
||||
@@ -1401,9 +1385,9 @@ void CWallet::AvailableCoinsMinConf(vector<COutput>& vCoins, int nConf) const
|
||||
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
const CWalletTx* pcoin = &wtx;
|
||||
|
||||
if (!pcoin->IsFinal())
|
||||
continue;
|
||||
@@ -1461,11 +1445,10 @@ int64_t CWallet::GetStake() const
|
||||
{
|
||||
int64_t nTotal = 0;
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
|
||||
nTotal += CWallet::GetCredit(*pcoin);
|
||||
if (wtx.IsCoinStake() && wtx.GetBlocksToMaturity() > 0 && wtx.GetDepthInMainChain() > 0)
|
||||
nTotal += CWallet::GetCredit(wtx);
|
||||
}
|
||||
return nTotal;
|
||||
}
|
||||
@@ -1474,11 +1457,10 @@ int64_t CWallet::GetNewMint() const
|
||||
{
|
||||
int64_t nTotal = 0;
|
||||
LOCK(cs_wallet);
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &(*it).second;
|
||||
if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
|
||||
nTotal += CWallet::GetCredit(*pcoin);
|
||||
if (wtx.IsCoinBase() && wtx.GetBlocksToMaturity() > 0 && wtx.GetDepthInMainChain() > 0)
|
||||
nTotal += CWallet::GetCredit(wtx);
|
||||
}
|
||||
return nTotal;
|
||||
}
|
||||
@@ -1492,9 +1474,9 @@ bool CWallet::GetAllBalances(int64_t& nBalance, int64_t& nStake, int64_t& nUncon
|
||||
TRY_LOCK(cs_wallet, lockWallet);
|
||||
if (!lockWallet)
|
||||
return false;
|
||||
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
for (const auto& [hash, wtx] : mapWallet)
|
||||
{
|
||||
const CWalletTx& pcoin = (*it).second;
|
||||
const CWalletTx& pcoin = wtx;
|
||||
|
||||
if (pcoin.IsCoinStake() && pcoin.GetBlocksToMaturity() > 0 && pcoin.GetDepthInMainChain() > 0)
|
||||
nStake += CWallet::GetCredit(pcoin);
|
||||
@@ -1519,7 +1501,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime,
|
||||
// List of values less than target
|
||||
pair<int64_t, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
|
||||
coinLowestLarger.first = std::numeric_limits<int64_t>::max();
|
||||
coinLowestLarger.second.first = NULL;
|
||||
coinLowestLarger.second.first = nullptr;
|
||||
vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > > vValue;
|
||||
int64_t nTotalLower = 0;
|
||||
|
||||
@@ -1571,7 +1553,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime,
|
||||
|
||||
if (nTotalLower < nTargetValue)
|
||||
{
|
||||
if (coinLowestLarger.second.first == NULL)
|
||||
if (coinLowestLarger.second.first == nullptr)
|
||||
return false;
|
||||
setCoinsRet.insert(coinLowestLarger.second);
|
||||
nValueRet += coinLowestLarger.first;
|
||||
@@ -1801,7 +1783,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
|
||||
|
||||
// Check that enough fee is included
|
||||
int64_t nPayFee = nTransactionFee * (1 + (int64_t)nBytes / 1000);
|
||||
int64_t nMinFee = wtxNew.GetMinFee(1, GMF_SEND, nBytes);
|
||||
int64_t nMinFee = wtxNew.GetMinFee(1, GetMinFeeMode::Send, nBytes);
|
||||
|
||||
if (nFeeRet < max(nPayFee, nMinFee))
|
||||
{
|
||||
@@ -1930,7 +1912,11 @@ bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64_t& nMinWeight, ui
|
||||
|
||||
bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key)
|
||||
{
|
||||
CBlockIndex* pindexPrev = pindexBest;
|
||||
CBlockIndex* pindexPrev;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexPrev = pindexBest;
|
||||
}
|
||||
CBigNum bnTargetPerCoinDay;
|
||||
bnTargetPerCoinDay.SetCompact(nBits);
|
||||
|
||||
@@ -1997,7 +1983,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
|
||||
if (fDebug && GetBoolArg("-printcoinstake"))
|
||||
printf("CreateCoinStake : kernel found\n");
|
||||
vector<valtype> vSolutions;
|
||||
txnouttype whichType;
|
||||
TxnOutType whichType;
|
||||
CScript scriptPubKeyOut;
|
||||
scriptPubKeyKernel = pcoin.first->vout[pcoin.second].scriptPubKey;
|
||||
if (!Solver(scriptPubKeyKernel, whichType, vSolutions))
|
||||
@@ -2007,31 +1993,30 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
|
||||
break;
|
||||
}
|
||||
if (fDebug && GetBoolArg("-printcoinstake"))
|
||||
printf("CreateCoinStake : parsed kernel type=%d\n", whichType);
|
||||
if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH)
|
||||
printf("CreateCoinStake : parsed kernel type=%d\n", static_cast<int>(whichType));
|
||||
if (whichType != TxnOutType::PubKey && whichType != TxnOutType::PubKeyHash)
|
||||
{
|
||||
if (fDebug && GetBoolArg("-printcoinstake"))
|
||||
printf("CreateCoinStake : no support for kernel type=%d\n", whichType);
|
||||
break; // only support pay to public key and pay to address
|
||||
printf("CreateCoinStake : no support for kernel type=%d\n", static_cast<int>(whichType));
|
||||
break;
|
||||
}
|
||||
if (whichType == TX_PUBKEYHASH) // pay to address type
|
||||
if (whichType == TxnOutType::PubKeyHash)
|
||||
{
|
||||
// convert to pay to public key type
|
||||
if (!keystore.GetKey(uint160(vSolutions[0]), key))
|
||||
{
|
||||
if (fDebug && GetBoolArg("-printcoinstake"))
|
||||
printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
|
||||
break; // unable to find corresponding public key
|
||||
printf("CreateCoinStake : failed to get key for kernel type=%d\n", static_cast<int>(whichType));
|
||||
break;
|
||||
}
|
||||
scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG;
|
||||
}
|
||||
if (whichType == TX_PUBKEY)
|
||||
if (whichType == TxnOutType::PubKey)
|
||||
{
|
||||
valtype& vchPubKey = vSolutions[0];
|
||||
if (!keystore.GetKey(Hash160(vchPubKey), key))
|
||||
{
|
||||
if (fDebug && GetBoolArg("-printcoinstake"))
|
||||
printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
|
||||
printf("CreateCoinStake : failed to get key for kernel type=%d\n", static_cast<int>(whichType));
|
||||
break; // unable to find corresponding public key
|
||||
}
|
||||
|
||||
@@ -2160,7 +2145,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
||||
// This is only to keep the database open to defeat the auto-flush for the
|
||||
// duration of this scope. This is the only place where this optimization
|
||||
// maybe makes sense; please don't do it anywhere else.
|
||||
CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
|
||||
CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : nullptr;
|
||||
|
||||
// Take key pair from key pool so it won't be used again
|
||||
reservekey.KeepKey();
|
||||
@@ -2178,7 +2163,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
|
||||
coin.MarkSpent(txin.prevout.n);
|
||||
coin.WriteToDisk();
|
||||
try { NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); }
|
||||
catch (...) { }
|
||||
catch (...) { printf("WARNING: NotifyTransactionChanged exception in CommitTransaction\n"); }
|
||||
}
|
||||
|
||||
if (fFileBacked)
|
||||
@@ -2295,7 +2280,7 @@ bool CWallet::SetAddressBookName(const CTxDestination& address, const string& st
|
||||
ChangeType nMode;
|
||||
{
|
||||
LOCK(cs_wallet); // mapAddressBook
|
||||
std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
|
||||
auto mi = mapAddressBook.find(address);
|
||||
nMode = (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED;
|
||||
fOwned = ::IsMine(*this, address);
|
||||
|
||||
@@ -2308,7 +2293,7 @@ bool CWallet::SetAddressBookName(const CTxDestination& address, const string& st
|
||||
SecureMsgWalletKeyChanged(caddress.ToString(), strName, nMode);
|
||||
}
|
||||
try { NotifyAddressBookChanged(this, address, strName, fOwned, nMode); }
|
||||
catch (...) { }
|
||||
catch (...) { printf("WARNING: NotifyAddressBookChanged exception in SetAddressBookName\n"); }
|
||||
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
@@ -2331,7 +2316,7 @@ bool CWallet::DelAddressBookName(const CTxDestination& address)
|
||||
SecureMsgWalletKeyChanged(caddress.ToString(), sName, CT_DELETED);
|
||||
}
|
||||
try { NotifyAddressBookChanged(this, address, "", fOwned, CT_DELETED); }
|
||||
catch (...) { }
|
||||
catch (...) { printf("WARNING: NotifyAddressBookChanged exception in DelAddressBookName\n"); }
|
||||
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
@@ -2362,10 +2347,9 @@ bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
|
||||
{
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
|
||||
if (mi != mapWallet.end())
|
||||
if (auto mi = mapWallet.find(hashTx); mi != mapWallet.end())
|
||||
{
|
||||
wtx = (*mi).second;
|
||||
wtx = mi->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2686,8 +2670,8 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64_t& nBalanceInQuestion, bo
|
||||
LOCK(cs_wallet);
|
||||
vector<CWalletTx*> vCoins;
|
||||
vCoins.reserve(mapWallet.size());
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
|
||||
vCoins.push_back(&(*it).second);
|
||||
for (auto& [hash, wtx] : mapWallet)
|
||||
vCoins.push_back(&wtx);
|
||||
|
||||
auto txdb_holder = MakeChainDB("r"); CTxDBBase& txdb = *txdb_holder;
|
||||
for (CWalletTx* pcoin : vCoins)
|
||||
@@ -2737,10 +2721,9 @@ void CWallet::DisableTransaction(const CTransaction &tx)
|
||||
LOCK(cs_wallet);
|
||||
for (const CTxIn& txin : tx.vin)
|
||||
{
|
||||
map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
if (mi != mapWallet.end())
|
||||
if (auto mi = mapWallet.find(txin.prevout.hash); mi != mapWallet.end())
|
||||
{
|
||||
CWalletTx& prev = (*mi).second;
|
||||
auto& [hash, prev] = *mi;
|
||||
if (txin.prevout.n < prev.vout.size() && IsMine(prev.vout[txin.prevout.n]))
|
||||
{
|
||||
prev.MarkUnspent(txin.prevout.n);
|
||||
@@ -2809,11 +2792,10 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
// Only notify UI if this transaction is in this wallet
|
||||
map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
|
||||
if (mi != mapWallet.end() && !IsInitialBlockDownload())
|
||||
if (auto mi = mapWallet.find(hashTx); mi != mapWallet.end() && !IsInitialBlockDownload())
|
||||
{
|
||||
try { NotifyTransactionChanged(this, hashTx, CT_UPDATED); }
|
||||
catch (...) { }
|
||||
catch (...) { printf("WARNING: NotifyTransactionChanged exception in UpdatedTransaction\n"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2822,9 +2804,9 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
|
||||
mapKeyBirth.clear();
|
||||
|
||||
// get birth times for keys with metadata
|
||||
for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
|
||||
if (it->second.nCreateTime)
|
||||
mapKeyBirth[it->first] = it->second.nCreateTime;
|
||||
for (const auto& [keyId, meta] : mapKeyMetadata)
|
||||
if (meta.nCreateTime)
|
||||
mapKeyBirth[keyId] = meta.nCreateTime;
|
||||
|
||||
// map in which we'll infer heights of other keys
|
||||
CBlockIndex *pindexMax = FindBlockByHeight(std::max(0, nBestHeight - 144)); // the tip can be reorganised; use a 144-block safety margin
|
||||
@@ -2843,11 +2825,8 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
|
||||
|
||||
// find first block that affects those keys, if there are any left
|
||||
std::vector<CKeyID> vAffected;
|
||||
for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
|
||||
// iterate over all wallet transactions...
|
||||
const CWalletTx &wtx = (*it).second;
|
||||
std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
|
||||
if (blit != mapBlockIndex.end() && blit->second->IsInMainChain()) {
|
||||
for (const auto& [hash, wtx] : mapWallet) {
|
||||
if (auto blit = mapBlockIndex.find(wtx.hashBlock); blit != mapBlockIndex.end() && blit->second->IsInMainChain()) {
|
||||
// ... which are already in a block
|
||||
int nHeight = blit->second->nHeight;
|
||||
for (const CTxOut &txout : wtx.vout) {
|
||||
@@ -2855,8 +2834,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
|
||||
::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected);
|
||||
for (const CKeyID &keyid : vAffected) {
|
||||
// ... and all their affected keys
|
||||
std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
|
||||
if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
|
||||
if (auto rit = mapKeyFirstBlock.find(keyid); rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
|
||||
rit->second = blit->second;
|
||||
}
|
||||
vAffected.clear();
|
||||
@@ -2865,8 +2843,8 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
|
||||
}
|
||||
|
||||
// Extract block timestamps for those keys
|
||||
for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
|
||||
mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
|
||||
for (const auto& [keyId, pindex] : mapKeyFirstBlock)
|
||||
mapKeyBirth[keyId] = pindex->nTime - 7200; // block times can be 2h off
|
||||
}
|
||||
|
||||
|
||||
|
||||
+27
-37
@@ -29,17 +29,15 @@ class COutput;
|
||||
class CCoinControl;
|
||||
|
||||
//typedef std::map<CKeyID, CStealthKeyMetadata> StealthKeyMetaMap;
|
||||
typedef std::map<std::string, std::string> mapValue_t;
|
||||
using mapValue_t = std::map<std::string, std::string>;
|
||||
|
||||
/** (client) version numbers for particular wallet features */
|
||||
enum WalletFeature
|
||||
enum class WalletFeature : int
|
||||
{
|
||||
FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output)
|
||||
|
||||
FEATURE_WALLETCRYPT = 40000, // wallet encryption
|
||||
FEATURE_COMPRPUBKEY = 60000, // compressed public keys
|
||||
|
||||
FEATURE_LATEST = 60000
|
||||
Base = 10500,
|
||||
WalletCrypt = 40000,
|
||||
ComprPubKey = 60000,
|
||||
Latest = 60000
|
||||
};
|
||||
|
||||
/** A key pool entry */
|
||||
@@ -76,7 +74,7 @@ class CWallet : public CCryptoKeyStore
|
||||
{
|
||||
private:
|
||||
bool SelectCoinsSimple(int64_t nTargetValue, unsigned int nSpendTime, int nMinConf, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const;
|
||||
bool SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl=NULL) const;
|
||||
bool SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl=nullptr) const;
|
||||
|
||||
CWalletDB *pwalletdbEncryption;
|
||||
|
||||
@@ -102,26 +100,19 @@ public:
|
||||
|
||||
CWallet()
|
||||
{
|
||||
nWalletVersion = FEATURE_BASE;
|
||||
nWalletMaxVersion = FEATURE_BASE;
|
||||
nWalletVersion = static_cast<int>(WalletFeature::Base);
|
||||
nWalletMaxVersion = static_cast<int>(WalletFeature::Base);
|
||||
fFileBacked = false;
|
||||
nMasterKeyMaxID = 0;
|
||||
pwalletdbEncryption = NULL;
|
||||
pwalletdbEncryption = nullptr;
|
||||
nOrderPosNext = 0;
|
||||
nCachedStakeWeight = 0;
|
||||
nCachedStakeWeightTime = 0;
|
||||
}
|
||||
CWallet(std::string strWalletFileIn)
|
||||
CWallet(std::string strWalletFileIn) : CWallet()
|
||||
{
|
||||
nWalletVersion = FEATURE_BASE;
|
||||
nWalletMaxVersion = FEATURE_BASE;
|
||||
strWalletFile = strWalletFileIn;
|
||||
fFileBacked = true;
|
||||
nMasterKeyMaxID = 0;
|
||||
pwalletdbEncryption = NULL;
|
||||
nOrderPosNext = 0;
|
||||
nCachedStakeWeight = 0;
|
||||
nCachedStakeWeightTime = 0;
|
||||
}
|
||||
|
||||
std::map<uint256, CWalletTx> mapWallet;
|
||||
@@ -134,10 +125,10 @@ public:
|
||||
int64_t nTimeFirstKey;
|
||||
|
||||
// check whether we are allowed to upgrade (or already support) to the named feature
|
||||
bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
|
||||
bool CanSupportFeature(WalletFeature wf) { return nWalletMaxVersion >= static_cast<int>(wf); }
|
||||
|
||||
void AvailableCoinsMinConf(std::vector<COutput>& vCoins, int nConf) const;
|
||||
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const;
|
||||
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=nullptr) const;
|
||||
bool SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const;
|
||||
// keystore implementation
|
||||
// Generate a new key
|
||||
@@ -169,7 +160,7 @@ public:
|
||||
/** Increment the next transaction order id
|
||||
@return next transaction order id
|
||||
*/
|
||||
int64_t IncOrderPosNext(CWalletDB *pwalletdb = NULL);
|
||||
int64_t IncOrderPosNext(CWalletDB *pwalletdb = nullptr);
|
||||
|
||||
typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
|
||||
typedef std::multimap<int64_t, TxPair > TxItems;
|
||||
@@ -186,7 +177,7 @@ public:
|
||||
bool EraseFromWallet(uint256 hash);
|
||||
void WalletUpdateSpent(const CTransaction& prevout, bool fBlock = false);
|
||||
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
|
||||
bool ScanForWalletTransactionsFromIndex(CBlockIndex* pindexStart, bool fUpdate, int* pnFound = NULL);
|
||||
bool ScanForWalletTransactionsFromIndex(CBlockIndex* pindexStart, bool fUpdate, int* pnFound = nullptr);
|
||||
int ScanForWalletTransaction(const uint256& hashTx);
|
||||
void ReacceptWalletTransactions();
|
||||
void ResendWalletTransactions(bool fForce = false);
|
||||
@@ -197,8 +188,8 @@ public:
|
||||
int64_t GetNewMint() const;
|
||||
// Get all balances in a single lock acquisition + single pass (avoids 4x lock + 4x iteration)
|
||||
bool GetAllBalances(int64_t& nBalance, int64_t& nStake, int64_t& nUnconfirmed, int64_t& nImmature) const;
|
||||
bool CreateTransaction(const std::vector<std::pair<CScript, int64_t> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl *coinControl=NULL);
|
||||
bool CreateTransaction(CScript scriptPubKey, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl *coinControl=NULL);
|
||||
bool CreateTransaction(const std::vector<std::pair<CScript, int64_t> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl *coinControl=nullptr);
|
||||
bool CreateTransaction(CScript scriptPubKey, int64_t nValue, std::string& sNarr, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl *coinControl=nullptr);
|
||||
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
|
||||
|
||||
bool GetStakeWeight(const CKeyStore& keystore, uint64_t& nMinWeight, uint64_t& nMaxWeight, uint64_t& nWeight);
|
||||
@@ -225,9 +216,9 @@ public:
|
||||
std::set< std::set<CTxDestination> > GetAddressGroupings();
|
||||
std::map<CTxDestination, int64_t> GetAddressBalances();
|
||||
|
||||
bool IsMine(const CTxIn& txin) const;
|
||||
[[nodiscard]] bool IsMine(const CTxIn& txin) const;
|
||||
int64_t GetDebit(const CTxIn& txin) const;
|
||||
bool IsMine(const CTxOut& txout) const
|
||||
[[nodiscard]] bool IsMine(const CTxOut& txout) const
|
||||
{
|
||||
return ::IsMine(*this, txout.scriptPubKey);
|
||||
}
|
||||
@@ -244,7 +235,7 @@ public:
|
||||
throw std::runtime_error("CWallet::GetChange() : value out of range");
|
||||
return (IsChange(txout) ? txout.nValue : 0);
|
||||
}
|
||||
bool IsMine(const CTransaction& tx) const
|
||||
[[nodiscard]] bool IsMine(const CTransaction& tx) const
|
||||
{
|
||||
for (const CTxOut& txout : tx.vout)
|
||||
if (IsMine(txout) && txout.nValue >= nMinimumInputValue)
|
||||
@@ -320,7 +311,7 @@ public:
|
||||
bool SetDefaultKey(const CPubKey &vchPubKey);
|
||||
|
||||
// signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
|
||||
bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
|
||||
bool SetMinVersion(WalletFeature, CWalletDB* pwalletdbIn = nullptr, bool fExplicit = false);
|
||||
|
||||
// change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
|
||||
bool SetMaxVersion(int nVersion);
|
||||
@@ -368,8 +359,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
typedef std::map<std::string, std::string> mapValue_t;
|
||||
|
||||
|
||||
static void ReadOrderPos(int64_t& nOrderPos, mapValue_t& mapValue)
|
||||
{
|
||||
@@ -422,7 +411,7 @@ public:
|
||||
|
||||
CWalletTx()
|
||||
{
|
||||
Init(NULL);
|
||||
Init(nullptr);
|
||||
}
|
||||
|
||||
CWalletTx(const CWallet* pwalletIn)
|
||||
@@ -467,7 +456,7 @@ public:
|
||||
(
|
||||
CWalletTx* pthis = const_cast<CWalletTx*>(this);
|
||||
if (fRead)
|
||||
pthis->Init(NULL);
|
||||
pthis->Init(nullptr);
|
||||
char fSpent = false;
|
||||
|
||||
if (!fRead)
|
||||
@@ -592,6 +581,7 @@ public:
|
||||
{
|
||||
if (vin.empty())
|
||||
return 0;
|
||||
LOCK(pwallet->cs_wallet);
|
||||
if (fDebitCached)
|
||||
return nDebitCached;
|
||||
nDebitCached = pwallet->GetDebit(*this);
|
||||
@@ -601,11 +591,10 @@ public:
|
||||
|
||||
int64_t GetCredit(bool fUseCache=true) const
|
||||
{
|
||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||
if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
|
||||
return 0;
|
||||
|
||||
// GetBalance can assume transactions in mapWallet won't change
|
||||
LOCK(pwallet->cs_wallet);
|
||||
if (fUseCache && fCreditCached)
|
||||
return nCreditCached;
|
||||
nCreditCached = pwallet->GetCredit(*this);
|
||||
@@ -615,10 +604,10 @@ public:
|
||||
|
||||
int64_t GetAvailableCredit(bool fUseCache=true) const
|
||||
{
|
||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||
if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
|
||||
return 0;
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
if (fUseCache && fAvailableCreditCached)
|
||||
return nAvailableCreditCached;
|
||||
|
||||
@@ -642,6 +631,7 @@ public:
|
||||
|
||||
int64_t GetChange() const
|
||||
{
|
||||
LOCK(pwallet->cs_wallet);
|
||||
if (fChangeCached)
|
||||
return nChangeCached;
|
||||
nChangeCached = pwallet->GetChange(*this);
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
#include <zmq.h>
|
||||
#include <string.h>
|
||||
|
||||
CZMQPublishNotifier* pzmqNotifier = NULL;
|
||||
CZMQPublishNotifier* pzmqNotifier = nullptr;
|
||||
|
||||
CZMQPublishNotifier::CZMQPublishNotifier()
|
||||
: pcontext(NULL), psocket(NULL), fInitialized(false)
|
||||
: pcontext(nullptr), psocket(nullptr), fInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ bool CZMQPublishNotifier::Initialize(const std::string& addr)
|
||||
{
|
||||
printf("ZMQ: Failed to create socket\n");
|
||||
zmq_ctx_destroy(pcontext);
|
||||
pcontext = NULL;
|
||||
pcontext = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ bool CZMQPublishNotifier::Initialize(const std::string& addr)
|
||||
printf("ZMQ: Failed to bind to %s: %s\n", address.c_str(), zmq_strerror(errno));
|
||||
zmq_close(psocket);
|
||||
zmq_ctx_destroy(pcontext);
|
||||
psocket = NULL;
|
||||
pcontext = NULL;
|
||||
psocket = nullptr;
|
||||
pcontext = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -65,12 +65,12 @@ void CZMQPublishNotifier::Shutdown()
|
||||
if (psocket)
|
||||
{
|
||||
zmq_close(psocket);
|
||||
psocket = NULL;
|
||||
psocket = nullptr;
|
||||
}
|
||||
if (pcontext)
|
||||
{
|
||||
zmq_ctx_destroy(pcontext);
|
||||
pcontext = NULL;
|
||||
pcontext = nullptr;
|
||||
}
|
||||
fInitialized = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user