Initial Vexta Core v0.1.0 release

This commit is contained in:
Capri 2026-07-15 14:07:28 +00:00
commit 25c454329d
2481 changed files with 689289 additions and 0 deletions

57
src/compat/assumptions.h Normal file
View file

@ -0,0 +1,57 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// Compile-time verification of assumptions we make.
#ifndef DIGIBYTE_COMPAT_ASSUMPTIONS_H
#define DIGIBYTE_COMPAT_ASSUMPTIONS_H
#include <limits>
// Assumption: We assume that the macro NDEBUG is not defined.
// Example(s): We use assert(...) extensively with the assumption of it never
// being a noop at runtime.
#if defined(NDEBUG)
# error "Vexta cannot be compiled without assertions."
#endif
// Assumption: We assume a C++17 (ISO/IEC 14882:2017) compiler (minimum requirement).
// Example(s): We assume the presence of C++17 features everywhere :-)
// ISO Standard C++17 [cpp.predefined]p1:
// "The name __cplusplus is defined to the value 201703L when compiling a C++
// translation unit."
static_assert(__cplusplus >= 201703L, "C++17 standard assumed");
// Assumption: We assume the floating-point types to fulfill the requirements of
// IEC 559 (IEEE 754) standard.
// Example(s): Floating-point division by zero in ConnectBlock, CreateTransaction
// and EstimateMedianVal.
static_assert(std::numeric_limits<float>::is_iec559, "IEEE 754 float assumed");
static_assert(std::numeric_limits<double>::is_iec559, "IEEE 754 double assumed");
// Assumption: We assume eight bits per byte (obviously, but remember: don't
// trust -- verify!).
// Example(s): Everywhere :-)
static_assert(std::numeric_limits<unsigned char>::digits == 8, "8-bit byte assumed");
// Assumption: We assume integer widths.
// Example(s): GetSizeOfCompactSize and WriteCompactSize in the serialization
// code.
static_assert(sizeof(short) == 2, "16-bit short assumed");
static_assert(sizeof(int) == 4, "32-bit int assumed");
static_assert(sizeof(unsigned) == 4, "32-bit unsigned assumed");
// Assumption: We assume size_t to be 32-bit or 64-bit.
// Example(s): size_t assumed to be at least 32-bit in ecdsa_signature_parse_der_lax(...).
// size_t assumed to be 32-bit or 64-bit in MallocUsage(...).
static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t assumed to be 32-bit or 64-bit");
static_assert(sizeof(size_t) == sizeof(void*), "Sizes of size_t and void* assumed to be equal");
// Some important things we are NOT assuming (non-exhaustive list):
// * We are NOT assuming a specific value for std::endian::native.
// * We are NOT assuming a specific value for std::locale("").name().
// * We are NOT assuming a specific value for std::numeric_limits<char>::is_signed.
#endif // DIGIBYTE_COMPAT_ASSUMPTIONS_H

60
src/compat/byteswap.h Normal file
View file

@ -0,0 +1,60 @@
// Copyright (c) 2014-2019 The Bitcoin Core developers
// Copyright (c) 2014-2019 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_COMPAT_BYTESWAP_H
#define DIGIBYTE_COMPAT_BYTESWAP_H
#if defined(HAVE_CONFIG_H)
#include <config/vexta-config.h>
#endif
#include <stdint.h>
#if defined(HAVE_BYTESWAP_H)
#include <byteswap.h>
#endif
#if defined(MAC_OSX)
#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
#else
// Non-MacOS / non-Darwin
#if HAVE_DECL_BSWAP_16 == 0
inline uint16_t bswap_16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
#endif // HAVE_DECL_BSWAP16 == 0
#if HAVE_DECL_BSWAP_32 == 0
inline uint32_t bswap_32(uint32_t x)
{
return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
}
#endif // HAVE_DECL_BSWAP32 == 0
#if HAVE_DECL_BSWAP_64 == 0
inline uint64_t bswap_64(uint64_t x)
{
return (((x & 0xff00000000000000ull) >> 56)
| ((x & 0x00ff000000000000ull) >> 40)
| ((x & 0x0000ff0000000000ull) >> 24)
| ((x & 0x000000ff00000000ull) >> 8)
| ((x & 0x00000000ff000000ull) << 8)
| ((x & 0x0000000000ff0000ull) << 24)
| ((x & 0x000000000000ff00ull) << 40)
| ((x & 0x00000000000000ffull) << 56));
}
#endif // HAVE_DECL_BSWAP64 == 0
#endif // defined(MAC_OSX)
#endif // DIGIBYTE_COMPAT_BYTESWAP_H

24
src/compat/cpuid.h Normal file
View file

@ -0,0 +1,24 @@
// Copyright (c) 2017-2019 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_COMPAT_CPUID_H
#define DIGIBYTE_COMPAT_CPUID_H
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
#define HAVE_GETCPUID
#include <cpuid.h>
// We can't use cpuid.h's __get_cpuid as it does not support subleafs.
void static inline GetCPUID(uint32_t leaf, uint32_t subleaf, uint32_t& a, uint32_t& b, uint32_t& c, uint32_t& d)
{
#ifdef __GNUC__
__cpuid_count(leaf, subleaf, a, b, c, d);
#else
__asm__ ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(leaf), "2"(subleaf));
#endif
}
#endif // defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
#endif // DIGIBYTE_COMPAT_CPUID_H

242
src/compat/endian.h Normal file
View file

@ -0,0 +1,242 @@
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Copyright (c) 2014-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_COMPAT_ENDIAN_H
#define DIGIBYTE_COMPAT_ENDIAN_H
#if defined(HAVE_CONFIG_H)
#include <config/vexta-config.h>
#endif
#include <compat/byteswap.h>
#include <stdint.h>
#if defined(HAVE_ENDIAN_H)
#include <endian.h>
#elif defined(HAVE_SYS_ENDIAN_H)
#include <sys/endian.h>
#endif
#ifndef HAVE_CONFIG_H
// While not technically a supported configuration, defaulting to defining these
// DECLs when we were compiled without autotools makes it easier for other build
// systems to build things like libvextaconsensus for strange targets.
#ifdef htobe16
#define HAVE_DECL_HTOBE16 1
#endif
#ifdef htole16
#define HAVE_DECL_HTOLE16 1
#endif
#ifdef be16toh
#define HAVE_DECL_BE16TOH 1
#endif
#ifdef le16toh
#define HAVE_DECL_LE16TOH 1
#endif
#ifdef htobe32
#define HAVE_DECL_HTOBE32 1
#endif
#ifdef htole32
#define HAVE_DECL_HTOLE32 1
#endif
#ifdef be32toh
#define HAVE_DECL_BE32TOH 1
#endif
#ifdef le32toh
#define HAVE_DECL_LE32TOH 1
#endif
#ifdef htobe64
#define HAVE_DECL_HTOBE64 1
#endif
#ifdef htole64
#define HAVE_DECL_HTOLE64 1
#endif
#ifdef be64toh
#define HAVE_DECL_BE64TOH 1
#endif
#ifdef le64toh
#define HAVE_DECL_LE64TOH 1
#endif
#endif // HAVE_CONFIG_H
#if defined(WORDS_BIGENDIAN)
#if HAVE_DECL_HTOBE16 == 0
inline uint16_t htobe16(uint16_t host_16bits)
{
return host_16bits;
}
#endif // HAVE_DECL_HTOBE16
#if HAVE_DECL_HTOLE16 == 0
inline uint16_t htole16(uint16_t host_16bits)
{
return bswap_16(host_16bits);
}
#endif // HAVE_DECL_HTOLE16
#if HAVE_DECL_BE16TOH == 0
inline uint16_t be16toh(uint16_t big_endian_16bits)
{
return big_endian_16bits;
}
#endif // HAVE_DECL_BE16TOH
#if HAVE_DECL_LE16TOH == 0
inline uint16_t le16toh(uint16_t little_endian_16bits)
{
return bswap_16(little_endian_16bits);
}
#endif // HAVE_DECL_LE16TOH
#if HAVE_DECL_HTOBE32 == 0
inline uint32_t htobe32(uint32_t host_32bits)
{
return host_32bits;
}
#endif // HAVE_DECL_HTOBE32
#if HAVE_DECL_HTOLE32 == 0
inline uint32_t htole32(uint32_t host_32bits)
{
return bswap_32(host_32bits);
}
#endif // HAVE_DECL_HTOLE32
#if HAVE_DECL_BE32TOH == 0
inline uint32_t be32toh(uint32_t big_endian_32bits)
{
return big_endian_32bits;
}
#endif // HAVE_DECL_BE32TOH
#if HAVE_DECL_LE32TOH == 0
inline uint32_t le32toh(uint32_t little_endian_32bits)
{
return bswap_32(little_endian_32bits);
}
#endif // HAVE_DECL_LE32TOH
#if HAVE_DECL_HTOBE64 == 0
inline uint64_t htobe64(uint64_t host_64bits)
{
return host_64bits;
}
#endif // HAVE_DECL_HTOBE64
#if HAVE_DECL_HTOLE64 == 0
inline uint64_t htole64(uint64_t host_64bits)
{
return bswap_64(host_64bits);
}
#endif // HAVE_DECL_HTOLE64
#if HAVE_DECL_BE64TOH == 0
inline uint64_t be64toh(uint64_t big_endian_64bits)
{
return big_endian_64bits;
}
#endif // HAVE_DECL_BE64TOH
#if HAVE_DECL_LE64TOH == 0
inline uint64_t le64toh(uint64_t little_endian_64bits)
{
return bswap_64(little_endian_64bits);
}
#endif // HAVE_DECL_LE64TOH
#else // WORDS_BIGENDIAN
#if HAVE_DECL_HTOBE16 == 0
inline uint16_t htobe16(uint16_t host_16bits)
{
return bswap_16(host_16bits);
}
#endif // HAVE_DECL_HTOBE16
#if HAVE_DECL_HTOLE16 == 0
inline uint16_t htole16(uint16_t host_16bits)
{
return host_16bits;
}
#endif // HAVE_DECL_HTOLE16
#if HAVE_DECL_BE16TOH == 0
inline uint16_t be16toh(uint16_t big_endian_16bits)
{
return bswap_16(big_endian_16bits);
}
#endif // HAVE_DECL_BE16TOH
#if HAVE_DECL_LE16TOH == 0
inline uint16_t le16toh(uint16_t little_endian_16bits)
{
return little_endian_16bits;
}
#endif // HAVE_DECL_LE16TOH
#if HAVE_DECL_HTOBE32 == 0
inline uint32_t htobe32(uint32_t host_32bits)
{
return bswap_32(host_32bits);
}
#endif // HAVE_DECL_HTOBE32
#if HAVE_DECL_HTOLE32 == 0
inline uint32_t htole32(uint32_t host_32bits)
{
return host_32bits;
}
#endif // HAVE_DECL_HTOLE32
#if HAVE_DECL_BE32TOH == 0
inline uint32_t be32toh(uint32_t big_endian_32bits)
{
return bswap_32(big_endian_32bits);
}
#endif // HAVE_DECL_BE32TOH
#if HAVE_DECL_LE32TOH == 0
inline uint32_t le32toh(uint32_t little_endian_32bits)
{
return little_endian_32bits;
}
#endif // HAVE_DECL_LE32TOH
#if HAVE_DECL_HTOBE64 == 0
inline uint64_t htobe64(uint64_t host_64bits)
{
return bswap_64(host_64bits);
}
#endif // HAVE_DECL_HTOBE64
#if HAVE_DECL_HTOLE64 == 0
inline uint64_t htole64(uint64_t host_64bits)
{
return host_64bits;
}
#endif // HAVE_DECL_HTOLE64
#if HAVE_DECL_BE64TOH == 0
inline uint64_t be64toh(uint64_t big_endian_64bits)
{
return bswap_64(big_endian_64bits);
}
#endif // HAVE_DECL_BE64TOH
#if HAVE_DECL_LE64TOH == 0
inline uint64_t le64toh(uint64_t little_endian_64bits)
{
return little_endian_64bits;
}
#endif // HAVE_DECL_LE64TOH
#endif // WORDS_BIGENDIAN
#endif // DIGIBYTE_COMPAT_ENDIAN_H

View file

@ -0,0 +1,63 @@
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Copyright (c) 2014-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <config/vexta-config.h>
#endif
#include <cstddef>
#include <cstdint>
#if defined(__i386__) || defined(__arm__)
extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp);
extern "C" int64_t __wrap___divmoddi4(int64_t u, int64_t v, int64_t* rp)
{
int32_t c1 = 0, c2 = 0;
int64_t uu = u, vv = v;
int64_t w;
int64_t r;
if (uu < 0) {
c1 = ~c1, c2 = ~c2, uu = -uu;
}
if (vv < 0) {
c1 = ~c1, vv = -vv;
}
w = __udivmoddi4(uu, vv, (uint64_t*)&r);
if (c1)
w = -w;
if (c2)
r = -r;
*rp = r;
return w;
}
#endif
extern "C" float log2f_old(float x);
#ifdef __i386__
__asm(".symver log2f_old,log2f@GLIBC_2.1");
#elif defined(__amd64__)
__asm(".symver log2f_old,log2f@GLIBC_2.2.5");
#elif defined(__arm__)
__asm(".symver log2f_old,log2f@GLIBC_2.4");
#elif defined(__aarch64__)
__asm(".symver log2f_old,log2f@GLIBC_2.17");
#elif defined(__powerpc64__)
# ifdef WORDS_BIGENDIAN
__asm(".symver log2f_old,log2f@GLIBC_2.3");
# else
__asm(".symver log2f_old,log2f@GLIBC_2.17");
# endif
#elif defined(__riscv)
__asm(".symver log2f_old,log2f@GLIBC_2.27");
#endif
extern "C" float __wrap_log2f(float x)
{
return log2f_old(x);
}

View file

@ -0,0 +1,69 @@
// Copyright (c) 2009-2019 The Bitcoin Core developers
// Copyright (c) 2014-2019 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <config/vexta-config.h>
#endif
#include <cstddef>
#if defined(HAVE_SYS_SELECT_H)
#include <sys/select.h>
#endif
extern "C" void* memcpy(void* a, const void* b, size_t c);
void* memcpy_int(void* a, const void* b, size_t c)
{
return memcpy(a, b, c);
}
namespace
{
// trigger: Use the memcpy_int wrapper which calls our internal memcpy.
// A direct call to memcpy may be optimized away by the compiler.
// test: Fill an array with a sequence of integers. memcpy to a new empty array.
// Verify that the arrays are equal. Use an odd size to decrease the odds of
// the call being optimized away.
template <unsigned int T>
bool sanity_test_memcpy()
{
unsigned int memcpy_test[T];
unsigned int memcpy_verify[T] = {};
for (unsigned int i = 0; i != T; ++i)
memcpy_test[i] = i;
memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test));
for (unsigned int i = 0; i != T; ++i) {
if (memcpy_verify[i] != i)
return false;
}
return true;
}
#if defined(HAVE_SYS_SELECT_H)
// trigger: Call FD_SET to trigger __fdelt_chk. FORTIFY_SOURCE must be defined
// as >0 and optimizations must be set to at least -O2.
// test: Add a file descriptor to an empty fd_set. Verify that it has been
// correctly added.
bool sanity_test_fdelt()
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return FD_ISSET(0, &fds);
}
#endif
} // namespace
bool glibc_sanity_test()
{
#if defined(HAVE_SYS_SELECT_H)
if (!sanity_test_fdelt())
return false;
#endif
return sanity_test_memcpy<1025>();
}

View file

@ -0,0 +1,62 @@
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Copyright (c) 2014-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <list>
#include <locale>
#include <stdexcept>
namespace
{
// trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init().
// test: convert a char from narrow to wide and back. Verify that the result
// matches the original.
bool sanity_test_widen(char testchar)
{
const std::ctype<char>& test(std::use_facet<std::ctype<char> >(std::locale()));
return test.narrow(test.widen(testchar), 'b') == testchar;
}
// trigger: use list::push_back and list::pop_back to trigger _M_hook and
// _M_unhook.
// test: Push a sequence of integers into a list. Pop them off and verify that
// they match the original sequence.
bool sanity_test_list(unsigned int size)
{
std::list<unsigned int> test;
for (unsigned int i = 0; i != size; ++i)
test.push_back(i + 1);
if (test.size() != size)
return false;
while (!test.empty()) {
if (test.back() != test.size())
return false;
test.pop_back();
}
return true;
}
} // namespace
// trigger: string::at(x) on an empty string to trigger __throw_out_of_range_fmt.
// test: force std::string to throw an out_of_range exception. Verify that
// it's caught correctly.
bool sanity_test_range_fmt()
{
std::string test;
try {
test.at(1);
} catch (const std::out_of_range&) {
return true;
} catch (...) {
}
return false;
}
bool glibcxx_sanity_test()
{
return sanity_test_widen('a') && sanity_test_list(100) && sanity_test_range_fmt();
}

10
src/compat/sanity.h Normal file
View file

@ -0,0 +1,10 @@
// Copyright (c) 2009-2014 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_COMPAT_SANITY_H
#define DIGIBYTE_COMPAT_SANITY_H
bool glibcxx_sanity_test();
#endif // DIGIBYTE_COMPAT_SANITY_H

72
src/compat/stdin.cpp Normal file
View file

@ -0,0 +1,72 @@
// Copyright (c) 2018-2019 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <config/vexta-config.h>
#endif
#include <cstdio> // for fileno(), stdin
#ifdef WIN32
#include <windows.h> // for SetStdinEcho()
#include <io.h> // for isatty()
#else
#include <termios.h> // for SetStdinEcho()
#include <unistd.h> // for SetStdinEcho(), isatty()
#include <poll.h> // for StdinReady()
#endif
#include <compat/stdin.h>
// https://stackoverflow.com/questions/1413445/reading-a-password-from-stdcin
void SetStdinEcho(bool enable)
{
#ifdef WIN32
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
if (!enable) {
mode &= ~ENABLE_ECHO_INPUT;
} else {
mode |= ENABLE_ECHO_INPUT;
}
SetConsoleMode(hStdin, mode);
#else
struct termios tty;
tcgetattr(STDIN_FILENO, &tty);
if (!enable) {
tty.c_lflag &= ~ECHO;
} else {
tty.c_lflag |= ECHO;
}
(void)tcsetattr(STDIN_FILENO, TCSANOW, &tty);
#endif
}
bool StdinTerminal()
{
#ifdef WIN32
return _isatty(_fileno(stdin));
#else
return isatty(fileno(stdin));
#endif
}
bool StdinReady()
{
if (!StdinTerminal()) {
return true;
}
#ifdef WIN32
return false;
#else
struct pollfd fds;
fds.fd = 0; /* this is STDIN */
fds.events = POLLIN;
return poll(&fds, 1, 0) == 1;
#endif
}
NoechoInst::NoechoInst() { SetStdinEcho(false); }
NoechoInst::~NoechoInst() { SetStdinEcho(true); }

18
src/compat/stdin.h Normal file
View file

@ -0,0 +1,18 @@
// Copyright (c) 2018 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DIGIBYTE_COMPAT_STDIN_H
#define DIGIBYTE_COMPAT_STDIN_H
struct NoechoInst {
NoechoInst();
~NoechoInst();
};
#define NO_STDIN_ECHO() NoechoInst _no_echo
bool StdinTerminal();
bool StdinReady();
#endif // DIGIBYTE_COMPAT_STDIN_H

19
src/compat/strnlen.cpp Normal file
View file

@ -0,0 +1,19 @@
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Copyright (c) 2014-2020 The DigiByte Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#if defined(HAVE_CONFIG_H)
#include <config/vexta-config.h>
#endif
#include <cstring>
#if HAVE_DECL_STRNLEN == 0
size_t strnlen( const char *start, size_t max_len)
{
const char *end = (const char *)memchr(start, '\0', max_len);
return end ? (size_t)(end - start) : max_len;
}
#endif // HAVE_DECL_STRNLEN