First cut at a C shared library interface to node.

This commit is contained in:
clemahieu 2017-12-09 23:15:57 -06:00
commit 9c60d6b5d4
15 changed files with 735 additions and 629 deletions

View file

@ -203,6 +203,12 @@ add_library (secure
rai/versioning.hpp
rai/versioning.cpp)
add_library (rai_lib SHARED
rai/interface.cpp
rai/interface.h
rai/numbers.cpp
rai/numbers.hpp)
add_library (node
${PLATFORM_NODE_SOURCE}
rai/node/bootstrap.cpp
@ -290,7 +296,7 @@ add_executable (rai_node
set_target_properties (argon2 PROPERTIES COMPILE_FLAGS "${PLATFORM_C_FLAGS} ${PLATFORM_COMPILE_FLAGS}")
set_target_properties (blake2 PROPERTIES COMPILE_FLAGS "${PLATFORM_C_FLAGS} ${PLATFORM_COMPILE_FLAGS} -D__SSE2__")
set_target_properties (ed25519 PROPERTIES COMPILE_FLAGS "${PLATFORM_C_FLAGS} ${PLATFORM_COMPILE_FLAGS} -DED25519_CUSTOMHASH -DED25519_CUSTOMRNG")
set_target_properties (secure node rai_node PROPERTIES COMPILE_FLAGS "${PLATFORM_CXX_FLAGS} ${PLATFORM_COMPILE_FLAGS} -DQT_NO_KEYWORDS -DACTIVE_NETWORK=${ACTIVE_NETWORK} -DRAIBLOCKS_VERSION_MAJOR=${CPACK_PACKAGE_VERSION_MAJOR} -DRAIBLOCKS_VERSION_MINOR=${CPACK_PACKAGE_VERSION_MINOR} -DBOOST_ASIO_HAS_STD_ARRAY=1")
set_target_properties (secure node rai_node rai_lib PROPERTIES COMPILE_FLAGS "${PLATFORM_CXX_FLAGS} ${PLATFORM_COMPILE_FLAGS} -DQT_NO_KEYWORDS -DACTIVE_NETWORK=${ACTIVE_NETWORK} -DRAIBLOCKS_VERSION_MAJOR=${CPACK_PACKAGE_VERSION_MAJOR} -DRAIBLOCKS_VERSION_MINOR=${CPACK_PACKAGE_VERSION_MINOR} -DBOOST_ASIO_HAS_STD_ARRAY=1")
set_target_properties (secure node rai_node PROPERTIES LINK_FLAGS "${PLATFORM_LINK_FLAGS}")
if (WIN32)
@ -306,20 +312,22 @@ else (WIN32)
endif (WIN32)
if (RAIBLOCKS_TEST)
target_link_libraries (core_test node secure lmdb xxhash ed25519 argon2 blake2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (core_test node secure lmdb rai_lib argon2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (slow_test node secure lmdb xxhash ed25519 argon2 blake2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (slow_test node secure lmdb rai_lib argon2 ${CRYPTOPP_LIBRARY} gtest_main gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS})
endif (RAIBLOCKS_TEST)
if (RAIBLOCKS_GUI)
target_link_libraries (qt_test node secure lmdb xxhash ed25519 qt argon2 blake2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Test ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (qt_test node secure lmdb rai_lib qt argon2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Test ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (qt_system node secure lmdb xxhash ed25519 qt argon2 blake2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (qt_system node secure lmdb rai_lib qt argon2 ${CRYPTOPP_LIBRARY} gtest libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (rai_wallet node secure lmdb xxhash ed25519 qt argon2 blake2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS} ${PLATFORM_WALLET_LIBS})
target_link_libraries (rai_wallet node secure lmdb rai_lib qt argon2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} Qt5::Core Qt5::Gui Qt5::Widgets ${QT_QTGUI_LIBRARY} ${PLATFORM_LIBS} ${PLATFORM_WALLET_LIBS})
endif (RAIBLOCKS_GUI)
target_link_libraries (rai_node node secure lmdb xxhash ed25519 argon2 blake2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS})
target_link_libraries (rai_lib xxhash ed25519 blake2 ${CRYPTOPP_LIBRARY})
target_link_libraries (rai_node node secure lmdb rai_lib argon2 ${CRYPTOPP_LIBRARY} libminiupnpc-static ${Boost_ATOMIC_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_LOG_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_LOG_SETUP_LIBRARY} ${Boost_THREAD_LIBRARY} ${PLATFORM_LIBS})
set (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE)
if (RAIBLOCKS_GUI)

View file

@ -1,14 +1,15 @@
#include <boost/property_tree/json_parser.hpp>
#include <ed25519-donna/ed25519.h>
#include <fstream>
#include <gtest/gtest.h>
#include <rai/interface.h>
#include <rai/node/common.hpp>
#include <rai/node/node.hpp>
#include <ed25519-donna/ed25519.h>
TEST (ed25519, signing)
{
rai::uint256_union prv (0);
@ -323,4 +324,4 @@ TEST (block, confirm_req_serialization)
ASSERT_FALSE (error);
ASSERT_EQ (req, req2);
ASSERT_EQ (*req.block, *req2.block);
}
}

View file

@ -1,9 +1,10 @@
#include <ed25519-donna/ed25519.h>
#include <gtest/gtest.h>
#include <rai/interface.h>
#include <rai/secure.hpp>
#include <ed25519-donna/ed25519.h>
TEST (uint128_union, decode_dec)
{
rai::uint128_union value;

71
rai/interface.cpp Normal file
View file

@ -0,0 +1,71 @@
#include <rai/interface.h>
#include <xxhash/xxhash.h>
#include <ed25519-donna/ed25519.h>
#include <blake2/blake2.h>
#include <rai/numbers.hpp>
extern "C" {
void xrb_uint256_to_string (xrb_uint256 source, char * destination)
{
}
void xrb_uint512_to_string (xrb_uint512 source, char * destination)
{
}
int xrb_uint256_from_string (char * source, xrb_uint256 destination)
{
return 1;
}
int xrb_uint512_from_string (char * source, xrb_uint512 destination)
{
return 1;
}
int xrb_valid_address (char * account)
{
return 1;
}
void sign_transaction (char * transaction, xrb_uint256 private_key, xrb_uint512 signature)
{
}
#include <ed25519-donna/ed25519-hash-custom.h>
void ed25519_randombytes_unsafe (void * out, size_t outlen)
{
rai::random_pool.GenerateBlock (reinterpret_cast <uint8_t *> (out), outlen);
}
void ed25519_hash_init (ed25519_hash_context * ctx)
{
ctx->blake2 = new blake2b_state;
blake2b_init (reinterpret_cast <blake2b_state *> (ctx->blake2), 64);
}
void ed25519_hash_update (ed25519_hash_context * ctx, uint8_t const * in, size_t inlen)
{
blake2b_update (reinterpret_cast <blake2b_state *> (ctx->blake2), in, inlen);
}
void ed25519_hash_final (ed25519_hash_context * ctx, uint8_t * out)
{
blake2b_final (reinterpret_cast <blake2b_state *> (ctx->blake2), out, 64);
delete reinterpret_cast <blake2b_state *> (ctx->blake2);
}
void ed25519_hash (uint8_t * out, uint8_t const * in, size_t inlen)
{
ed25519_hash_context ctx;
ed25519_hash_init (&ctx);
ed25519_hash_update (&ctx, in, inlen);
ed25519_hash_final (&ctx, out);
}
}

34
rai/interface.h Normal file
View file

@ -0,0 +1,34 @@
#ifndef XRB_INTERFACE_H
#define XRB_INTERFACE_H
#if __cplusplus
extern "C" {
#endif
typedef char * xrb_uint256; // 32byte array for public and private keys
typedef char * xrb_uint512; // 64byte array for signatures
// Convert public/private key bytes 'source' to a 64 byte not-null-terminated hex string 'destination'
void xrb_uint256_to_string (xrb_uint256 source, char * destination);
// Convert public/private key bytes 'source' to a 128 byte not-null-terminated hex string 'destination'
void xrb_uint512_to_string (xrb_uint512 source, char * destination);
// Convert 64 byte hex string 'source' to a byte array 'destination'
// Return 0 on success, nonzero on error
int xrb_uint256_from_string (char * source, xrb_uint256 destination);
// Convert 128 byte hex string 'source' to a byte array 'destination'
// Return 0 on success, nonzero on error
int xrb_uint512_from_string (char * source, xrb_uint512 destination);
// Check if the null-terminated string 'account' is a valid xrb account number
// Return 0 on correct, nonzero on invalid
int xrb_valid_address (char * account);
// Sign 'transaction' using 'private_key' and write to 'signature'
void sign_transaction (char * transaction, xrb_uint256 private_key, xrb_uint512 signature);
#if __cplusplus
} // extern "C"
#endif
#endif // XRB_INTERFACE_H

View file

@ -1,13 +1,14 @@
#pragma once
#include <rai/interface.h>
#include <rai/secure.hpp>
#include <boost/asio.hpp>
#include <xxhash/xxhash.h>
#include <bitset>
#include <xxhash/xxhash.h>
namespace rai
{
using endpoint = boost::asio::ip::udp::endpoint;

View file

@ -1,5 +1,6 @@
#include <rai/node/node.hpp>
#include <rai/interface.h>
#include <rai/node/common.hpp>
#include <rai/node/rpc.hpp>
@ -18,10 +19,10 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <ed25519-donna/ed25519.h>
#include <upnpcommands.h>
#include <ed25519-donna/ed25519.h>
double constexpr rai::node::price_max;
double constexpr rai::node::free_cutoff;
std::chrono::seconds constexpr rai::node::period;

View file

@ -1,8 +1,10 @@
#include <rai/node/rpc.hpp>
#include <rai/node/node.hpp>
#include <boost/algorithm/string.hpp>
#include <rai/interface.h>
#include <rai/node/node.hpp>
#include <ed25519-donna/ed25519.h>
rai::rpc_config::rpc_config () :

View file

@ -1,5 +1,6 @@
#include <rai/node/wallet.hpp>
#include <rai/interface.h>
#include <rai/node/node.hpp>
#include <rai/node/xorshift.hpp>
@ -8,10 +9,10 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <ed25519-donna/ed25519.h>
#include <future>
#include <ed25519-donna/ed25519.h>
rai::work_pool::work_pool (unsigned max_threads_a, std::unique_ptr <rai::opencl_work> opencl_a) :
ticket (0),
done (false),

434
rai/numbers.cpp Normal file
View file

@ -0,0 +1,434 @@
#include <rai/numbers.hpp>
#include <ed25519-donna/ed25519.h>
#include <blake2/blake2.h>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
thread_local CryptoPP::AutoSeededRandomPool rai::random_pool;
namespace
{
char const * base58_reverse ("~012345678~~~~~~~9:;<=>?@~ABCDE~FGHIJKLMNOP~~~~~~QRSTUVWXYZ[~\\]^_`abcdefghi");
uint8_t base58_decode (char value)
{
assert (value >= '0');
assert (value <= '~');
auto result (base58_reverse [value - 0x30] - 0x30);
return result;
}
char const * account_lookup ("13456789abcdefghijkmnopqrstuwxyz");
char const * account_reverse ("~0~1234567~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~89:;<=>?@AB~CDEFGHIJK~LMNO~~~~~");
char account_encode (uint8_t value)
{
assert (value < 32);
auto result (account_lookup [value]);
return result;
}
uint8_t account_decode (char value)
{
assert (value >= '0');
assert (value <= '~');
auto result (account_reverse [value - 0x30] - 0x30);
return result;
}
}
void rai::uint256_union::encode_account (std::string & destination_a) const
{
assert (destination_a.empty ());
destination_a.reserve (64);
uint64_t check (0);
blake2b_state hash;
blake2b_init (&hash, 5);
blake2b_update (&hash, bytes.data (), bytes.size ());
blake2b_final (&hash, reinterpret_cast <uint8_t *> (&check), 5);
rai::uint512_t number_l (number ());
number_l <<= 40;
number_l |= rai::uint512_t (check);
for (auto i (0); i < 60; ++i)
{
auto r (number_l.convert_to <uint8_t> () & 0x1f);
number_l >>= 5;
destination_a.push_back (account_encode (r));
}
destination_a.append ("_brx"); // xrb_
std::reverse (destination_a.begin (), destination_a.end ());
}
std::string rai::uint256_union::to_account_split () const
{
auto result (to_account ());
assert (result.size () == 64);
result.insert (32, "\n");
return result;
}
std::string rai::uint256_union::to_account () const
{
std::string result;
encode_account (result);
return result;
}
bool rai::uint256_union::decode_account_v1 (std::string const & source_a)
{
auto result (source_a.size () != 50);
if (!result)
{
rai::uint512_t number_l;
for (auto i (source_a.begin ()), j (source_a.end ()); !result && i != j; ++i)
{
uint8_t character (*i);
result = character < 0x30 || character >= 0x80;
if (!result)
{
uint8_t byte (base58_decode (character));
result = byte == '~';
if (!result)
{
number_l *= 58;
number_l += byte;
}
}
}
if (!result)
{
*this = number_l.convert_to <rai::uint256_t> ();
uint32_t check ((number_l >> 256).convert_to <uint32_t> ());
result = (number_l >> (256 + 32)) != 13;
if (!result)
{
uint32_t validation;
blake2b_state hash;
blake2b_init (&hash, sizeof (validation));
blake2b_update (&hash, bytes.data (), sizeof (bytes));
blake2b_final (&hash, reinterpret_cast <uint8_t *> (&validation), sizeof (validation));
result = check != validation;
}
}
}
return result;
}
bool rai::uint256_union::decode_account (std::string const & source_a)
{
auto result (source_a.size () != 64);
if (!result)
{
if (source_a [0] == 'x' && source_a [1] == 'r' && source_a [2] == 'b' && (source_a [3] == '_' || source_a [3] == '-'))
{
rai::uint512_t number_l;
for (auto i (source_a.begin () + 4), j (source_a.end ()); !result && i != j; ++i)
{
uint8_t character (*i);
result = character < 0x30 || character >= 0x80;
if (!result)
{
uint8_t byte (account_decode (character));
result = byte == '~';
if (!result)
{
number_l <<= 5;
number_l += byte;
}
}
}
if (!result)
{
*this = (number_l >> 40).convert_to <rai::uint256_t> ();
uint64_t check (number_l.convert_to <uint64_t> ());
check &= 0xffffffffff;
uint64_t validation (0);
blake2b_state hash;
blake2b_init (&hash, 5);
blake2b_update (&hash, bytes.data (), bytes.size ());
blake2b_final (&hash, reinterpret_cast <uint8_t *> (&validation), 5);
result = check != validation;
}
}
else
{
result = true;
}
}
else
{
result = decode_account_v1 (source_a);
}
return result;
}
rai::uint256_union::uint256_union (rai::uint256_t const & number_a)
{
rai::uint256_t number_l (number_a);
for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i)
{
*i = ((number_l) & 0xff).convert_to <uint8_t> ();
number_l >>= 8;
}
}
bool rai::uint256_union::operator == (rai::uint256_union const & other_a) const
{
return bytes == other_a.bytes;
}
// Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv)
void rai::uint256_union::encrypt (rai::raw_key const & cleartext, rai::raw_key const & key, uint128_union const & iv)
{
CryptoPP::AES::Encryption alg (key.data.bytes.data (), sizeof (key.data.bytes));
CryptoPP::CTR_Mode_ExternalCipher::Encryption enc (alg, iv.bytes.data ());
enc.ProcessData (bytes.data (), cleartext.data.bytes.data (), sizeof (cleartext.data.bytes));
}
bool rai::uint256_union::is_zero () const
{
return qwords [0] == 0 && qwords [1] == 0 && qwords [2] == 0 && qwords [3] == 0;
}
std::string rai::uint256_union::to_string () const
{
std::string result;
encode_hex (result);
return result;
}
bool rai::uint256_union::operator < (rai::uint256_union const & other_a) const
{
return number () < other_a.number ();
}
rai::uint256_union & rai::uint256_union::operator ^= (rai::uint256_union const & other_a)
{
auto j (other_a.qwords.begin ());
for (auto i (qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j)
{
*i ^= *j;
}
return *this;
}
rai::uint256_union rai::uint256_union::operator ^ (rai::uint256_union const & other_a) const
{
rai::uint256_union result;
auto k (result.qwords.begin ());
for (auto i (qwords.begin ()), j (other_a.qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j, ++k)
{
*k = *i ^ *j;
}
return result;
}
rai::uint256_union::uint256_union (std::string const & hex_a)
{
decode_hex (hex_a);
}
void rai::uint256_union::clear ()
{
qwords.fill (0);
}
rai::uint256_t rai::uint256_union::number () const
{
rai::uint256_t result;
auto shift (0);
for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i)
{
result <<= shift;
result |= *i;
shift = 8;
}
return result;
}
void rai::uint256_union::encode_hex (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (64) << std::setfill ('0');
stream << number ();
text = stream.str ();
}
bool rai::uint256_union::decode_hex (std::string const & text)
{
auto result (false);
if (!text.empty ())
{
if (text.size () <= 64)
{
std::stringstream stream (text);
stream << std::hex << std::noshowbase;
rai::uint256_t number_l;
try
{
stream >> number_l;
*this = number_l;
if (!stream.eof ())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
else
{
result = true;
}
}
else
{
result = true;
}
return result;
}
void rai::uint256_union::encode_dec (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::dec << std::noshowbase;
stream << number ();
text = stream.str ();
}
bool rai::uint256_union::decode_dec (std::string const & text)
{
auto result (text.size () > 78);
if (!result)
{
std::stringstream stream (text);
stream << std::dec << std::noshowbase;
rai::uint256_t number_l;
try
{
stream >> number_l;
*this = number_l;
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
rai::uint256_union::uint256_union (uint64_t value0)
{
*this = rai::uint256_t (value0);
}
bool rai::uint256_union::operator != (rai::uint256_union const & other_a) const
{
return ! (*this == other_a);
}
bool rai::uint512_union::operator == (rai::uint512_union const & other_a) const
{
return bytes == other_a.bytes;
}
rai::uint512_union::uint512_union (rai::uint512_t const & number_a)
{
rai::uint512_t number_l (number_a);
for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i)
{
*i = ((number_l) & 0xff).convert_to <uint8_t> ();
number_l >>= 8;
}
}
void rai::uint512_union::clear ()
{
bytes.fill (0);
}
rai::uint512_t rai::uint512_union::number () const
{
rai::uint512_t result;
auto shift (0);
for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i)
{
result <<= shift;
result |= *i;
shift = 8;
}
return result;
}
void rai::uint512_union::encode_hex (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (128) << std::setfill ('0');
stream << number ();
text = stream.str ();
}
bool rai::uint512_union::decode_hex (std::string const & text)
{
auto result (text.size () > 128);
if (!result)
{
std::stringstream stream (text);
stream << std::hex << std::noshowbase;
rai::uint512_t number_l;
try
{
stream >> number_l;
*this = number_l;
if (!stream.eof ())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
bool rai::uint512_union::operator != (rai::uint512_union const & other_a) const
{
return ! (*this == other_a);
}
rai::uint512_union & rai::uint512_union::operator ^= (rai::uint512_union const & other_a)
{
uint256s [0] ^= other_a.uint256s [0];
uint256s [1] ^= other_a.uint256s [1];
return *this;
}
rai::raw_key::~raw_key ()
{
data.clear ();
}
bool rai::raw_key::operator == (rai::raw_key const & other_a) const
{
return data == other_a.data;
}
bool rai::raw_key::operator != (rai::raw_key const & other_a) const
{
return !(*this == other_a);
}
// This this = AES_DEC_CTR (ciphertext, key, iv)
void rai::raw_key::decrypt (rai::uint256_union const & ciphertext, rai::raw_key const & key_a, uint128_union const & iv)
{
CryptoPP::AES::Encryption alg (key_a.data.bytes.data (), sizeof (key_a.data.bytes));
CryptoPP::CTR_Mode_ExternalCipher::Decryption dec (alg, iv.bytes.data ());
dec.ProcessData (data.bytes.data (), ciphertext.bytes.data (), sizeof (ciphertext.bytes));
}

143
rai/numbers.hpp Normal file
View file

@ -0,0 +1,143 @@
#pragma once
#include <boost/multiprecision/cpp_int.hpp>
#include <cryptopp/osrng.h>
namespace rai {
// Random pool used by RaiBlocks.
// This must be thread_local as long as the AutoSeededRandomPool implementation requires it
extern thread_local CryptoPP::AutoSeededRandomPool random_pool;
using uint128_t = boost::multiprecision::uint128_t;
using uint256_t = boost::multiprecision::uint256_t;
using uint512_t = boost::multiprecision::uint512_t;
// SI dividers
rai::uint128_t const Gxrb_ratio = rai::uint128_t ("1000000000000000000000000000000000"); // 10^33
rai::uint128_t const Mxrb_ratio = rai::uint128_t ("1000000000000000000000000000000"); // 10^30
rai::uint128_t const kxrb_ratio = rai::uint128_t ("1000000000000000000000000000"); // 10^27
rai::uint128_t const xrb_ratio = rai::uint128_t ("1000000000000000000000000"); // 10^24
rai::uint128_t const mxrb_ratio = rai::uint128_t ("1000000000000000000000"); // 10^21
rai::uint128_t const uxrb_ratio = rai::uint128_t ("1000000000000000000"); // 10^18
union uint128_union
{
public:
uint128_union () = default;
uint128_union (std::string const &);
uint128_union (uint64_t);
uint128_union (rai::uint128_union const &) = default;
uint128_union (rai::uint128_t const &);
bool operator == (rai::uint128_union const &) const;
bool operator != (rai::uint128_union const &) const;
bool operator < (rai::uint128_union const &) const;
bool operator > (rai::uint128_union const &) const;
void encode_hex (std::string &) const;
bool decode_hex (std::string const &);
void encode_dec (std::string &) const;
bool decode_dec (std::string const &);
rai::uint128_t number () const;
void clear ();
bool is_zero () const;
std::string to_string () const;
std::string to_string_dec () const;
std::array <uint8_t, 16> bytes;
std::array <char, 16> chars;
std::array <uint32_t, 4> dwords;
std::array <uint64_t, 2> qwords;
};
// Balances are 128 bit.
using amount = uint128_union;
class raw_key;
union uint256_union
{
uint256_union () = default;
uint256_union (std::string const &);
uint256_union (uint64_t);
uint256_union (rai::uint256_t const &);
void encrypt (rai::raw_key const &, rai::raw_key const &, uint128_union const &);
uint256_union & operator ^= (rai::uint256_union const &);
uint256_union operator ^ (rai::uint256_union const &) const;
bool operator == (rai::uint256_union const &) const;
bool operator != (rai::uint256_union const &) const;
bool operator < (rai::uint256_union const &) const;
void encode_hex (std::string &) const;
bool decode_hex (std::string const &);
void encode_dec (std::string &) const;
bool decode_dec (std::string const &);
void encode_account (std::string &) const;
std::string to_account () const;
std::string to_account_split () const;
bool decode_account_v1 (std::string const &);
bool decode_account (std::string const &);
std::array <uint8_t, 32> bytes;
std::array <char, 32> chars;
std::array <uint32_t, 8> dwords;
std::array <uint64_t, 4> qwords;
std::array <uint128_union, 2> owords;
void clear ();
bool is_zero () const;
std::string to_string () const;
rai::uint256_t number () const;
};
// All keys and hashes are 256 bit.
using block_hash = uint256_union;
using account = uint256_union;
using public_key = uint256_union;
using private_key = uint256_union;
using secret_key = uint256_union;
using checksum = uint256_union;
class raw_key
{
public:
raw_key () = default;
~raw_key ();
void decrypt (rai::uint256_union const &, rai::raw_key const &, uint128_union const &);
raw_key (rai::raw_key const &) = delete;
raw_key (rai::raw_key const &&) = delete;
rai::raw_key & operator = (rai::raw_key const &) = delete;
bool operator == (rai::raw_key const &) const;
bool operator != (rai::raw_key const &) const;
rai::uint256_union data;
};
union uint512_union
{
uint512_union () = default;
uint512_union (rai::uint512_t const &);
bool operator == (rai::uint512_union const &) const;
bool operator != (rai::uint512_union const &) const;
rai::uint512_union & operator ^= (rai::uint512_union const &);
void encode_hex (std::string &) const;
bool decode_hex (std::string const &);
std::array <uint8_t, 64> bytes;
std::array <uint32_t, 16> dwords;
std::array <uint64_t, 8> qwords;
std::array <uint256_union, 2> uint256s;
void clear ();
rai::uint512_t number () const;
};
// Only signatures are 512 bit.
using signature = uint512_union;
rai::uint512_union sign_message (rai::raw_key const &, rai::public_key const &, rai::uint256_union const &);
bool validate_message (rai::public_key const &, rai::uint256_union const &, rai::uint512_union const &);
}
namespace std
{
template <>
struct hash <rai::uint256_union>
{
size_t operator () (rai::uint256_union const & data_a) const
{
return *reinterpret_cast <size_t const *> (data_a.bytes.data ());
}
};
template <>
struct hash <rai::uint256_t>
{
size_t operator () (rai::uint256_t const & number_a) const
{
return number_a.convert_to <size_t> ();
}
};
}

View file

@ -1,16 +1,15 @@
#include <rai/secure.hpp>
#include <rai/interface.h>
#include <rai/node/working.hpp>
#include <rai/versioning.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <blake2/blake2.h>
#include <queue>
#include <ed25519-donna/ed25519.h>
#include <queue>
// Genesis keys for network variants
namespace
{

View file

@ -5,6 +5,9 @@
#include <boost/property_tree/ptree.hpp>
#include <unordered_map>
#include <blake2/blake2.h>
namespace boost
{
template <>

View file

@ -1,13 +1,10 @@
#include <rai/utility.hpp>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <ed25519-donna/ed25519.h>
#include <rai/interface.h>
#include <lmdb/libraries/liblmdb/lmdb.h>
thread_local CryptoPP::AutoSeededRandomPool rai::random_pool;
#include <ed25519-donna/ed25519.h>
boost::filesystem::path rai::unique_path ()
{
@ -308,473 +305,17 @@ std::string rai::uint128_union::to_string_dec () const
return result;
}
bool rai::uint256_union::operator == (rai::uint256_union const & other_a) const
{
return bytes == other_a.bytes;
}
// Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv)
void rai::uint256_union::encrypt (rai::raw_key const & cleartext, rai::raw_key const & key, uint128_union const & iv)
{
CryptoPP::AES::Encryption alg (key.data.bytes.data (), sizeof (key.data.bytes));
CryptoPP::CTR_Mode_ExternalCipher::Encryption enc (alg, iv.bytes.data ());
enc.ProcessData (bytes.data (), cleartext.data.bytes.data (), sizeof (cleartext.data.bytes));
}
bool rai::uint256_union::is_zero () const
{
return qwords [0] == 0 && qwords [1] == 0 && qwords [2] == 0 && qwords [3] == 0;
}
std::string rai::uint256_union::to_string () const
{
std::string result;
encode_hex (result);
return result;
}
bool rai::uint256_union::operator < (rai::uint256_union const & other_a) const
{
return number () < other_a.number ();
}
rai::uint256_union & rai::uint256_union::operator ^= (rai::uint256_union const & other_a)
{
auto j (other_a.qwords.begin ());
for (auto i (qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j)
{
*i ^= *j;
}
return *this;
}
rai::uint256_union rai::uint256_union::operator ^ (rai::uint256_union const & other_a) const
{
rai::uint256_union result;
auto k (result.qwords.begin ());
for (auto i (qwords.begin ()), j (other_a.qwords.begin ()), n (qwords.end ()); i != n; ++i, ++j, ++k)
{
*k = *i ^ *j;
}
return result;
}
rai::uint256_union::uint256_union (std::string const & hex_a)
{
decode_hex (hex_a);
}
void rai::uint256_union::clear ()
{
qwords.fill (0);
}
rai::uint256_t rai::uint256_union::number () const
{
rai::uint256_t result;
auto shift (0);
for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i)
{
result <<= shift;
result |= *i;
shift = 8;
}
return result;
}
void rai::uint256_union::encode_hex (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (64) << std::setfill ('0');
stream << number ();
text = stream.str ();
}
bool rai::uint256_union::decode_hex (std::string const & text)
{
auto result (false);
if (!text.empty ())
{
if (text.size () <= 64)
{
std::stringstream stream (text);
stream << std::hex << std::noshowbase;
rai::uint256_t number_l;
try
{
stream >> number_l;
*this = number_l;
if (!stream.eof ())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
else
{
result = true;
}
}
else
{
result = true;
}
return result;
}
void rai::uint256_union::encode_dec (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::dec << std::noshowbase;
stream << number ();
text = stream.str ();
}
bool rai::uint256_union::decode_dec (std::string const & text)
{
auto result (text.size () > 78);
if (!result)
{
std::stringstream stream (text);
stream << std::dec << std::noshowbase;
rai::uint256_t number_l;
try
{
stream >> number_l;
*this = number_l;
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
rai::uint256_union::uint256_union (uint64_t value0)
{
*this = rai::uint256_t (value0);
}
bool rai::uint256_union::operator != (rai::uint256_union const & other_a) const
{
return ! (*this == other_a);
}
rai::raw_key::~raw_key ()
{
data.clear ();
}
bool rai::raw_key::operator == (rai::raw_key const & other_a) const
{
return data == other_a.data;
}
bool rai::raw_key::operator != (rai::raw_key const & other_a) const
{
return !(*this == other_a);
}
// This this = AES_DEC_CTR (ciphertext, key, iv)
void rai::raw_key::decrypt (rai::uint256_union const & ciphertext, rai::raw_key const & key_a, uint128_union const & iv)
{
CryptoPP::AES::Encryption alg (key_a.data.bytes.data (), sizeof (key_a.data.bytes));
CryptoPP::CTR_Mode_ExternalCipher::Decryption dec (alg, iv.bytes.data ());
dec.ProcessData (data.bytes.data (), ciphertext.bytes.data (), sizeof (ciphertext.bytes));
}
namespace
{
char const * base58_reverse ("~012345678~~~~~~~9:;<=>?@~ABCDE~FGHIJKLMNOP~~~~~~QRSTUVWXYZ[~\\]^_`abcdefghi");
uint8_t base58_decode (char value)
{
assert (value >= '0');
assert (value <= '~');
auto result (base58_reverse [value - 0x30] - 0x30);
return result;
}
char const * account_lookup ("13456789abcdefghijkmnopqrstuwxyz");
char const * account_reverse ("~0~1234567~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~89:;<=>?@AB~CDEFGHIJK~LMNO~~~~~");
char account_encode (uint8_t value)
{
assert (value < 32);
auto result (account_lookup [value]);
return result;
}
uint8_t account_decode (char value)
{
assert (value >= '0');
assert (value <= '~');
auto result (account_reverse [value - 0x30] - 0x30);
return result;
}
}
void rai::uint256_union::encode_account (std::string & destination_a) const
{
assert (destination_a.empty ());
destination_a.reserve (64);
uint64_t check (0);
blake2b_state hash;
blake2b_init (&hash, 5);
blake2b_update (&hash, bytes.data (), bytes.size ());
blake2b_final (&hash, reinterpret_cast <uint8_t *> (&check), 5);
rai::uint512_t number_l (number ());
number_l <<= 40;
number_l |= rai::uint512_t (check);
for (auto i (0); i < 60; ++i)
{
auto r (number_l.convert_to <uint8_t> () & 0x1f);
number_l >>= 5;
destination_a.push_back (account_encode (r));
}
destination_a.append ("_brx"); // xrb_
std::reverse (destination_a.begin (), destination_a.end ());
}
std::string rai::uint256_union::to_account_split () const
{
auto result (to_account ());
assert (result.size () == 64);
result.insert (32, "\n");
return result;
}
std::string rai::uint256_union::to_account () const
{
std::string result;
encode_account (result);
return result;
}
bool rai::uint256_union::decode_account_v1 (std::string const & source_a)
{
auto result (source_a.size () != 50);
if (!result)
{
rai::uint512_t number_l;
for (auto i (source_a.begin ()), j (source_a.end ()); !result && i != j; ++i)
{
uint8_t character (*i);
result = character < 0x30 || character >= 0x80;
if (!result)
{
uint8_t byte (base58_decode (character));
result = byte == '~';
if (!result)
{
number_l *= 58;
number_l += byte;
}
}
}
if (!result)
{
*this = number_l.convert_to <rai::uint256_t> ();
uint32_t check ((number_l >> 256).convert_to <uint32_t> ());
result = (number_l >> (256 + 32)) != 13;
if (!result)
{
uint32_t validation;
blake2b_state hash;
blake2b_init (&hash, sizeof (validation));
blake2b_update (&hash, bytes.data (), sizeof (bytes));
blake2b_final (&hash, reinterpret_cast <uint8_t *> (&validation), sizeof (validation));
result = check != validation;
}
}
}
return result;
}
bool rai::uint256_union::decode_account (std::string const & source_a)
{
auto result (source_a.size () != 64);
if (!result)
{
if (source_a [0] == 'x' && source_a [1] == 'r' && source_a [2] == 'b' && (source_a [3] == '_' || source_a [3] == '-'))
{
rai::uint512_t number_l;
for (auto i (source_a.begin () + 4), j (source_a.end ()); !result && i != j; ++i)
{
uint8_t character (*i);
result = character < 0x30 || character >= 0x80;
if (!result)
{
uint8_t byte (account_decode (character));
result = byte == '~';
if (!result)
{
number_l <<= 5;
number_l += byte;
}
}
}
if (!result)
{
*this = (number_l >> 40).convert_to <rai::uint256_t> ();
uint64_t check (number_l.convert_to <uint64_t> ());
check &= 0xffffffffff;
uint64_t validation (0);
blake2b_state hash;
blake2b_init (&hash, 5);
blake2b_update (&hash, bytes.data (), bytes.size ());
blake2b_final (&hash, reinterpret_cast <uint8_t *> (&validation), 5);
result = check != validation;
}
}
else
{
result = true;
}
}
else
{
result = decode_account_v1 (source_a);
}
return result;
}
rai::uint256_union::uint256_union (rai::uint256_t const & number_a)
{
rai::uint256_t number_l (number_a);
for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i)
{
*i = ((number_l) & 0xff).convert_to <uint8_t> ();
number_l >>= 8;
}
}
bool rai::uint512_union::operator == (rai::uint512_union const & other_a) const
{
return bytes == other_a.bytes;
}
rai::uint512_union::uint512_union (rai::uint512_t const & number_a)
{
rai::uint512_t number_l (number_a);
for (auto i (bytes.rbegin ()), n (bytes.rend ()); i != n; ++i)
{
*i = ((number_l) & 0xff).convert_to <uint8_t> ();
number_l >>= 8;
}
}
void rai::uint512_union::clear ()
{
bytes.fill (0);
}
rai::uint512_t rai::uint512_union::number () const
{
rai::uint512_t result;
auto shift (0);
for (auto i (bytes.begin ()), n (bytes.end ()); i != n; ++i)
{
result <<= shift;
result |= *i;
shift = 8;
}
return result;
}
void rai::uint512_union::encode_hex (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (128) << std::setfill ('0');
stream << number ();
text = stream.str ();
}
bool rai::uint512_union::decode_hex (std::string const & text)
{
auto result (text.size () > 128);
if (!result)
{
std::stringstream stream (text);
stream << std::hex << std::noshowbase;
rai::uint512_t number_l;
try
{
stream >> number_l;
*this = number_l;
if (!stream.eof ())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
bool rai::uint512_union::operator != (rai::uint512_union const & other_a) const
{
return ! (*this == other_a);
}
rai::uint512_union & rai::uint512_union::operator ^= (rai::uint512_union const & other_a)
{
uint256s [0] ^= other_a.uint256s [0];
uint256s [1] ^= other_a.uint256s [1];
return *this;
}
extern "C"
{
#include <ed25519-donna/ed25519-hash-custom.h>
void ed25519_randombytes_unsafe (void * out, size_t outlen)
{
rai::random_pool.GenerateBlock (reinterpret_cast <uint8_t *> (out), outlen);
}
void ed25519_hash_init (ed25519_hash_context * ctx)
{
ctx->blake2 = new blake2b_state;
blake2b_init (reinterpret_cast <blake2b_state *> (ctx->blake2), 64);
}
void ed25519_hash_update (ed25519_hash_context * ctx, uint8_t const * in, size_t inlen)
{
blake2b_update (reinterpret_cast <blake2b_state *> (ctx->blake2), in, inlen);
}
void ed25519_hash_final (ed25519_hash_context * ctx, uint8_t * out)
{
blake2b_final (reinterpret_cast <blake2b_state *> (ctx->blake2), out, 64);
delete reinterpret_cast <blake2b_state *> (ctx->blake2);
}
void ed25519_hash (uint8_t * out, uint8_t const * in, size_t inlen)
{
ed25519_hash_context ctx;
ed25519_hash_init (&ctx);
ed25519_hash_update (&ctx, in, inlen);
ed25519_hash_final (&ctx, out);
}
}
rai::uint512_union rai::sign_message (rai::raw_key const & private_key, rai::public_key const & public_key, rai::uint256_union const & message)
{
rai::uint512_union result;
ed25519_sign (message.bytes.data (), sizeof (message.bytes), private_key.data.bytes.data (), public_key.bytes.data (), result.bytes.data ());
ed25519_sign (message.bytes.data (), sizeof (message.bytes), private_key.data.bytes.data (), public_key.bytes.data (), result.bytes.data ());
return result;
}
bool rai::validate_message (rai::public_key const & public_key, rai::uint256_union const & message, rai::uint512_union const & signature)
{
auto result (0 != ed25519_sign_open (message.bytes.data (), sizeof (message.bytes), public_key.bytes.data (), signature.bytes.data ()));
return result;
auto result (0 != ed25519_sign_open (message.bytes.data (), sizeof (message.bytes), public_key.bytes.data (), signature.bytes.data ()));
return result;
}
void rai::open_or_create (std::fstream & stream_a, std::string const & path_a)

View file

@ -5,12 +5,9 @@
#include <condition_variable>
#include <type_traits>
#include <blake2/blake2.h>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/filesystem.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <cryptopp/osrng.h>
@ -18,12 +15,11 @@
#include <lmdb/libraries/liblmdb/lmdb.h>
#include <rai/config.hpp>
#include <rai/interface.h>
#include <rai/numbers.hpp>
namespace rai
{
// Random pool used by RaiBlocks.
// This must be thread_local as long as the AutoSeededRandomPool implementation requires it
extern thread_local CryptoPP::AutoSeededRandomPool random_pool;
// We operate on streams of uint8_t by convention
using stream = std::basic_streambuf <uint8_t>;
using bufferstream = boost::iostreams::stream_buffer <boost::iostreams::basic_array_source <uint8_t>>;
@ -123,16 +119,6 @@ bool fetch_object (T & object, boost::filesystem::path const & path_a, std::fstr
std::string to_string_hex (uint64_t);
bool from_string_hex (std::string const &, uint64_t &);
using uint128_t = boost::multiprecision::uint128_t;
using uint256_t = boost::multiprecision::uint256_t;
using uint512_t = boost::multiprecision::uint512_t;
// SI dividers
rai::uint128_t const Gxrb_ratio = rai::uint128_t ("1000000000000000000000000000000000"); // 10^33
rai::uint128_t const Mxrb_ratio = rai::uint128_t ("1000000000000000000000000000000"); // 10^30
rai::uint128_t const kxrb_ratio = rai::uint128_t ("1000000000000000000000000000"); // 10^27
rai::uint128_t const xrb_ratio = rai::uint128_t ("1000000000000000000000000"); // 10^24
rai::uint128_t const mxrb_ratio = rai::uint128_t ("1000000000000000000000"); // 10^21
rai::uint128_t const uxrb_ratio = rai::uint128_t ("1000000000000000000"); // 10^18
class mdb_env
{
public:
@ -141,116 +127,6 @@ public:
operator MDB_env * () const;
MDB_env * environment;
};
class transaction
{
public:
transaction (rai::mdb_env &, MDB_txn *, bool);
~transaction ();
operator MDB_txn * () const;
MDB_txn * handle;
rai::mdb_env & environment;
};
union uint128_union
{
public:
uint128_union () = default;
uint128_union (std::string const &);
uint128_union (uint64_t);
uint128_union (rai::uint128_union const &) = default;
uint128_union (rai::uint128_t const &);
bool operator == (rai::uint128_union const &) const;
bool operator != (rai::uint128_union const &) const;
bool operator < (rai::uint128_union const &) const;
bool operator > (rai::uint128_union const &) const;
void encode_hex (std::string &) const;
bool decode_hex (std::string const &);
void encode_dec (std::string &) const;
bool decode_dec (std::string const &);
rai::uint128_t number () const;
void clear ();
bool is_zero () const;
std::string to_string () const;
std::string to_string_dec () const;
std::array <uint8_t, 16> bytes;
std::array <char, 16> chars;
std::array <uint32_t, 4> dwords;
std::array <uint64_t, 2> qwords;
};
// Balances are 128 bit.
using amount = uint128_union;
class raw_key;
class mdb_val;
union uint256_union
{
uint256_union () = default;
uint256_union (std::string const &);
uint256_union (uint64_t);
uint256_union (rai::uint256_t const &);
void encrypt (rai::raw_key const &, rai::raw_key const &, uint128_union const &);
uint256_union & operator ^= (rai::uint256_union const &);
uint256_union operator ^ (rai::uint256_union const &) const;
bool operator == (rai::uint256_union const &) const;
bool operator != (rai::uint256_union const &) const;
bool operator < (rai::uint256_union const &) const;
void encode_hex (std::string &) const;
bool decode_hex (std::string const &);
void encode_dec (std::string &) const;
bool decode_dec (std::string const &);
void encode_account (std::string &) const;
std::string to_account () const;
std::string to_account_split () const;
bool decode_account_v1 (std::string const &);
bool decode_account (std::string const &);
std::array <uint8_t, 32> bytes;
std::array <char, 32> chars;
std::array <uint32_t, 8> dwords;
std::array <uint64_t, 4> qwords;
std::array <uint128_union, 2> owords;
void clear ();
bool is_zero () const;
std::string to_string () const;
rai::uint256_t number () const;
};
// All keys and hashes are 256 bit.
using block_hash = uint256_union;
using account = uint256_union;
using public_key = uint256_union;
using private_key = uint256_union;
using secret_key = uint256_union;
using checksum = uint256_union;
class raw_key
{
public:
raw_key () = default;
~raw_key ();
void decrypt (rai::uint256_union const &, rai::raw_key const &, uint128_union const &);
raw_key (rai::raw_key const &) = delete;
raw_key (rai::raw_key const &&) = delete;
rai::raw_key & operator = (rai::raw_key const &) = delete;
bool operator == (rai::raw_key const &) const;
bool operator != (rai::raw_key const &) const;
rai::uint256_union data;
};
union uint512_union
{
uint512_union () = default;
uint512_union (rai::uint512_t const &);
bool operator == (rai::uint512_union const &) const;
bool operator != (rai::uint512_union const &) const;
rai::uint512_union & operator ^= (rai::uint512_union const &);
void encode_hex (std::string &) const;
bool decode_hex (std::string const &);
std::array <uint8_t, 64> bytes;
std::array <uint32_t, 16> dwords;
std::array <uint64_t, 8> qwords;
std::array <uint256_union, 2> uint256s;
void clear ();
rai::uint512_t number () const;
};
// Only signatures are 512 bit.
using signature = uint512_union;
rai::uint512_union sign_message (rai::raw_key const &, rai::public_key const &, rai::uint256_union const &);
bool validate_message (rai::public_key const &, rai::uint256_union const &, rai::uint512_union const &);
class mdb_val
{
public:
@ -266,23 +142,13 @@ public:
operator MDB_val const & () const;
MDB_val value;
};
}
namespace std
class transaction
{
template <>
struct hash <rai::uint256_union>
{
size_t operator () (rai::uint256_union const & data_a) const
{
return *reinterpret_cast <size_t const *> (data_a.bytes.data ());
}
};
template <>
struct hash <rai::uint256_t>
{
size_t operator () (rai::uint256_t const & number_a) const
{
return number_a.convert_to <size_t> ();
}
public:
transaction (rai::mdb_env &, MDB_txn *, bool);
~transaction ();
operator MDB_txn * () const;
MDB_txn * handle;
rai::mdb_env & environment;
};
}