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:
parent
957386c101
commit
b41d82553c
12 changed files with 1619 additions and 1456 deletions
|
@ -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
1114
rai/blocks.cpp
Normal file
File diff suppressed because it is too large
Load diff
231
rai/blocks.hpp
Normal file
231
rai/blocks.hpp
Normal 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
100
rai/core_test/interface.cpp
Normal 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);
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
141
rai/numbers.cpp
141
rai/numbers.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
1056
rai/secure.cpp
1056
rai/secure.cpp
File diff suppressed because it is too large
Load diff
196
rai/secure.hpp
196
rai/secure.hpp
|
@ -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
|
||||
{
|
||||
|
|
178
rai/utility.cpp
178
rai/utility.cpp
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <rai/blocks.hpp>
|
||||
#include <rai/utility.hpp>
|
||||
|
||||
namespace rai
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue