Adding sign_transaction implementation to interface.

Moving block related code in to shared lib so serialization/deserialization can be accessed.
Adding interface tests.
This commit is contained in:
clemahieu 2017-12-21 03:02:39 -06:00
commit b41d82553c
12 changed files with 1619 additions and 1456 deletions

View file

@ -204,6 +204,8 @@ add_library (secure
rai/versioning.cpp)
add_library (rai_lib SHARED
rai/blocks.cpp
rai/blocks.hpp
rai/interface.cpp
rai/interface.h
rai/numbers.cpp
@ -236,18 +238,19 @@ if (RAIBLOCKS_TEST)
add_executable (core_test
rai/core_test/block.cpp
rai/core_test/block_store.cpp
rai/core_test/node.cpp
rai/core_test/interface.cpp
rai/core_test/conflicts.cpp
rai/core_test/daemon.cpp
rai/core_test/entry.cpp
rai/core_test/gap_cache.cpp
rai/core_test/ledger.cpp
rai/core_test/network.cpp
rai/core_test/node.cpp
rai/core_test/message.cpp
rai/core_test/message_parser.cpp
rai/core_test/processor_service.cpp
rai/core_test/peer_container.cpp
rai/core_test/rpc.cpp
rai/core_test/network.cpp
rai/core_test/uint256_union.cpp
rai/core_test/versioning.cpp
rai/core_test/wallet.cpp

1114
rai/blocks.cpp Normal file

File diff suppressed because it is too large Load diff

231
rai/blocks.hpp Normal file
View file

@ -0,0 +1,231 @@
#pragma once
#include <rai/numbers.hpp>
#include <assert.h>
#include <blake2/blake2.h>
#include <boost/property_tree/json_parser.hpp>
#include <streambuf>
namespace rai
{
std::string to_string_hex (uint64_t);
bool from_string_hex (std::string const &, uint64_t &);
// We operate on streams of uint8_t by convention
using stream = std::basic_streambuf <uint8_t>;
// Read a raw byte stream the size of `T' and fill value.
template <typename T>
bool read (rai::stream & stream_a, T & value)
{
static_assert (std::is_pod <T>::value, "Can't stream read non-standard layout types");
auto amount_read (stream_a.sgetn (reinterpret_cast <uint8_t *> (&value), sizeof (value)));
return amount_read != sizeof (value);
}
template <typename T>
void write (rai::stream & stream_a, T const & value)
{
static_assert (std::is_pod <T>::value, "Can't stream write non-standard layout types");
auto amount_written (stream_a.sputn (reinterpret_cast <uint8_t const *> (&value), sizeof (value)));
assert (amount_written == sizeof (value));
}
class block_visitor;
enum class block_type : uint8_t
{
invalid,
not_a_block,
send,
receive,
open,
change
};
class block
{
public:
// Return a digest of the hashables in this block.
rai::block_hash hash () const;
std::string to_json ();
virtual void hash (blake2b_state &) const = 0;
virtual uint64_t block_work () const = 0;
virtual void block_work_set (uint64_t) = 0;
// Previous block in account's chain, zero for open block
virtual rai::block_hash previous () const = 0;
// Source block for open/receive blocks, zero otherwise.
virtual rai::block_hash source () const = 0;
// Previous block or account number for open blocks
virtual rai::block_hash root () const = 0;
virtual rai::account representative () const = 0;
virtual void serialize (rai::stream &) const = 0;
virtual void serialize_json (std::string &) const = 0;
virtual void visit (rai::block_visitor &) const = 0;
virtual bool operator == (rai::block const &) const = 0;
virtual rai::block_type type () const = 0;
virtual void signature_set (rai::uint512_union const &) = 0;
};
class send_hashables
{
public:
send_hashables (rai::account const &, rai::block_hash const &, rai::amount const &);
send_hashables (bool &, rai::stream &);
send_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash previous;
rai::account destination;
rai::amount balance;
};
class send_block : public rai::block
{
public:
send_block (rai::block_hash const &, rai::account const &, rai::amount const &, rai::raw_key const &, rai::public_key const &, uint64_t);
send_block (bool &, rai::stream &);
send_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
void signature_set (rai::uint512_union const &) override;
bool operator == (rai::block const &) const override;
bool operator == (rai::send_block const &) const;
static size_t constexpr size = sizeof (rai::account) + sizeof (rai::block_hash) + sizeof (rai::amount) + sizeof (rai::signature) + sizeof (uint64_t);
send_hashables hashables;
rai::signature signature;
uint64_t work;
};
class receive_hashables
{
public:
receive_hashables (rai::block_hash const &, rai::block_hash const &);
receive_hashables (bool &, rai::stream &);
receive_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash previous;
rai::block_hash source;
};
class receive_block : public rai::block
{
public:
receive_block (rai::block_hash const &, rai::block_hash const &, rai::raw_key const &, rai::public_key const &, uint64_t);
receive_block (bool &, rai::stream &);
receive_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
void signature_set (rai::uint512_union const &) override;
bool operator == (rai::block const &) const override;
bool operator == (rai::receive_block const &) const;
static size_t constexpr size = sizeof (rai::block_hash) + sizeof (rai::block_hash) + sizeof (rai::signature) + sizeof (uint64_t);
receive_hashables hashables;
rai::signature signature;
uint64_t work;
};
class open_hashables
{
public:
open_hashables (rai::block_hash const &, rai::account const &, rai::account const &);
open_hashables (bool &, rai::stream &);
open_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash source;
rai::account representative;
rai::account account;
};
class open_block : public rai::block
{
public:
open_block (rai::block_hash const &, rai::account const &, rai::account const &, rai::raw_key const &, rai::public_key const &, uint64_t);
open_block (rai::block_hash const &, rai::account const &, rai::account const &, std::nullptr_t);
open_block (bool &, rai::stream &);
open_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
void signature_set (rai::uint512_union const &) override;
bool operator == (rai::block const &) const override;
bool operator == (rai::open_block const &) const;
static size_t constexpr size = sizeof (rai::block_hash) + sizeof (rai::account) + sizeof (rai::account) + sizeof (rai::signature) + sizeof (uint64_t);
rai::open_hashables hashables;
rai::signature signature;
uint64_t work;
};
class change_hashables
{
public:
change_hashables (rai::block_hash const &, rai::account const &);
change_hashables (bool &, rai::stream &);
change_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash previous;
rai::account representative;
};
class change_block : public rai::block
{
public:
change_block (rai::block_hash const &, rai::account const &, rai::raw_key const &, rai::public_key const &, uint64_t);
change_block (bool &, rai::stream &);
change_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
void signature_set (rai::uint512_union const &) override;
bool operator == (rai::block const &) const override;
bool operator == (rai::change_block const &) const;
static size_t constexpr size = sizeof (rai::block_hash) + sizeof (rai::account) + sizeof (rai::signature) + sizeof (uint64_t);
rai::change_hashables hashables;
rai::signature signature;
uint64_t work;
};
class block_visitor
{
public:
virtual void send_block (rai::send_block const &) = 0;
virtual void receive_block (rai::receive_block const &) = 0;
virtual void open_block (rai::open_block const &) = 0;
virtual void change_block (rai::change_block const &) = 0;
};
std::unique_ptr <rai::block> deserialize_block (rai::stream &);
std::unique_ptr <rai::block> deserialize_block (rai::stream &, rai::block_type);
std::unique_ptr <rai::block> deserialize_block_json (boost::property_tree::ptree const &);
void serialize_block (rai::stream &, rai::block const &);
}

100
rai/core_test/interface.cpp Normal file
View file

@ -0,0 +1,100 @@
#include <gtest/gtest.h>
#include <memory>
#include <rai/blocks.hpp>
#include <rai/numbers.hpp>
#include <rai/interface.h>
TEST (interface, xrb_uint256_to_string)
{
rai::uint256_union zero (0);
char text [65] = { 0 };
xrb_uint256_to_string (zero.bytes.data (), text);
ASSERT_STREQ ("0000000000000000000000000000000000000000000000000000000000000000", text);
}
TEST (interface, xrb_uint256_to_address)
{
rai::uint256_union zero (0);
char text [65] = { 0 };
xrb_uint256_to_address (zero.bytes.data (), text);
ASSERT_STREQ ("xrb_1111111111111111111111111111111111111111111111111111hifc8npp", text);
}
TEST (interface, xrb_uint512_to_string)
{
rai::uint512_union zero (0);
char text [129] = { 0 };
xrb_uint512_to_string (zero.bytes.data (), text);
ASSERT_STREQ ("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", text);
}
TEST (interface, xrb_uint256_from_string)
{
rai::uint256_union zero (0);
ASSERT_EQ (0, xrb_uint256_from_string ("0000000000000000000000000000000000000000000000000000000000000000", zero.bytes.data ()));
ASSERT_EQ (1, xrb_uint256_from_string ("00000000000000000000000000000000000000000000000000000000000000000", zero.bytes.data ()));
ASSERT_EQ (1, xrb_uint256_from_string ("000000000000000000000000000%000000000000000000000000000000000000", zero.bytes.data ()));
}
TEST (interface, xrb_uint512_from_string)
{
rai::uint512_union zero (0);
ASSERT_EQ (0, xrb_uint512_from_string ("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", zero.bytes.data ()));
ASSERT_EQ (1, xrb_uint512_from_string ("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", zero.bytes.data ()));
ASSERT_EQ (1, xrb_uint512_from_string ("0000000000000000000000000000000000000000000000000000000000%000000000000000000000000000000000000000000000000000000000000000000000", zero.bytes.data ()));
}
TEST (interface, xrb_valid_address)
{
ASSERT_EQ (0, xrb_valid_address ("xrb_1111111111111111111111111111111111111111111111111111hifc8npp"));
ASSERT_EQ (1, xrb_valid_address ("xrb_1111111111111111111111111111111111111111111111111111hifc8nppp"));
ASSERT_EQ (1, xrb_valid_address ("xrb_1111111211111111111111111111111111111111111111111111hifc8npp"));
}
TEST (interface, xrb_seed_create)
{
rai::uint256_union seed;
xrb_generate_random (seed.bytes.data ());
ASSERT_FALSE (seed.is_zero ());
}
TEST (interface, xrb_seed_key)
{
rai::uint256_union seed (0);
rai::uint256_union prv;
xrb_seed_key (seed.bytes.data (), 0, prv.bytes.data ());
ASSERT_FALSE (prv.is_zero ());
}
TEST (interface, xrb_key_account)
{
rai::uint256_union prv (0);
rai::uint256_union pub;
xrb_key_account (prv.bytes.data (), pub.bytes.data ());
ASSERT_FALSE (pub.is_zero ());
}
TEST (interface, sign_transaction)
{
rai::raw_key key;
xrb_generate_random (key.data.bytes.data ());
rai::uint256_union pub;
xrb_key_account (key.data.bytes.data (), pub.bytes.data ());
rai::send_block send (0, 0, 0, key, pub, 0);
ASSERT_FALSE (rai::validate_message (pub, send.hash (), send.signature));
send.signature.bytes [0] ^= 1;
ASSERT_TRUE (rai::validate_message (pub, send.hash (), send.signature));
auto transaction (xrb_sign_transaction (send.to_json ().c_str (), key.data.bytes.data ()));
boost::property_tree::ptree block_l;
std::string transaction_l (transaction);
std::stringstream block_stream (transaction_l);
boost::property_tree::read_json (block_stream, block_l);
auto block (rai::deserialize_block_json (block_l));
ASSERT_NE (nullptr, block);
auto send1 (dynamic_cast <rai::send_block *> (block.get ()));
ASSERT_NE (nullptr, send1);
ASSERT_FALSE (rai::validate_message (pub, send.hash (), send1->signature));
free (transaction);
}

View file

@ -6,6 +6,9 @@
#include <blake2/blake2.h>
#include <boost/property_tree/json_parser.hpp>
#include <rai/blocks.hpp>
#include <rai/numbers.hpp>
#include <cstring>
@ -53,7 +56,7 @@ int xrb_valid_address (const char * account_a)
return result;
}
void xrb_seed_create (xrb_uint256 seed)
void xrb_generate_random (xrb_uint256 seed)
{
auto & number (*reinterpret_cast <rai::uint256_union *> (seed));
rai::random_pool.GenerateBlock (number.bytes.data (), number.bytes.size ());
@ -71,9 +74,26 @@ void xrb_key_account (const xrb_uint256 key, xrb_uint256 pub)
ed25519_publickey (key, pub);
}
char * sign_transaction (const char * transaction, const xrb_uint256 private_key, xrb_uint512 signature)
char * xrb_sign_transaction (const char * transaction, const xrb_uint256 private_key)
{
return nullptr;
char * result (nullptr);
boost::property_tree::ptree block_l;
std::string transaction_l (transaction);
std::stringstream block_stream (transaction_l);
boost::property_tree::read_json (block_stream, block_l);
auto block (rai::deserialize_block_json (block_l));
if (block != nullptr)
{
rai::uint256_union pub;
ed25519_publickey (private_key, pub.bytes.data ());
rai::raw_key prv;
prv.data = *reinterpret_cast <rai::uint256_union *> (private_key);
block->signature_set (rai::sign_message (prv, pub, block->hash ()));
auto json (block->to_json ());
result = reinterpret_cast <char *> (malloc (json.size () + 1));
strncpy (result, json.c_str (), json.size () + 1);
}
return result;
}
#include <ed25519-donna/ed25519-hash-custom.h>

View file

@ -27,15 +27,15 @@ int xrb_uint512_from_string (const char * source, xrb_uint512 destination);
// Return 0 on correct, nonzero on invalid
int xrb_valid_address (const char * account);
// Create a new random seed in 'seed'
void xrb_seed_create (xrb_uint256 seed);
// Create a new random number in to 'destination'
void xrb_generate_random (xrb_uint256 destination);
// Retrieve the detereministic private key for 'seed' at 'index'
void xrb_seed_key (const xrb_uint256 seed, int index, xrb_uint256);
// Derive the public key 'pub' from 'key'
void xrb_key_account (xrb_uint256 key, xrb_uint256 pub);
// Sign 'transaction' using 'private_key' and write to 'signature'
char * sign_transaction (const char * transaction, const xrb_uint256 private_key, xrb_uint512 signature);
char * xrb_sign_transaction (const char * transaction, const xrb_uint256 private_key);
#if __cplusplus
} // extern "C"

View file

@ -462,3 +462,144 @@ bool rai::validate_message (rai::public_key const & public_key, rai::uint256_uni
return result;
}
rai::uint128_union::uint128_union (std::string const & string_a)
{
decode_hex (string_a);
}
rai::uint128_union::uint128_union (uint64_t value_a)
{
*this = rai::uint128_t (value_a);
}
rai::uint128_union::uint128_union (rai::uint128_t const & value_a)
{
rai::uint128_t number_l (value_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::uint128_union::operator == (rai::uint128_union const & other_a) const
{
return qwords [0] == other_a.qwords [0] && qwords [1] == other_a.qwords [1];
}
bool rai::uint128_union::operator != (rai::uint128_union const & other_a) const
{
return !(*this == other_a);
}
bool rai::uint128_union::operator < (rai::uint128_union const & other_a) const
{
return number () < other_a.number ();
}
bool rai::uint128_union::operator > (rai::uint128_union const & other_a) const
{
return number () > other_a.number ();
}
rai::uint128_t rai::uint128_union::number () const
{
rai::uint128_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::uint128_union::encode_hex (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (32) << std::setfill ('0');
stream << number ();
text = stream.str ();
}
bool rai::uint128_union::decode_hex (std::string const & text)
{
auto result (text.size () > 32);
if (!result)
{
std::stringstream stream (text);
stream << std::hex << std::noshowbase;
rai::uint128_t number_l;
try
{
stream >> number_l;
*this = number_l;
if (!stream.eof ())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
void rai::uint128_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::uint128_union::decode_dec (std::string const & text)
{
auto result (text.size () > 39);
if (!result)
{
std::stringstream stream (text);
stream << std::dec << std::noshowbase;
rai::uint128_t number_l;
try
{
stream >> number_l;
*this = number_l;
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
void rai::uint128_union::clear ()
{
qwords.fill (0);
}
bool rai::uint128_union::is_zero () const
{
return qwords [0] == 0 && qwords [1] == 0;
}
std::string rai::uint128_union::to_string () const
{
std::string result;
encode_hex (result);
return result;
}
std::string rai::uint128_union::to_string_dec () const
{
std::string result;
encode_dec (result);
return result;
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
#pragma once
#include <rai/blocks.hpp>
#include <rai/utility.hpp>
#include <boost/property_tree/ptree.hpp>
@ -30,38 +31,6 @@ public:
rai::public_key pub;
rai::raw_key prv;
};
class block_visitor;
enum class block_type : uint8_t
{
invalid,
not_a_block,
send,
receive,
open,
change
};
class block
{
public:
// Return a digest of the hashables in this block.
rai::block_hash hash () const;
std::string to_json ();
virtual void hash (blake2b_state &) const = 0;
virtual uint64_t block_work () const = 0;
virtual void block_work_set (uint64_t) = 0;
// Previous block in account's chain, zero for open block
virtual rai::block_hash previous () const = 0;
// Source block for open/receive blocks, zero otherwise.
virtual rai::block_hash source () const = 0;
// Previous block or account number for open blocks
virtual rai::block_hash root () const = 0;
virtual rai::account representative () const = 0;
virtual void serialize (rai::stream &) const = 0;
virtual void serialize_json (std::string &) const = 0;
virtual void visit (rai::block_visitor &) const = 0;
virtual bool operator == (rai::block const &) const = 0;
virtual rai::block_type type () const = 0;
};
class shared_ptr_block_hash
{
public:
@ -69,169 +38,6 @@ public:
bool operator () (std::shared_ptr <rai::block> const &, std::shared_ptr <rai::block> const &) const;
};
std::unique_ptr <rai::block> deserialize_block (MDB_val const &);
std::unique_ptr <rai::block> deserialize_block (rai::stream &);
std::unique_ptr <rai::block> deserialize_block (rai::stream &, rai::block_type);
std::unique_ptr <rai::block> deserialize_block_json (boost::property_tree::ptree const &);
void serialize_block (rai::stream &, rai::block const &);
class send_hashables
{
public:
send_hashables (rai::account const &, rai::block_hash const &, rai::amount const &);
send_hashables (bool &, rai::stream &);
send_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash previous;
rai::account destination;
rai::amount balance;
};
class send_block : public rai::block
{
public:
send_block (rai::block_hash const &, rai::account const &, rai::amount const &, rai::raw_key const &, rai::public_key const &, uint64_t);
send_block (bool &, rai::stream &);
send_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
bool operator == (rai::block const &) const override;
bool operator == (rai::send_block const &) const;
static size_t constexpr size = sizeof (rai::account) + sizeof (rai::block_hash) + sizeof (rai::amount) + sizeof (rai::signature) + sizeof (uint64_t);
send_hashables hashables;
rai::signature signature;
uint64_t work;
};
class receive_hashables
{
public:
receive_hashables (rai::block_hash const &, rai::block_hash const &);
receive_hashables (bool &, rai::stream &);
receive_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash previous;
rai::block_hash source;
};
class receive_block : public rai::block
{
public:
receive_block (rai::block_hash const &, rai::block_hash const &, rai::raw_key const &, rai::public_key const &, uint64_t);
receive_block (bool &, rai::stream &);
receive_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
bool operator == (rai::block const &) const override;
bool operator == (rai::receive_block const &) const;
static size_t constexpr size = sizeof (rai::block_hash) + sizeof (rai::block_hash) + sizeof (rai::signature) + sizeof (uint64_t);
receive_hashables hashables;
rai::signature signature;
uint64_t work;
};
class open_hashables
{
public:
open_hashables (rai::block_hash const &, rai::account const &, rai::account const &);
open_hashables (bool &, rai::stream &);
open_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash source;
rai::account representative;
rai::account account;
};
class open_block : public rai::block
{
public:
open_block (rai::block_hash const &, rai::account const &, rai::account const &, rai::raw_key const &, rai::public_key const &, uint64_t);
open_block (rai::block_hash const &, rai::account const &, rai::account const &, std::nullptr_t);
open_block (bool &, rai::stream &);
open_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
bool operator == (rai::block const &) const override;
bool operator == (rai::open_block const &) const;
static size_t constexpr size = sizeof (rai::block_hash) + sizeof (rai::account) + sizeof (rai::account) + sizeof (rai::signature) + sizeof (uint64_t);
rai::open_hashables hashables;
rai::signature signature;
uint64_t work;
};
class change_hashables
{
public:
change_hashables (rai::block_hash const &, rai::account const &);
change_hashables (bool &, rai::stream &);
change_hashables (bool &, boost::property_tree::ptree const &);
void hash (blake2b_state &) const;
rai::block_hash previous;
rai::account representative;
};
class change_block : public rai::block
{
public:
change_block (rai::block_hash const &, rai::account const &, rai::raw_key const &, rai::public_key const &, uint64_t);
change_block (bool &, rai::stream &);
change_block (bool &, boost::property_tree::ptree const &);
using rai::block::hash;
void hash (blake2b_state &) const override;
uint64_t block_work () const override;
void block_work_set (uint64_t) override;
rai::block_hash previous () const override;
rai::block_hash source () const override;
rai::block_hash root () const override;
rai::account representative () const override;
void serialize (rai::stream &) const override;
void serialize_json (std::string &) const override;
bool deserialize (rai::stream &);
bool deserialize_json (boost::property_tree::ptree const &);
void visit (rai::block_visitor &) const override;
rai::block_type type () const override;
bool operator == (rai::block const &) const override;
bool operator == (rai::change_block const &) const;
static size_t constexpr size = sizeof (rai::block_hash) + sizeof (rai::account) + sizeof (rai::signature) + sizeof (uint64_t);
rai::change_hashables hashables;
rai::signature signature;
uint64_t work;
};
class block_visitor
{
public:
virtual void send_block (rai::send_block const &) = 0;
virtual void receive_block (rai::receive_block const &) = 0;
virtual void open_block (rai::open_block const &) = 0;
virtual void change_block (rai::change_block const &) = 0;
};
// Latest information about an account
class account_info
{

View file

@ -12,43 +12,6 @@ boost::filesystem::path rai::unique_path ()
return result;
}
std::string rai::to_string_hex (uint64_t value_a)
{
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (16) << std::setfill ('0');
stream << value_a;
return stream.str ();
}
bool rai::from_string_hex (std::string const & value_a, uint64_t & target_a)
{
auto result (value_a.empty ());
if (!result)
{
result = value_a.size () > 16;
if (!result)
{
std::stringstream stream (value_a);
stream << std::hex << std::noshowbase;
uint64_t number_l;
try
{
stream >> number_l;
target_a = number_l;
if (!stream.eof())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
}
return result;
}
rai::mdb_env::mdb_env (bool & error_a, boost::filesystem::path const & path_a)
{
boost::system::error_code error;
@ -164,147 +127,6 @@ rai::transaction::operator MDB_txn * () const
return handle;
}
rai::uint128_union::uint128_union (std::string const & string_a)
{
decode_hex (string_a);
}
rai::uint128_union::uint128_union (uint64_t value_a)
{
*this = rai::uint128_t (value_a);
}
rai::uint128_union::uint128_union (rai::uint128_t const & value_a)
{
rai::uint128_t number_l (value_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::uint128_union::operator == (rai::uint128_union const & other_a) const
{
return qwords [0] == other_a.qwords [0] && qwords [1] == other_a.qwords [1];
}
bool rai::uint128_union::operator != (rai::uint128_union const & other_a) const
{
return !(*this == other_a);
}
bool rai::uint128_union::operator < (rai::uint128_union const & other_a) const
{
return number () < other_a.number ();
}
bool rai::uint128_union::operator > (rai::uint128_union const & other_a) const
{
return number () > other_a.number ();
}
rai::uint128_t rai::uint128_union::number () const
{
rai::uint128_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::uint128_union::encode_hex (std::string & text) const
{
assert (text.empty ());
std::stringstream stream;
stream << std::hex << std::noshowbase << std::setw (32) << std::setfill ('0');
stream << number ();
text = stream.str ();
}
bool rai::uint128_union::decode_hex (std::string const & text)
{
auto result (text.size () > 32);
if (!result)
{
std::stringstream stream (text);
stream << std::hex << std::noshowbase;
rai::uint128_t number_l;
try
{
stream >> number_l;
*this = number_l;
if (!stream.eof ())
{
result = true;
}
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
void rai::uint128_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::uint128_union::decode_dec (std::string const & text)
{
auto result (text.size () > 39);
if (!result)
{
std::stringstream stream (text);
stream << std::dec << std::noshowbase;
rai::uint128_t number_l;
try
{
stream >> number_l;
*this = number_l;
}
catch (std::runtime_error &)
{
result = true;
}
}
return result;
}
void rai::uint128_union::clear ()
{
qwords.fill (0);
}
bool rai::uint128_union::is_zero () const
{
return qwords [0] == 0 && qwords [1] == 0;
}
std::string rai::uint128_union::to_string () const
{
std::string result;
encode_hex (result);
return result;
}
std::string rai::uint128_union::to_string_dec () const
{
std::string result;
encode_dec (result);
return result;
}
void rai::open_or_create (std::fstream & stream_a, std::string const & path_a)
{
stream_a.open (path_a, std::ios_base::in);

View file

@ -20,8 +20,6 @@
namespace rai
{
// 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>>;
using vectorstream = boost::iostreams::stream_buffer <boost::iostreams::back_insert_device <std::vector <uint8_t>>>;
// OS-specific way of finding a path to a home directory.
@ -30,21 +28,6 @@ boost::filesystem::path working_path ();
boost::filesystem::path unique_path ();
// Lower priority of calling work generating thread
void work_thread_reprioritize ();
// Read a raw byte stream the size of `T' and fill value.
template <typename T>
bool read (rai::stream & stream_a, T & value)
{
static_assert (std::is_pod <T>::value, "Can't stream read non-standard layout types");
auto amount_read (stream_a.sgetn (reinterpret_cast <uint8_t *> (&value), sizeof (value)));
return amount_read != sizeof (value);
}
template <typename T>
void write (rai::stream & stream_a, T const & value)
{
static_assert (std::is_pod <T>::value, "Can't stream write non-standard layout types");
auto amount_written (stream_a.sputn (reinterpret_cast <uint8_t const *> (&value), sizeof (value)));
assert (amount_written == sizeof (value));
}
// C++ stream are absolutely horrible so I need this helper function to do the most basic operation of creating a file if it doesn't exist or truntacing it.
void open_or_create (std::fstream &, std::string const &);
// Reads a json object from the stream and if was changed, write the object back to the stream
@ -116,8 +99,6 @@ bool fetch_object (T & object, boost::filesystem::path const & path_a, std::fstr
}
return error;
}
std::string to_string_hex (uint64_t);
bool from_string_hex (std::string const &, uint64_t &);
class mdb_env
{

View file

@ -1,5 +1,6 @@
#pragma once
#include <rai/blocks.hpp>
#include <rai/utility.hpp>
namespace rai