Merge pull request #4767 from pwojcikdev/spaceship-comparisons
Use spaceship comparisons
This commit is contained in:
commit
04ebc91fd2
19 changed files with 679 additions and 571 deletions
|
|
@ -35,10 +35,12 @@ add_executable(
|
||||||
network_filter.cpp
|
network_filter.cpp
|
||||||
network_functions.cpp
|
network_functions.cpp
|
||||||
node.cpp
|
node.cpp
|
||||||
|
numbers.cpp
|
||||||
object_stream.cpp
|
object_stream.cpp
|
||||||
optimistic_scheduler.cpp
|
optimistic_scheduler.cpp
|
||||||
processing_queue.cpp
|
processing_queue.cpp
|
||||||
processor_service.cpp
|
processor_service.cpp
|
||||||
|
random_pool.cpp
|
||||||
rep_crawler.cpp
|
rep_crawler.cpp
|
||||||
receivable.cpp
|
receivable.cpp
|
||||||
peer_history.cpp
|
peer_history.cpp
|
||||||
|
|
@ -54,7 +56,6 @@ add_executable(
|
||||||
throttle.cpp
|
throttle.cpp
|
||||||
toml.cpp
|
toml.cpp
|
||||||
timer.cpp
|
timer.cpp
|
||||||
uint256_union.cpp
|
|
||||||
unchecked_map.cpp
|
unchecked_map.cpp
|
||||||
utility.cpp
|
utility.cpp
|
||||||
vote_cache.cpp
|
vote_cache.cpp
|
||||||
|
|
|
||||||
|
|
@ -2406,7 +2406,7 @@ TEST (ledger, state_account)
|
||||||
.work (*pool.generate (nano::dev::genesis->hash ()))
|
.work (*pool.generate (nano::dev::genesis->hash ()))
|
||||||
.build ();
|
.build ();
|
||||||
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
|
ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1));
|
||||||
ASSERT_EQ (nano::dev::genesis_key.pub, ledger.any.block_account (transaction, send1->hash ()));
|
ASSERT_EQ (nano::dev::genesis_key.pub, ledger.any.block_account (transaction, send1->hash ()).value ());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (ledger, state_send_receive)
|
TEST (ledger, state_send_receive)
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,192 @@
|
||||||
#include <nano/crypto_lib/random_pool.hpp>
|
#include <nano/lib/numbers.hpp>
|
||||||
#include <nano/secure/common.hpp>
|
#include <nano/secure/common.hpp>
|
||||||
#include <nano/test_common/testutil.hpp>
|
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
TEST (numbers, identity)
|
||||||
|
{
|
||||||
|
ASSERT_EQ (1, nano::uint128_union (1).number ().convert_to<uint8_t> ());
|
||||||
|
ASSERT_EQ (1, nano::uint256_union (1).number ().convert_to<uint8_t> ());
|
||||||
|
ASSERT_EQ (1, nano::uint512_union (1).number ().convert_to<uint8_t> ());
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template <typename Union, typename Bound>
|
template <typename Type>
|
||||||
void assert_union_types ();
|
void check_operator_less_than (Type lhs, Type rhs)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE (lhs < rhs);
|
||||||
|
ASSERT_FALSE (rhs < lhs);
|
||||||
|
ASSERT_FALSE (lhs < lhs);
|
||||||
|
ASSERT_FALSE (rhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Union, typename Bound>
|
template <typename Type>
|
||||||
void test_union_operator_less_than ();
|
void test_operator_less_than ()
|
||||||
|
{
|
||||||
|
using underlying_t = typename Type::underlying_type;
|
||||||
|
|
||||||
template <typename Num>
|
// Small
|
||||||
void check_operator_less_than (Num lhs, Num rhs);
|
check_operator_less_than (Type{ 123 }, Type{ 124 });
|
||||||
|
check_operator_less_than (Type{ 124 }, Type{ 125 });
|
||||||
|
|
||||||
template <typename Union, typename Bound>
|
// Medium
|
||||||
void test_union_operator_greater_than ();
|
check_operator_less_than (Type{ std::numeric_limits<uint16_t>::max () - 1 }, Type{ std::numeric_limits<uint16_t>::max () + 1 });
|
||||||
|
check_operator_less_than (Type{ std::numeric_limits<uint32_t>::max () - 12345678 }, Type{ std::numeric_limits<uint32_t>::max () - 123456 });
|
||||||
|
|
||||||
template <typename Num>
|
// Large
|
||||||
void check_operator_greater_than (Num lhs, Num rhs);
|
check_operator_less_than (Type{ std::numeric_limits<uint64_t>::max () - 555555555555 }, Type{ std::numeric_limits<uint64_t>::max () - 1 });
|
||||||
|
|
||||||
|
// Boundary values
|
||||||
|
check_operator_less_than (Type{ std::numeric_limits<underlying_t>::min () }, Type{ std::numeric_limits<underlying_t>::max () });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
void check_operator_greater_than (Type lhs, Type rhs)
|
||||||
|
{
|
||||||
|
ASSERT_TRUE (lhs > rhs);
|
||||||
|
ASSERT_FALSE (rhs > lhs);
|
||||||
|
ASSERT_FALSE (lhs > lhs);
|
||||||
|
ASSERT_FALSE (rhs > rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
void test_operator_greater_than ()
|
||||||
|
{
|
||||||
|
using underlying_t = typename Type::underlying_type;
|
||||||
|
|
||||||
|
// Small
|
||||||
|
check_operator_greater_than (Type{ 124 }, Type{ 123 });
|
||||||
|
check_operator_greater_than (Type{ 125 }, Type{ 124 });
|
||||||
|
|
||||||
|
// Medium
|
||||||
|
check_operator_greater_than (Type{ std::numeric_limits<uint16_t>::max () + 1 }, Type{ std::numeric_limits<uint16_t>::max () - 1 });
|
||||||
|
check_operator_greater_than (Type{ std::numeric_limits<uint32_t>::max () - 123456 }, Type{ std::numeric_limits<uint32_t>::max () - 12345678 });
|
||||||
|
|
||||||
|
// Large
|
||||||
|
check_operator_greater_than (Type{ std::numeric_limits<uint64_t>::max () - 1 }, Type{ std::numeric_limits<uint64_t>::max () - 555555555555 });
|
||||||
|
|
||||||
|
// Boundary values
|
||||||
|
check_operator_greater_than (Type{ std::numeric_limits<underlying_t>::max () }, Type{ std::numeric_limits<underlying_t>::min () });
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
void test_comparison ()
|
||||||
|
{
|
||||||
|
test_operator_less_than<Type> ();
|
||||||
|
test_operator_greater_than<Type> ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST (numbers, comparison)
|
||||||
|
{
|
||||||
|
test_comparison<nano::uint128_union> ();
|
||||||
|
test_comparison<nano::uint256_union> ();
|
||||||
|
test_comparison<nano::uint512_union> ();
|
||||||
|
test_comparison<nano::block_hash> ();
|
||||||
|
test_comparison<nano::public_key> ();
|
||||||
|
test_comparison<nano::hash_or_account> ();
|
||||||
|
test_comparison<nano::link> ();
|
||||||
|
test_comparison<nano::root> ();
|
||||||
|
test_comparison<nano::raw_key> ();
|
||||||
|
test_comparison<nano::wallet_id> ();
|
||||||
|
test_comparison<nano::qualified_root> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template <typename Type, template <typename> class Hash>
|
||||||
|
void test_hashing ()
|
||||||
|
{
|
||||||
|
Hash<Type> hash;
|
||||||
|
using underlying_t = typename Type::underlying_type;
|
||||||
|
|
||||||
|
// Basic equality tests
|
||||||
|
ASSERT_EQ (hash (Type{}), hash (Type{}));
|
||||||
|
ASSERT_EQ (hash (Type{ 123 }), hash (Type{ 123 }));
|
||||||
|
|
||||||
|
// Basic inequality tests
|
||||||
|
ASSERT_NE (hash (Type{ 123 }), hash (Type{ 124 }));
|
||||||
|
ASSERT_NE (hash (Type{ 0 }), hash (Type{ 1 }));
|
||||||
|
|
||||||
|
// Boundary value tests
|
||||||
|
constexpr auto min_val = std::numeric_limits<underlying_t>::min ();
|
||||||
|
constexpr auto max_val = std::numeric_limits<underlying_t>::max ();
|
||||||
|
|
||||||
|
// Min/Max tests
|
||||||
|
ASSERT_EQ (hash (Type{ min_val }), hash (Type{ min_val }));
|
||||||
|
ASSERT_EQ (hash (Type{ max_val }), hash (Type{ max_val }));
|
||||||
|
ASSERT_NE (hash (Type{ min_val }), hash (Type{ max_val }));
|
||||||
|
|
||||||
|
// Near boundary tests
|
||||||
|
ASSERT_NE (hash (Type{ min_val }), hash (Type{ min_val + 1 }));
|
||||||
|
ASSERT_NE (hash (Type{ max_val }), hash (Type{ max_val - 1 }));
|
||||||
|
ASSERT_NE (hash (Type{ min_val + 1 }), hash (Type{ max_val }));
|
||||||
|
ASSERT_NE (hash (Type{ max_val - 1 }), hash (Type{ min_val }));
|
||||||
|
|
||||||
|
// Common value tests
|
||||||
|
std::vector<underlying_t> common_values = {
|
||||||
|
0, // Zero
|
||||||
|
1, // One
|
||||||
|
42, // Common test value
|
||||||
|
0xFF, // Byte boundary
|
||||||
|
0xFFFF, // Word boundary
|
||||||
|
min_val, // Minimum
|
||||||
|
max_val, // Maximum
|
||||||
|
max_val / 2, // Middle value
|
||||||
|
min_val + (max_val / 2) // Offset middle
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test all common values against each other
|
||||||
|
for (size_t i = 0; i < common_values.size (); ++i)
|
||||||
|
{
|
||||||
|
for (size_t j = i + 1; j < common_values.size (); ++j)
|
||||||
|
{
|
||||||
|
if (common_values[i] != common_values[j])
|
||||||
|
{
|
||||||
|
ASSERT_NE (hash (Type{ common_values[i] }), hash (Type{ common_values[j] }));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT_EQ (hash (Type{ common_values[i] }), hash (Type{ common_values[j] }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST (numbers, hashing)
|
||||||
|
{
|
||||||
|
// Using std::hash
|
||||||
|
test_hashing<nano::uint128_union, std::hash> ();
|
||||||
|
test_hashing<nano::uint256_union, std::hash> ();
|
||||||
|
test_hashing<nano::uint512_union, std::hash> ();
|
||||||
|
test_hashing<nano::block_hash, std::hash> ();
|
||||||
|
test_hashing<nano::public_key, std::hash> ();
|
||||||
|
test_hashing<nano::hash_or_account, std::hash> ();
|
||||||
|
test_hashing<nano::link, std::hash> ();
|
||||||
|
test_hashing<nano::root, std::hash> ();
|
||||||
|
test_hashing<nano::raw_key, std::hash> ();
|
||||||
|
test_hashing<nano::wallet_id, std::hash> ();
|
||||||
|
test_hashing<nano::qualified_root, std::hash> ();
|
||||||
|
|
||||||
|
// Using boost::hash
|
||||||
|
test_hashing<nano::uint128_union, boost::hash> ();
|
||||||
|
test_hashing<nano::uint256_union, boost::hash> ();
|
||||||
|
test_hashing<nano::uint512_union, boost::hash> ();
|
||||||
|
test_hashing<nano::block_hash, boost::hash> ();
|
||||||
|
test_hashing<nano::public_key, boost::hash> ();
|
||||||
|
test_hashing<nano::hash_or_account, boost::hash> ();
|
||||||
|
test_hashing<nano::link, boost::hash> ();
|
||||||
|
test_hashing<nano::root, boost::hash> ();
|
||||||
|
test_hashing<nano::raw_key, boost::hash> ();
|
||||||
|
test_hashing<nano::wallet_id, boost::hash> ();
|
||||||
|
test_hashing<nano::qualified_root, boost::hash> ();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (uint128_union, decode_dec)
|
TEST (uint128_union, decode_dec)
|
||||||
|
|
@ -64,16 +229,6 @@ TEST (uint128_union, decode_dec_overflow)
|
||||||
ASSERT_TRUE (error);
|
ASSERT_TRUE (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (uint128_union, operator_less_than)
|
|
||||||
{
|
|
||||||
test_union_operator_less_than<nano::uint128_union, nano::uint128_t> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST (uint128_union, operator_greater_than)
|
|
||||||
{
|
|
||||||
test_union_operator_greater_than<nano::uint128_union, nano::uint128_t> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct test_punct : std::moneypunct<char>
|
struct test_punct : std::moneypunct<char>
|
||||||
{
|
{
|
||||||
pattern do_pos_format () const
|
pattern do_pos_format () const
|
||||||
|
|
@ -149,13 +304,6 @@ TEST (uint128_union, decode_decimal)
|
||||||
ASSERT_EQ (1230 * nano::Knano_ratio, amount.number ());
|
ASSERT_EQ (1230 * nano::Knano_ratio, amount.number ());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (unions, identity)
|
|
||||||
{
|
|
||||||
ASSERT_EQ (1, nano::uint128_union (1).number ().convert_to<uint8_t> ());
|
|
||||||
ASSERT_EQ (1, nano::uint256_union (1).number ().convert_to<uint8_t> ());
|
|
||||||
ASSERT_EQ (1, nano::uint512_union (1).number ().convert_to<uint8_t> ());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST (uint256_union, key_encryption)
|
TEST (uint256_union, key_encryption)
|
||||||
{
|
{
|
||||||
nano::keypair key1;
|
nano::keypair key1;
|
||||||
|
|
@ -449,11 +597,6 @@ TEST (uint256_union, bounds)
|
||||||
ASSERT_TRUE (key.decode_account (bad2));
|
ASSERT_TRUE (key.decode_account (bad2));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (uint256_union, operator_less_than)
|
|
||||||
{
|
|
||||||
test_union_operator_less_than<nano::uint256_union, nano::uint256_t> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST (uint64_t, parse)
|
TEST (uint64_t, parse)
|
||||||
{
|
{
|
||||||
uint64_t value0 (1);
|
uint64_t value0 (1);
|
||||||
|
|
@ -505,113 +648,3 @@ TEST (uint512_union, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
template <typename Union, typename Bound>
|
|
||||||
void assert_union_types ()
|
|
||||||
{
|
|
||||||
static_assert ((std::is_same<Union, nano::uint128_union>::value && std::is_same<Bound, nano::uint128_t>::value) || (std::is_same<Union, nano::uint256_union>::value && std::is_same<Bound, nano::uint256_t>::value) || (std::is_same<Union, nano::uint512_union>::value && std::is_same<Bound, nano::uint512_t>::value),
|
|
||||||
"Union type needs to be consistent with the lower/upper Bound type");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Union, typename Bound>
|
|
||||||
void test_union_operator_less_than ()
|
|
||||||
{
|
|
||||||
assert_union_types<Union, Bound> ();
|
|
||||||
|
|
||||||
// Small
|
|
||||||
check_operator_less_than (Union (123), Union (124));
|
|
||||||
check_operator_less_than (Union (124), Union (125));
|
|
||||||
|
|
||||||
// Medium
|
|
||||||
check_operator_less_than (Union (std::numeric_limits<uint16_t>::max () - 1), Union (std::numeric_limits<uint16_t>::max () + 1));
|
|
||||||
check_operator_less_than (Union (std::numeric_limits<uint32_t>::max () - 12345678), Union (std::numeric_limits<uint32_t>::max () - 123456));
|
|
||||||
|
|
||||||
// Large
|
|
||||||
check_operator_less_than (Union (std::numeric_limits<uint64_t>::max () - 555555555555), Union (std::numeric_limits<uint64_t>::max () - 1));
|
|
||||||
|
|
||||||
// Boundary values
|
|
||||||
check_operator_less_than (Union (std::numeric_limits<Bound>::min ()), Union (std::numeric_limits<Bound>::max ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Num>
|
|
||||||
void check_operator_less_than (Num lhs, Num rhs)
|
|
||||||
{
|
|
||||||
ASSERT_TRUE (lhs < rhs);
|
|
||||||
ASSERT_FALSE (rhs < lhs);
|
|
||||||
ASSERT_FALSE (lhs < lhs);
|
|
||||||
ASSERT_FALSE (rhs < rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Union, typename Bound>
|
|
||||||
void test_union_operator_greater_than ()
|
|
||||||
{
|
|
||||||
assert_union_types<Union, Bound> ();
|
|
||||||
|
|
||||||
// Small
|
|
||||||
check_operator_greater_than (Union (124), Union (123));
|
|
||||||
check_operator_greater_than (Union (125), Union (124));
|
|
||||||
|
|
||||||
// Medium
|
|
||||||
check_operator_greater_than (Union (std::numeric_limits<uint16_t>::max () + 1), Union (std::numeric_limits<uint16_t>::max () - 1));
|
|
||||||
check_operator_greater_than (Union (std::numeric_limits<uint32_t>::max () - 123456), Union (std::numeric_limits<uint32_t>::max () - 12345678));
|
|
||||||
|
|
||||||
// Large
|
|
||||||
check_operator_greater_than (Union (std::numeric_limits<uint64_t>::max () - 1), Union (std::numeric_limits<uint64_t>::max () - 555555555555));
|
|
||||||
|
|
||||||
// Boundary values
|
|
||||||
check_operator_greater_than (Union (std::numeric_limits<Bound>::max ()), Union (std::numeric_limits<Bound>::min ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Num>
|
|
||||||
void check_operator_greater_than (Num lhs, Num rhs)
|
|
||||||
{
|
|
||||||
ASSERT_TRUE (lhs > rhs);
|
|
||||||
ASSERT_FALSE (rhs > lhs);
|
|
||||||
ASSERT_FALSE (lhs > lhs);
|
|
||||||
ASSERT_FALSE (rhs > rhs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST (random_pool, multithreading)
|
|
||||||
{
|
|
||||||
std::vector<std::thread> threads;
|
|
||||||
for (auto i = 0; i < 100; ++i)
|
|
||||||
{
|
|
||||||
threads.emplace_back ([] () {
|
|
||||||
nano::uint256_union number;
|
|
||||||
nano::random_pool::generate_block (number.bytes.data (), number.bytes.size ());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (auto & i : threads)
|
|
||||||
{
|
|
||||||
i.join ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test that random 64bit numbers are within the given range
|
|
||||||
TEST (random_pool, generate_word64)
|
|
||||||
{
|
|
||||||
int occurrences[10] = { 0 };
|
|
||||||
for (auto i = 0; i < 1000; ++i)
|
|
||||||
{
|
|
||||||
auto random = nano::random_pool::generate_word64 (1, 9);
|
|
||||||
ASSERT_TRUE (random >= 1 && random <= 9);
|
|
||||||
occurrences[random] += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto i = 1; i < 10; ++i)
|
|
||||||
{
|
|
||||||
ASSERT_GT (occurrences[i], 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test random numbers > uint32 max
|
|
||||||
TEST (random_pool, generate_word64_big_number)
|
|
||||||
{
|
|
||||||
uint64_t min = static_cast<uint64_t> (std::numeric_limits<uint32_t>::max ()) + 1;
|
|
||||||
uint64_t max = std::numeric_limits<uint64_t>::max ();
|
|
||||||
auto big_random = nano::random_pool::generate_word64 (min, max);
|
|
||||||
ASSERT_GE (big_random, min);
|
|
||||||
}
|
|
||||||
48
nano/core_test/random_pool.cpp
Normal file
48
nano/core_test/random_pool.cpp
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include <nano/crypto_lib/random_pool.hpp>
|
||||||
|
#include <nano/lib/numbers.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
TEST (random_pool, multithreading)
|
||||||
|
{
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
for (auto i = 0; i < 100; ++i)
|
||||||
|
{
|
||||||
|
threads.emplace_back ([] () {
|
||||||
|
nano::uint256_union number;
|
||||||
|
nano::random_pool::generate_block (number.bytes.data (), number.bytes.size ());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (auto & i : threads)
|
||||||
|
{
|
||||||
|
i.join ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that random 64bit numbers are within the given range
|
||||||
|
TEST (random_pool, generate_word64)
|
||||||
|
{
|
||||||
|
int occurrences[10] = { 0 };
|
||||||
|
for (auto i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
auto random = nano::random_pool::generate_word64 (1, 9);
|
||||||
|
ASSERT_TRUE (random >= 1 && random <= 9);
|
||||||
|
occurrences[random] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 1; i < 10; ++i)
|
||||||
|
{
|
||||||
|
ASSERT_GT (occurrences[i], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test random numbers > uint32 max
|
||||||
|
TEST (random_pool, generate_word64_big_number)
|
||||||
|
{
|
||||||
|
uint64_t min = static_cast<uint64_t> (std::numeric_limits<uint32_t>::max ()) + 1;
|
||||||
|
uint64_t max = std::numeric_limits<uint64_t>::max ();
|
||||||
|
auto big_random = nano::random_pool::generate_word64 (min, max);
|
||||||
|
ASSERT_GE (big_random, min);
|
||||||
|
}
|
||||||
|
|
@ -609,7 +609,7 @@ std::optional<nano::account> nano::send_block::destination_field () const
|
||||||
return hashables.destination;
|
return hashables.destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::root const & nano::send_block::root () const
|
nano::root nano::send_block::root () const
|
||||||
{
|
{
|
||||||
return hashables.previous;
|
return hashables.previous;
|
||||||
}
|
}
|
||||||
|
|
@ -899,7 +899,7 @@ std::optional<nano::block_hash> nano::open_block::source_field () const
|
||||||
return hashables.source;
|
return hashables.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::root const & nano::open_block::root () const
|
nano::root nano::open_block::root () const
|
||||||
{
|
{
|
||||||
return hashables.account;
|
return hashables.account;
|
||||||
}
|
}
|
||||||
|
|
@ -1165,7 +1165,7 @@ bool nano::change_block::valid_predecessor (nano::block const & block_a) const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::root const & nano::change_block::root () const
|
nano::root nano::change_block::root () const
|
||||||
{
|
{
|
||||||
return hashables.previous;
|
return hashables.previous;
|
||||||
}
|
}
|
||||||
|
|
@ -1482,7 +1482,7 @@ bool nano::state_block::valid_predecessor (nano::block const & block_a) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::root const & nano::state_block::root () const
|
nano::root nano::state_block::root () const
|
||||||
{
|
{
|
||||||
if (!hashables.previous.is_zero ())
|
if (!hashables.previous.is_zero ())
|
||||||
{
|
{
|
||||||
|
|
@ -1836,7 +1836,7 @@ std::optional<nano::block_hash> nano::receive_block::source_field () const
|
||||||
return hashables.source;
|
return hashables.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::root const & nano::receive_block::root () const
|
nano::root nano::receive_block::root () const
|
||||||
{
|
{
|
||||||
return hashables.previous;
|
return hashables.previous;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ public:
|
||||||
virtual uint64_t block_work () const = 0;
|
virtual uint64_t block_work () const = 0;
|
||||||
virtual void block_work_set (uint64_t) = 0;
|
virtual void block_work_set (uint64_t) = 0;
|
||||||
// Previous block or account number for open blocks
|
// Previous block or account number for open blocks
|
||||||
virtual nano::root const & root () const = 0;
|
virtual nano::root root () const = 0;
|
||||||
// Qualified root value based on previous() and root()
|
// Qualified root value based on previous() and root()
|
||||||
virtual nano::qualified_root qualified_root () const;
|
virtual nano::qualified_root qualified_root () const;
|
||||||
virtual void serialize (nano::stream &) const = 0;
|
virtual void serialize (nano::stream &) const = 0;
|
||||||
|
|
@ -123,7 +123,7 @@ public:
|
||||||
virtual ~send_block () = default;
|
virtual ~send_block () = default;
|
||||||
uint64_t block_work () const override;
|
uint64_t block_work () const override;
|
||||||
void block_work_set (uint64_t) override;
|
void block_work_set (uint64_t) override;
|
||||||
nano::root const & root () const override;
|
nano::root root () const override;
|
||||||
void serialize (nano::stream &) const override;
|
void serialize (nano::stream &) const override;
|
||||||
bool deserialize (nano::stream &);
|
bool deserialize (nano::stream &);
|
||||||
void serialize_json (std::string &, bool = false) const override;
|
void serialize_json (std::string &, bool = false) const override;
|
||||||
|
|
@ -177,7 +177,7 @@ public:
|
||||||
virtual ~receive_block () = default;
|
virtual ~receive_block () = default;
|
||||||
uint64_t block_work () const override;
|
uint64_t block_work () const override;
|
||||||
void block_work_set (uint64_t) override;
|
void block_work_set (uint64_t) override;
|
||||||
nano::root const & root () const override;
|
nano::root root () const override;
|
||||||
void serialize (nano::stream &) const override;
|
void serialize (nano::stream &) const override;
|
||||||
bool deserialize (nano::stream &);
|
bool deserialize (nano::stream &);
|
||||||
void serialize_json (std::string &, bool = false) const override;
|
void serialize_json (std::string &, bool = false) const override;
|
||||||
|
|
@ -232,7 +232,7 @@ public:
|
||||||
virtual ~open_block () = default;
|
virtual ~open_block () = default;
|
||||||
uint64_t block_work () const override;
|
uint64_t block_work () const override;
|
||||||
void block_work_set (uint64_t) override;
|
void block_work_set (uint64_t) override;
|
||||||
nano::root const & root () const override;
|
nano::root root () const override;
|
||||||
void serialize (nano::stream &) const override;
|
void serialize (nano::stream &) const override;
|
||||||
bool deserialize (nano::stream &);
|
bool deserialize (nano::stream &);
|
||||||
void serialize_json (std::string &, bool = false) const override;
|
void serialize_json (std::string &, bool = false) const override;
|
||||||
|
|
@ -287,7 +287,7 @@ public:
|
||||||
virtual ~change_block () = default;
|
virtual ~change_block () = default;
|
||||||
uint64_t block_work () const override;
|
uint64_t block_work () const override;
|
||||||
void block_work_set (uint64_t) override;
|
void block_work_set (uint64_t) override;
|
||||||
nano::root const & root () const override;
|
nano::root root () const override;
|
||||||
void serialize (nano::stream &) const override;
|
void serialize (nano::stream &) const override;
|
||||||
bool deserialize (nano::stream &);
|
bool deserialize (nano::stream &);
|
||||||
void serialize_json (std::string &, bool = false) const override;
|
void serialize_json (std::string &, bool = false) const override;
|
||||||
|
|
@ -353,7 +353,7 @@ public:
|
||||||
virtual ~state_block () = default;
|
virtual ~state_block () = default;
|
||||||
uint64_t block_work () const override;
|
uint64_t block_work () const override;
|
||||||
void block_work_set (uint64_t) override;
|
void block_work_set (uint64_t) override;
|
||||||
nano::root const & root () const override;
|
nano::root root () const override;
|
||||||
void serialize (nano::stream &) const override;
|
void serialize (nano::stream &) const override;
|
||||||
bool deserialize (nano::stream &);
|
bool deserialize (nano::stream &);
|
||||||
void serialize_json (std::string &, bool = false) const override;
|
void serialize_json (std::string &, bool = false) const override;
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,6 @@ std::string nano::public_key::to_account () const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::public_key::public_key () :
|
|
||||||
uint256_union{ 0 }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::public_key const & nano::public_key::null ()
|
nano::public_key const & nano::public_key::null ()
|
||||||
{
|
{
|
||||||
return nano::hardened_constants::get ().not_an_account;
|
return nano::hardened_constants::get ().not_an_account;
|
||||||
|
|
@ -143,12 +138,6 @@ bool nano::public_key::decode_account (std::string const & source_a)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::uint256_union::uint256_union (nano::uint256_t const & number_a)
|
|
||||||
{
|
|
||||||
bytes.fill (0);
|
|
||||||
boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv)
|
// Construct a uint256_union = AES_ENC_CTR (cleartext, key, iv)
|
||||||
void nano::uint256_union::encrypt (nano::raw_key const & cleartext, nano::raw_key const & key, uint128_union const & iv)
|
void nano::uint256_union::encrypt (nano::raw_key const & cleartext, nano::raw_key const & key, uint128_union const & iv)
|
||||||
{
|
{
|
||||||
|
|
@ -157,11 +146,6 @@ void nano::uint256_union::encrypt (nano::raw_key const & cleartext, nano::raw_ke
|
||||||
enc.ProcessData (bytes.data (), cleartext.bytes.data (), sizeof (cleartext.bytes));
|
enc.ProcessData (bytes.data (), cleartext.bytes.data (), sizeof (cleartext.bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nano::uint256_union::is_zero () const
|
|
||||||
{
|
|
||||||
return qwords[0] == 0 && qwords[1] == 0 && qwords[2] == 0 && qwords[3] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string nano::uint256_union::to_string () const
|
std::string nano::uint256_union::to_string () const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
@ -193,22 +177,9 @@ nano::uint256_union nano::uint256_union::operator^ (nano::uint256_union const &
|
||||||
nano::uint256_union::uint256_union (std::string const & hex_a)
|
nano::uint256_union::uint256_union (std::string const & hex_a)
|
||||||
{
|
{
|
||||||
auto error (decode_hex (hex_a));
|
auto error (decode_hex (hex_a));
|
||||||
|
|
||||||
release_assert (!error);
|
release_assert (!error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nano::uint256_union::clear ()
|
|
||||||
{
|
|
||||||
qwords.fill (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint256_t nano::uint256_union::number () const
|
|
||||||
{
|
|
||||||
nano::uint256_t result;
|
|
||||||
boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nano::uint256_union::encode_hex (std::string & text) const
|
void nano::uint256_union::encode_hex (std::string & text) const
|
||||||
{
|
{
|
||||||
debug_assert (text.empty ());
|
debug_assert (text.empty ());
|
||||||
|
|
@ -281,46 +252,6 @@ bool nano::uint256_union::decode_dec (std::string const & text)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::uint256_union::uint256_union (uint64_t value0)
|
|
||||||
{
|
|
||||||
*this = nano::uint256_t (value0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint512_union::operator== (nano::uint512_union const & other_a) const
|
|
||||||
{
|
|
||||||
return bytes == other_a.bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint512_union::uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower)
|
|
||||||
{
|
|
||||||
uint256s[0] = upper;
|
|
||||||
uint256s[1] = lower;
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint512_union::uint512_union (nano::uint512_t const & number_a)
|
|
||||||
{
|
|
||||||
bytes.fill (0);
|
|
||||||
boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint512_union::is_zero () const
|
|
||||||
{
|
|
||||||
return qwords[0] == 0 && qwords[1] == 0 && qwords[2] == 0 && qwords[3] == 0
|
|
||||||
&& qwords[4] == 0 && qwords[5] == 0 && qwords[6] == 0 && qwords[7] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nano::uint512_union::clear ()
|
|
||||||
{
|
|
||||||
bytes.fill (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint512_t nano::uint512_union::number () const
|
|
||||||
{
|
|
||||||
nano::uint512_t result;
|
|
||||||
boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nano::uint512_union::encode_hex (std::string & text) const
|
void nano::uint512_union::encode_hex (std::string & text) const
|
||||||
{
|
{
|
||||||
debug_assert (text.empty ());
|
debug_assert (text.empty ());
|
||||||
|
|
@ -355,18 +286,6 @@ bool nano::uint512_union::decode_hex (std::string const & text)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nano::uint512_union::operator!= (nano::uint512_union const & other_a) const
|
|
||||||
{
|
|
||||||
return !(*this == other_a);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint512_union & nano::uint512_union::operator^= (nano::uint512_union const & other_a)
|
|
||||||
{
|
|
||||||
uint256s[0] ^= other_a.uint256s[0];
|
|
||||||
uint256s[1] ^= other_a.uint256s[1];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string nano::uint512_union::to_string () const
|
std::string nano::uint512_union::to_string () const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
@ -431,48 +350,9 @@ bool nano::validate_message (nano::public_key const & public_key, nano::uint256_
|
||||||
nano::uint128_union::uint128_union (std::string const & string_a)
|
nano::uint128_union::uint128_union (std::string const & string_a)
|
||||||
{
|
{
|
||||||
auto error (decode_hex (string_a));
|
auto error (decode_hex (string_a));
|
||||||
|
|
||||||
release_assert (!error);
|
release_assert (!error);
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::uint128_union::uint128_union (uint64_t value_a)
|
|
||||||
{
|
|
||||||
*this = nano::uint128_t (value_a);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint128_union::uint128_union (nano::uint128_t const & number_a)
|
|
||||||
{
|
|
||||||
bytes.fill (0);
|
|
||||||
boost::multiprecision::export_bits (number_a, bytes.rbegin (), 8, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint128_union::operator== (nano::uint128_union const & other_a) const
|
|
||||||
{
|
|
||||||
return qwords[0] == other_a.qwords[0] && qwords[1] == other_a.qwords[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint128_union::operator!= (nano::uint128_union const & other_a) const
|
|
||||||
{
|
|
||||||
return !(*this == other_a);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint128_union::operator< (nano::uint128_union const & other_a) const
|
|
||||||
{
|
|
||||||
return std::memcmp (bytes.data (), other_a.bytes.data (), 16) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint128_union::operator> (nano::uint128_union const & other_a) const
|
|
||||||
{
|
|
||||||
return std::memcmp (bytes.data (), other_a.bytes.data (), 16) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::uint128_t nano::uint128_union::number () const
|
|
||||||
{
|
|
||||||
nano::uint128_t result;
|
|
||||||
boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nano::uint128_union::encode_hex (std::string & text) const
|
void nano::uint128_union::encode_hex (std::string & text) const
|
||||||
{
|
{
|
||||||
debug_assert (text.empty ());
|
debug_assert (text.empty ());
|
||||||
|
|
@ -747,16 +627,6 @@ std::string nano::uint128_union::format_balance (nano::uint128_t scale, int prec
|
||||||
return ::format_balance (number (), scale, precision, group_digits, thousands_sep, decimal_point, grouping);
|
return ::format_balance (number (), scale, precision, group_digits, thousands_sep, decimal_point, grouping);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nano::uint128_union::clear ()
|
|
||||||
{
|
|
||||||
qwords.fill (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::uint128_union::is_zero () const
|
|
||||||
{
|
|
||||||
return qwords[0] == 0 && qwords[1] == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string nano::uint128_union::to_string () const
|
std::string nano::uint128_union::to_string () const
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
@ -771,26 +641,6 @@ std::string nano::uint128_union::to_string_dec () const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::hash_or_account::hash_or_account () :
|
|
||||||
account{}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::hash_or_account::hash_or_account (uint64_t value_a) :
|
|
||||||
raw (value_a)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::hash_or_account::is_zero () const
|
|
||||||
{
|
|
||||||
return raw.is_zero ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nano::hash_or_account::clear ()
|
|
||||||
{
|
|
||||||
raw.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::hash_or_account::decode_hex (std::string const & text_a)
|
bool nano::hash_or_account::decode_hex (std::string const & text_a)
|
||||||
{
|
{
|
||||||
return raw.decode_hex (text_a);
|
return raw.decode_hex (text_a);
|
||||||
|
|
@ -811,36 +661,6 @@ std::string nano::hash_or_account::to_account () const
|
||||||
return account.to_account ();
|
return account.to_account ();
|
||||||
}
|
}
|
||||||
|
|
||||||
nano::block_hash const & nano::hash_or_account::as_block_hash () const
|
|
||||||
{
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::account const & nano::hash_or_account::as_account () const
|
|
||||||
{
|
|
||||||
return account;
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::hash_or_account::operator nano::uint256_union const & () const
|
|
||||||
{
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::block_hash const & nano::root::previous () const
|
|
||||||
{
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::hash_or_account::operator== (nano::hash_or_account const & hash_or_account_a) const
|
|
||||||
{
|
|
||||||
return bytes == hash_or_account_a.bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::hash_or_account::operator!= (nano::hash_or_account const & hash_or_account_a) const
|
|
||||||
{
|
|
||||||
return !(*this == hash_or_account_a);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string nano::to_string_hex (uint64_t const value_a)
|
std::string nano::to_string_hex (uint64_t const value_a)
|
||||||
{
|
{
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
|
|
@ -915,6 +735,13 @@ std::ostream & nano::operator<< (std::ostream & os, const uint512_union & val)
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream & nano::operator<< (std::ostream & os, const hash_or_account & val)
|
||||||
|
{
|
||||||
|
// TODO: Replace with streaming implementation
|
||||||
|
os << val.to_string ();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
|
#pragma warning(disable : 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
|
||||||
|
|
@ -947,43 +774,3 @@ double nano::difficulty::to_multiplier (uint64_t const difficulty_a, uint64_t co
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nano::public_key::operator nano::link const & () const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<nano::link const &> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::public_key::operator nano::root const & () const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<nano::root const &> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::public_key::operator nano::hash_or_account const & () const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<nano::hash_or_account const &> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::public_key::operator== (std::nullptr_t) const
|
|
||||||
{
|
|
||||||
return bytes == null ().bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nano::public_key::operator!= (std::nullptr_t) const
|
|
||||||
{
|
|
||||||
return !(*this == nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::block_hash::operator nano::link const & () const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<nano::link const &> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::block_hash::operator nano::root const & () const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<nano::root const &> (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
nano::block_hash::operator nano::hash_or_account const & () const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<nano::hash_or_account const &> (*this);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
#include <boost/multiprecision/cpp_int.hpp>
|
#include <boost/multiprecision/cpp_int.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <compare>
|
||||||
|
#include <limits>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
|
|
@ -13,6 +15,7 @@ namespace nano
|
||||||
using uint128_t = boost::multiprecision::uint128_t;
|
using uint128_t = boost::multiprecision::uint128_t;
|
||||||
using uint256_t = boost::multiprecision::uint256_t;
|
using uint256_t = boost::multiprecision::uint256_t;
|
||||||
using uint512_t = boost::multiprecision::uint512_t;
|
using uint512_t = boost::multiprecision::uint512_t;
|
||||||
|
|
||||||
// SI dividers
|
// SI dividers
|
||||||
nano::uint128_t const Knano_ratio = nano::uint128_t ("1000000000000000000000000000000000"); // 10^33 = 1000 nano
|
nano::uint128_t const Knano_ratio = nano::uint128_t ("1000000000000000000000000000000000"); // 10^33 = 1000 nano
|
||||||
nano::uint128_t const nano_ratio = nano::uint128_t ("1000000000000000000000000000000"); // 10^30 = 1 nano
|
nano::uint128_t const nano_ratio = nano::uint128_t ("1000000000000000000000000000000"); // 10^30 = 1 nano
|
||||||
|
|
@ -20,31 +23,55 @@ nano::uint128_t const raw_ratio = nano::uint128_t ("1"); // 10^0
|
||||||
|
|
||||||
class uint128_union
|
class uint128_union
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
// Type that is implicitly convertible to this union
|
||||||
|
using underlying_type = nano::uint128_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint128_union () = default;
|
uint128_union () = default;
|
||||||
|
uint128_union (uint64_t value) :
|
||||||
|
uint128_union (nano::uint128_t{ value }){};
|
||||||
|
uint128_union (nano::uint128_t const & value)
|
||||||
|
{
|
||||||
|
bytes.fill (0);
|
||||||
|
boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode from hex string
|
* Decode from hex string
|
||||||
* @warning Aborts at runtime if the input is invalid
|
* @warning Aborts at runtime if the input is invalid
|
||||||
*/
|
*/
|
||||||
uint128_union (std::string const &);
|
explicit uint128_union (std::string const &);
|
||||||
uint128_union (uint64_t);
|
|
||||||
uint128_union (nano::uint128_t const &);
|
|
||||||
bool operator== (nano::uint128_union const &) const;
|
|
||||||
bool operator!= (nano::uint128_union const &) const;
|
|
||||||
bool operator< (nano::uint128_union const &) const;
|
|
||||||
bool operator> (nano::uint128_union const &) const;
|
|
||||||
void encode_hex (std::string &) const;
|
void encode_hex (std::string &) const;
|
||||||
bool decode_hex (std::string const &);
|
bool decode_hex (std::string const &);
|
||||||
void encode_dec (std::string &) const;
|
void encode_dec (std::string &) const;
|
||||||
bool decode_dec (std::string const &, bool = false);
|
bool decode_dec (std::string const &, bool = false);
|
||||||
bool decode_dec (std::string const &, nano::uint128_t);
|
bool decode_dec (std::string const &, nano::uint128_t);
|
||||||
|
|
||||||
std::string format_balance (nano::uint128_t scale, int precision, bool group_digits) const;
|
std::string format_balance (nano::uint128_t scale, int precision, bool group_digits) const;
|
||||||
std::string format_balance (nano::uint128_t scale, int precision, bool group_digits, std::locale const & locale) const;
|
std::string format_balance (nano::uint128_t scale, int precision, bool group_digits, std::locale const & locale) const;
|
||||||
nano::uint128_t number () const;
|
|
||||||
void clear ();
|
void clear ()
|
||||||
bool is_zero () const;
|
{
|
||||||
|
qwords.fill (0);
|
||||||
|
}
|
||||||
|
bool is_zero () const
|
||||||
|
{
|
||||||
|
return qwords[0] == 0 && qwords[1] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nano::uint128_t number () const
|
||||||
|
{
|
||||||
|
nano::uint128_t result;
|
||||||
|
boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string to_string () const;
|
std::string to_string () const;
|
||||||
std::string to_string_dec () const;
|
std::string to_string_dec () const;
|
||||||
|
|
||||||
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 16> bytes;
|
std::array<uint8_t, 16> bytes;
|
||||||
|
|
@ -52,6 +79,24 @@ public:
|
||||||
std::array<uint32_t, 4> dwords;
|
std::array<uint32_t, 4> dwords;
|
||||||
std::array<uint64_t, 2> qwords;
|
std::array<uint64_t, 2> qwords;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public: // Keep operators inlined
|
||||||
|
std::strong_ordering operator<=> (nano::uint128_union const & other) const
|
||||||
|
{
|
||||||
|
return std::memcmp (bytes.data (), other.bytes.data (), 16) <=> 0;
|
||||||
|
};
|
||||||
|
bool operator== (nano::uint128_union const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
|
operator nano::uint128_t () const
|
||||||
|
{
|
||||||
|
return number ();
|
||||||
|
}
|
||||||
|
uint128_union const & as_union () const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert (std::is_nothrow_move_constructible<uint128_union>::value, "uint128_union should be noexcept MoveConstructible");
|
static_assert (std::is_nothrow_move_constructible<uint128_union>::value, "uint128_union should be noexcept MoveConstructible");
|
||||||
|
|
||||||
|
|
@ -61,37 +106,69 @@ class amount : public uint128_union
|
||||||
public:
|
public:
|
||||||
using uint128_union::uint128_union;
|
using uint128_union::uint128_union;
|
||||||
|
|
||||||
|
auto operator<=> (nano::amount const & other) const
|
||||||
|
{
|
||||||
|
return uint128_union::operator<=> (other);
|
||||||
|
}
|
||||||
operator nano::uint128_t () const
|
operator nano::uint128_t () const
|
||||||
{
|
{
|
||||||
return number ();
|
return number ();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class raw_key;
|
class raw_key;
|
||||||
|
|
||||||
class uint256_union
|
class uint256_union
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
// Type that is implicitly convertible to this union
|
||||||
|
using underlying_type = nano::uint256_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint256_union () = default;
|
uint256_union () = default;
|
||||||
|
uint256_union (uint64_t value) :
|
||||||
|
uint256_union (nano::uint256_t{ value }){};
|
||||||
|
uint256_union (nano::uint256_t const & value)
|
||||||
|
{
|
||||||
|
bytes.fill (0);
|
||||||
|
boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode from hex string
|
* Decode from hex string
|
||||||
* @warning Aborts at runtime if the input is invalid
|
* @warning Aborts at runtime if the input is invalid
|
||||||
*/
|
*/
|
||||||
explicit uint256_union (std::string const &);
|
explicit uint256_union (std::string const &);
|
||||||
uint256_union (uint64_t);
|
|
||||||
uint256_union (nano::uint256_t const &);
|
|
||||||
void encrypt (nano::raw_key const &, nano::raw_key const &, uint128_union const &);
|
void encrypt (nano::raw_key const &, nano::raw_key const &, uint128_union const &);
|
||||||
uint256_union & operator^= (nano::uint256_union const &);
|
|
||||||
uint256_union operator^ (nano::uint256_union const &) const;
|
uint256_union & operator^= (uint256_union const &);
|
||||||
|
uint256_union operator^ (uint256_union const &) const;
|
||||||
|
|
||||||
void encode_hex (std::string &) const;
|
void encode_hex (std::string &) const;
|
||||||
bool decode_hex (std::string const &);
|
bool decode_hex (std::string const &);
|
||||||
void encode_dec (std::string &) const;
|
void encode_dec (std::string &) const;
|
||||||
bool decode_dec (std::string const &);
|
bool decode_dec (std::string const &);
|
||||||
|
|
||||||
void clear ();
|
void clear ()
|
||||||
bool is_zero () const;
|
{
|
||||||
std::string to_string () const;
|
qwords.fill (0);
|
||||||
nano::uint256_t number () const;
|
}
|
||||||
|
bool is_zero () const
|
||||||
|
{
|
||||||
|
return owords[0].is_zero () && owords[1].is_zero ();
|
||||||
|
}
|
||||||
|
|
||||||
|
nano::uint256_t number () const
|
||||||
|
{
|
||||||
|
nano::uint256_t result;
|
||||||
|
boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string () const;
|
||||||
|
|
||||||
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 32> bytes;
|
std::array<uint8_t, 32> bytes;
|
||||||
|
|
@ -100,33 +177,46 @@ public:
|
||||||
std::array<uint64_t, 4> qwords;
|
std::array<uint64_t, 4> qwords;
|
||||||
std::array<uint128_union, 2> owords;
|
std::array<uint128_union, 2> owords;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
inline bool operator== (nano::uint256_union const & lhs, nano::uint256_union const & rhs)
|
|
||||||
{
|
|
||||||
return lhs.bytes == rhs.bytes;
|
|
||||||
}
|
|
||||||
inline bool operator!= (nano::uint256_union const & lhs, nano::uint256_union const & rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
inline bool operator< (nano::uint256_union const & lhs, nano::uint256_union const & rhs)
|
|
||||||
{
|
|
||||||
return std::memcmp (lhs.bytes.data (), rhs.bytes.data (), 32) < 0;
|
|
||||||
}
|
|
||||||
static_assert (std::is_nothrow_move_constructible<uint256_union>::value, "uint256_union should be noexcept MoveConstructible");
|
|
||||||
|
|
||||||
class link;
|
public: // Keep operators inlined
|
||||||
class root;
|
std::strong_ordering operator<=> (nano::uint256_union const & other) const
|
||||||
class hash_or_account;
|
{
|
||||||
|
return std::memcmp (bytes.data (), other.bytes.data (), 32) <=> 0;
|
||||||
|
};
|
||||||
|
bool operator== (nano::uint256_union const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
|
operator nano::uint256_t () const
|
||||||
|
{
|
||||||
|
return number ();
|
||||||
|
}
|
||||||
|
uint256_union const & as_union () const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert (std::is_nothrow_move_constructible<uint256_union>::value, "uint256_union should be noexcept MoveConstructible");
|
||||||
|
|
||||||
// All keys and hashes are 256 bit.
|
// All keys and hashes are 256 bit.
|
||||||
class block_hash final : public uint256_union
|
class block_hash final : public uint256_union
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using uint256_union::uint256_union;
|
using uint256_union::uint256_union;
|
||||||
operator nano::link const & () const;
|
|
||||||
operator nano::root const & () const;
|
public: // Keep operators inlined
|
||||||
operator nano::hash_or_account const & () const;
|
auto operator<=> (nano::block_hash const & other) const
|
||||||
|
{
|
||||||
|
return uint256_union::operator<=> (other);
|
||||||
|
}
|
||||||
|
bool operator== (nano::block_hash const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
|
operator nano::uint256_t () const
|
||||||
|
{
|
||||||
|
return number ();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class public_key final : public uint256_union
|
class public_key final : public uint256_union
|
||||||
|
|
@ -134,21 +224,35 @@ class public_key final : public uint256_union
|
||||||
public:
|
public:
|
||||||
using uint256_union::uint256_union;
|
using uint256_union::uint256_union;
|
||||||
|
|
||||||
public_key ();
|
public_key () :
|
||||||
|
uint256_union{ 0 } {};
|
||||||
|
|
||||||
static const public_key & null ();
|
static const public_key & null ();
|
||||||
|
|
||||||
std::string to_node_id () const;
|
bool decode_node_id (std::string const &);
|
||||||
bool decode_node_id (std::string const & source_a);
|
|
||||||
void encode_account (std::string &) const;
|
void encode_account (std::string &) const;
|
||||||
std::string to_account () const;
|
|
||||||
bool decode_account (std::string const &);
|
bool decode_account (std::string const &);
|
||||||
|
|
||||||
operator nano::link const & () const;
|
std::string to_node_id () const;
|
||||||
operator nano::root const & () const;
|
std::string to_account () const;
|
||||||
operator nano::hash_or_account const & () const;
|
|
||||||
bool operator== (std::nullptr_t) const;
|
public: // Keep operators inlined
|
||||||
bool operator!= (std::nullptr_t) const;
|
auto operator<=> (nano::public_key const & other) const
|
||||||
|
{
|
||||||
|
return uint256_union::operator<=> (other);
|
||||||
|
}
|
||||||
|
bool operator== (nano::public_key const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
|
bool operator== (std::nullptr_t) const
|
||||||
|
{
|
||||||
|
return *this == null ();
|
||||||
|
}
|
||||||
|
operator nano::uint256_t () const
|
||||||
|
{
|
||||||
|
return number ();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class wallet_id : public uint256_union
|
class wallet_id : public uint256_union
|
||||||
|
|
@ -162,24 +266,33 @@ using account = public_key;
|
||||||
class hash_or_account
|
class hash_or_account
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
hash_or_account ();
|
// Type that is implicitly convertible to this union
|
||||||
hash_or_account (uint64_t value_a);
|
using underlying_type = nano::uint256_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
hash_or_account () :
|
||||||
|
account{} {};
|
||||||
|
hash_or_account (uint64_t value) :
|
||||||
|
raw{ value } {};
|
||||||
|
hash_or_account (uint256_union const & value) :
|
||||||
|
raw{ value } {};
|
||||||
|
|
||||||
|
void clear ()
|
||||||
|
{
|
||||||
|
raw.clear ();
|
||||||
|
}
|
||||||
|
bool is_zero () const
|
||||||
|
{
|
||||||
|
return raw.is_zero ();
|
||||||
|
}
|
||||||
|
|
||||||
bool is_zero () const;
|
|
||||||
void clear ();
|
|
||||||
std::string to_string () const;
|
|
||||||
bool decode_hex (std::string const &);
|
bool decode_hex (std::string const &);
|
||||||
bool decode_account (std::string const &);
|
bool decode_account (std::string const &);
|
||||||
|
|
||||||
|
std::string to_string () const;
|
||||||
std::string to_account () const;
|
std::string to_account () const;
|
||||||
|
|
||||||
nano::account const & as_account () const;
|
public:
|
||||||
nano::block_hash const & as_block_hash () const;
|
|
||||||
|
|
||||||
operator nano::uint256_union const & () const;
|
|
||||||
|
|
||||||
bool operator== (nano::hash_or_account const &) const;
|
|
||||||
bool operator!= (nano::hash_or_account const &) const;
|
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 32> bytes;
|
std::array<uint8_t, 32> bytes;
|
||||||
|
|
@ -187,6 +300,36 @@ public:
|
||||||
nano::account account;
|
nano::account account;
|
||||||
nano::block_hash hash;
|
nano::block_hash hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public: // Keep operators inlined
|
||||||
|
auto operator<=> (nano::hash_or_account const & other) const
|
||||||
|
{
|
||||||
|
return raw <=> other.raw;
|
||||||
|
};
|
||||||
|
bool operator== (nano::hash_or_account const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
|
explicit operator nano::uint256_t () const
|
||||||
|
{
|
||||||
|
return raw.number ();
|
||||||
|
}
|
||||||
|
explicit operator nano::uint256_union () const
|
||||||
|
{
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
nano::account const & as_account () const
|
||||||
|
{
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
nano::block_hash const & as_block_hash () const
|
||||||
|
{
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
nano::uint256_union const & as_union () const
|
||||||
|
{
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A link can either be a destination account or source hash
|
// A link can either be a destination account or source hash
|
||||||
|
|
@ -194,6 +337,16 @@ class link final : public hash_or_account
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using hash_or_account::hash_or_account;
|
using hash_or_account::hash_or_account;
|
||||||
|
|
||||||
|
public: // Keep operators inlined
|
||||||
|
auto operator<=> (nano::link const & other) const
|
||||||
|
{
|
||||||
|
return hash_or_account::operator<=> (other);
|
||||||
|
}
|
||||||
|
bool operator== (nano::link const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A root can either be an open block hash or a previous hash
|
// A root can either be an open block hash or a previous hash
|
||||||
|
|
@ -202,7 +355,20 @@ class root final : public hash_or_account
|
||||||
public:
|
public:
|
||||||
using hash_or_account::hash_or_account;
|
using hash_or_account::hash_or_account;
|
||||||
|
|
||||||
nano::block_hash const & previous () const;
|
nano::block_hash const & previous () const
|
||||||
|
{
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public: // Keep operators inlined
|
||||||
|
auto operator<=> (nano::root const & other) const
|
||||||
|
{
|
||||||
|
return hash_or_account::operator<=> (other);
|
||||||
|
}
|
||||||
|
bool operator== (nano::root const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// The seed or private key
|
// The seed or private key
|
||||||
|
|
@ -213,22 +379,52 @@ public:
|
||||||
~raw_key ();
|
~raw_key ();
|
||||||
void decrypt (nano::uint256_union const &, nano::raw_key const &, uint128_union const &);
|
void decrypt (nano::uint256_union const &, nano::raw_key const &, uint128_union const &);
|
||||||
};
|
};
|
||||||
|
|
||||||
class uint512_union
|
class uint512_union
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
// Type that is implicitly convertible to this union
|
||||||
|
using underlying_type = nano::uint512_t;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint512_union () = default;
|
uint512_union () = default;
|
||||||
uint512_union (nano::uint256_union const &, nano::uint256_union const &);
|
uint512_union (nano::uint512_t const & value)
|
||||||
uint512_union (nano::uint512_t const &);
|
{
|
||||||
bool operator== (nano::uint512_union const &) const;
|
bytes.fill (0);
|
||||||
bool operator!= (nano::uint512_union const &) const;
|
boost::multiprecision::export_bits (value, bytes.rbegin (), 8, false);
|
||||||
nano::uint512_union & operator^= (nano::uint512_union const &);
|
}
|
||||||
|
uint512_union (nano::uint256_union const & upper, nano::uint256_union const & lower) :
|
||||||
|
uint256s{ upper, lower } {};
|
||||||
|
|
||||||
|
nano::uint512_union & operator^= (nano::uint512_union const & other)
|
||||||
|
{
|
||||||
|
uint256s[0] ^= other.uint256s[0];
|
||||||
|
uint256s[1] ^= other.uint256s[1];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void encode_hex (std::string &) const;
|
void encode_hex (std::string &) const;
|
||||||
bool decode_hex (std::string const &);
|
bool decode_hex (std::string const &);
|
||||||
void clear ();
|
|
||||||
bool is_zero () const;
|
void clear ()
|
||||||
nano::uint512_t number () const;
|
{
|
||||||
|
bytes.fill (0);
|
||||||
|
}
|
||||||
|
bool is_zero () const
|
||||||
|
{
|
||||||
|
return uint256s[0].is_zero () && uint256s[1].is_zero ();
|
||||||
|
}
|
||||||
|
|
||||||
|
nano::uint512_t number () const
|
||||||
|
{
|
||||||
|
nano::uint512_t result;
|
||||||
|
boost::multiprecision::import_bits (result, bytes.begin (), bytes.end ());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string to_string () const;
|
std::string to_string () const;
|
||||||
|
|
||||||
|
public:
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 64> bytes;
|
std::array<uint8_t, 64> bytes;
|
||||||
|
|
@ -236,6 +432,24 @@ public:
|
||||||
std::array<uint64_t, 8> qwords;
|
std::array<uint64_t, 8> qwords;
|
||||||
std::array<uint256_union, 2> uint256s;
|
std::array<uint256_union, 2> uint256s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public: // Keep operators inlined
|
||||||
|
std::strong_ordering operator<=> (nano::uint512_union const & other) const
|
||||||
|
{
|
||||||
|
return std::memcmp (bytes.data (), other.bytes.data (), 64) <=> 0;
|
||||||
|
};
|
||||||
|
bool operator== (nano::uint512_union const & other) const
|
||||||
|
{
|
||||||
|
return *this <=> other == 0;
|
||||||
|
}
|
||||||
|
operator nano::uint512_t () const
|
||||||
|
{
|
||||||
|
return number ();
|
||||||
|
}
|
||||||
|
uint512_union const & as_union () const
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert (std::is_nothrow_move_constructible<uint512_union>::value, "uint512_union should be noexcept MoveConstructible");
|
static_assert (std::is_nothrow_move_constructible<uint512_union>::value, "uint512_union should be noexcept MoveConstructible");
|
||||||
|
|
||||||
|
|
@ -248,15 +462,19 @@ public:
|
||||||
class qualified_root : public uint512_union
|
class qualified_root : public uint512_union
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using uint512_union::uint512_union;
|
qualified_root () = default;
|
||||||
|
qualified_root (nano::root const & root, nano::block_hash const & previous) :
|
||||||
|
uint512_union{ root.as_union (), previous.as_union () } {};
|
||||||
|
qualified_root (nano::uint512_t const & value) :
|
||||||
|
uint512_union{ value } {};
|
||||||
|
|
||||||
nano::root const & root () const
|
nano::root root () const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<nano::root const &> (uint256s[0]);
|
return nano::root{ uint256s[0] };
|
||||||
}
|
}
|
||||||
nano::block_hash const & previous () const
|
nano::block_hash previous () const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<nano::block_hash const &> (uint256s[1]);
|
return nano::block_hash{ uint256s[1] };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -276,6 +494,7 @@ bool from_string_hex (std::string const &, uint64_t &);
|
||||||
std::ostream & operator<< (std::ostream &, const uint128_union &);
|
std::ostream & operator<< (std::ostream &, const uint128_union &);
|
||||||
std::ostream & operator<< (std::ostream &, const uint256_union &);
|
std::ostream & operator<< (std::ostream &, const uint256_union &);
|
||||||
std::ostream & operator<< (std::ostream &, const uint512_union &);
|
std::ostream & operator<< (std::ostream &, const uint512_union &);
|
||||||
|
std::ostream & operator<< (std::ostream &, const hash_or_account &);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a double to string in fixed format
|
* Convert a double to string in fixed format
|
||||||
|
|
@ -297,92 +516,91 @@ namespace difficulty
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::uint256_union>
|
struct hash<::nano::uint128_union>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::uint256_union const & data_a) const
|
size_t operator() (::nano::uint128_union const & value) const noexcept
|
||||||
{
|
{
|
||||||
return data_a.qwords[0] + data_a.qwords[1] + data_a.qwords[2] + data_a.qwords[3];
|
return value.qwords[0] + value.qwords[1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::account>
|
struct hash<::nano::uint256_union>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::account const & data_a) const
|
size_t operator() (::nano::uint256_union const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::uint256_union> () (data_a);
|
return value.qwords[0] + value.qwords[1] + value.qwords[2] + value.qwords[3];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::public_key>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::public_key const & value) const noexcept
|
||||||
|
{
|
||||||
|
return hash<::nano::uint256_union>{}(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::block_hash>
|
struct hash<::nano::block_hash>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::block_hash const & data_a) const
|
size_t operator() (::nano::block_hash const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::uint256_union> () (data_a);
|
return hash<::nano::uint256_union>{}(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::hash_or_account>
|
struct hash<::nano::hash_or_account>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::hash_or_account const & data_a) const
|
size_t operator() (::nano::hash_or_account const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::block_hash> () (data_a.as_block_hash ());
|
return hash<::nano::block_hash>{}(value.as_block_hash ());
|
||||||
}
|
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::raw_key>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::raw_key const & data_a) const
|
|
||||||
{
|
|
||||||
return hash<::nano::uint256_union> () (data_a);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::root>
|
struct hash<::nano::root>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::root const & data_a) const
|
size_t operator() (::nano::root const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::uint256_union> () (data_a);
|
return hash<::nano::hash_or_account>{}(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::link>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::link const & value) const noexcept
|
||||||
|
{
|
||||||
|
return hash<::nano::hash_or_account>{}(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::raw_key>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::raw_key const & value) const noexcept
|
||||||
|
{
|
||||||
|
return hash<::nano::uint256_union>{}(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::wallet_id>
|
struct hash<::nano::wallet_id>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::wallet_id const & data_a) const
|
size_t operator() (::nano::wallet_id const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::uint256_union> () (data_a);
|
return hash<::nano::uint256_union>{}(value);
|
||||||
}
|
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::uint256_t>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::uint256_t const & number_a) const
|
|
||||||
{
|
|
||||||
return number_a.convert_to<size_t> ();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::uint512_union>
|
struct hash<::nano::uint512_union>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::uint512_union const & data_a) const
|
size_t operator() (::nano::uint512_union const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::uint256_union> () (data_a.uint256s[0]) + hash<::nano::uint256_union> () (data_a.uint256s[1]);
|
return hash<::nano::uint256_union>{}(value.uint256s[0]) + hash<::nano::uint256_union> () (value.uint256s[1]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::qualified_root>
|
struct hash<::nano::qualified_root>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::qualified_root const & data_a) const
|
size_t operator() (::nano::qualified_root const & value) const noexcept
|
||||||
{
|
{
|
||||||
return hash<::nano::uint512_union> () (data_a);
|
return hash<::nano::uint512_union>{}(value);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct equal_to<std::reference_wrapper<::nano::block_hash const>>
|
|
||||||
{
|
|
||||||
bool operator() (std::reference_wrapper<::nano::block_hash const> const & lhs, std::reference_wrapper<::nano::block_hash const> const & rhs) const
|
|
||||||
{
|
|
||||||
return lhs.get () == rhs.get ();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -390,20 +608,91 @@ struct equal_to<std::reference_wrapper<::nano::block_hash const>>
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
template <>
|
template <>
|
||||||
struct hash<std::reference_wrapper<::nano::block_hash const>>
|
struct hash<::nano::uint128_union>
|
||||||
{
|
{
|
||||||
size_t operator() (std::reference_wrapper<::nano::block_hash const> const & hash_a) const
|
size_t operator() (::nano::uint128_union const & value) const noexcept
|
||||||
{
|
{
|
||||||
std::hash<::nano::block_hash> hash;
|
return std::hash<::nano::uint128_union> () (value);
|
||||||
return hash (hash_a);
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::uint256_union>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::uint256_union const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::uint256_union> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::public_key>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::public_key const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::public_key> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::block_hash>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::block_hash const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::block_hash> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::hash_or_account>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::hash_or_account const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::hash_or_account> () (value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::root>
|
struct hash<::nano::root>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::root const & value_a) const
|
size_t operator() (::nano::root const & value) const noexcept
|
||||||
{
|
{
|
||||||
return std::hash<::nano::root> () (value_a);
|
return std::hash<::nano::root> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::link>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::link const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::link> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::raw_key>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::raw_key const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::raw_key> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::wallet_id>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::wallet_id const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::wallet_id> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::uint512_union>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::uint512_union const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::uint512_union> () (value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct hash<::nano::qualified_root>
|
||||||
|
{
|
||||||
|
size_t operator() (::nano::qualified_root const & value) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<::nano::qualified_root> () (value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -427,6 +716,11 @@ struct fmt::formatter<nano::uint512_union> : fmt::ostream_formatter
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct fmt::formatter<nano::hash_or_account> : fmt::ostream_formatter
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<nano::block_hash> : fmt::formatter<nano::uint256_union>
|
struct fmt::formatter<nano::block_hash> : fmt::formatter<nano::uint256_union>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ void nano::pulls_cache::add (nano::pull_info const & pull_a)
|
||||||
cache.erase (cache.begin ());
|
cache.erase (cache.begin ());
|
||||||
}
|
}
|
||||||
debug_assert (cache.size () <= cache_size_max);
|
debug_assert (cache.size () <= cache_size_max);
|
||||||
nano::uint512_union head_512 (pull_a.account_or_head, pull_a.head_original);
|
nano::uint512_union head_512 (pull_a.account_or_head.as_union (), pull_a.head_original);
|
||||||
auto existing (cache.get<account_head_tag> ().find (head_512));
|
auto existing (cache.get<account_head_tag> ().find (head_512));
|
||||||
if (existing == cache.get<account_head_tag> ().end ())
|
if (existing == cache.get<account_head_tag> ().end ())
|
||||||
{
|
{
|
||||||
|
|
@ -336,7 +336,7 @@ void nano::pulls_cache::add (nano::pull_info const & pull_a)
|
||||||
void nano::pulls_cache::update_pull (nano::pull_info & pull_a)
|
void nano::pulls_cache::update_pull (nano::pull_info & pull_a)
|
||||||
{
|
{
|
||||||
nano::lock_guard<nano::mutex> guard{ pulls_cache_mutex };
|
nano::lock_guard<nano::mutex> guard{ pulls_cache_mutex };
|
||||||
nano::uint512_union head_512 (pull_a.account_or_head, pull_a.head_original);
|
nano::uint512_union head_512 (pull_a.account_or_head.as_union (), pull_a.head_original);
|
||||||
auto existing (cache.get<account_head_tag> ().find (head_512));
|
auto existing (cache.get<account_head_tag> ().find (head_512));
|
||||||
if (existing != cache.get<account_head_tag> ().end ())
|
if (existing != cache.get<account_head_tag> ().end ())
|
||||||
{
|
{
|
||||||
|
|
@ -347,7 +347,7 @@ void nano::pulls_cache::update_pull (nano::pull_info & pull_a)
|
||||||
void nano::pulls_cache::remove (nano::pull_info const & pull_a)
|
void nano::pulls_cache::remove (nano::pull_info const & pull_a)
|
||||||
{
|
{
|
||||||
nano::lock_guard<nano::mutex> guard{ pulls_cache_mutex };
|
nano::lock_guard<nano::mutex> guard{ pulls_cache_mutex };
|
||||||
nano::uint512_union head_512 (pull_a.account_or_head, pull_a.head_original);
|
nano::uint512_union head_512 (pull_a.account_or_head.as_union (), pull_a.head_original);
|
||||||
cache.get<account_head_tag> ().erase (head_512);
|
cache.get<account_head_tag> ().erase (head_512);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code ec, std::
|
||||||
// Is block expected?
|
// Is block expected?
|
||||||
bool block_expected (false);
|
bool block_expected (false);
|
||||||
// Unconfirmed head is used only for lazy destinations if legacy bootstrap is not available, see nano::bootstrap_attempt::lazy_destinations_increment (...)
|
// Unconfirmed head is used only for lazy destinations if legacy bootstrap is not available, see nano::bootstrap_attempt::lazy_destinations_increment (...)
|
||||||
bool unconfirmed_account_head = node->flags.disable_legacy_bootstrap && pull_blocks == 0 && pull.retry_limit <= node->network_params.bootstrap.lazy_retry_limit && (expected == pull.account_or_head.as_block_hash ()) && (block->account_field () == pull.account_or_head.as_account ());
|
bool unconfirmed_account_head = node->flags.disable_legacy_bootstrap && pull_blocks == 0 && pull.retry_limit <= node->network_params.bootstrap.lazy_retry_limit && (expected == pull.account_or_head.as_block_hash ()) && (block->account_field ().value_or (0) == pull.account_or_head.as_account ());
|
||||||
if (hash == expected || unconfirmed_account_head)
|
if (hash == expected || unconfirmed_account_head)
|
||||||
{
|
{
|
||||||
expected = block->previous ();
|
expected = block->previous ();
|
||||||
|
|
@ -394,7 +394,7 @@ void nano::bulk_pull_server::set_current_end ()
|
||||||
if (!request->end.is_zero ())
|
if (!request->end.is_zero ())
|
||||||
{
|
{
|
||||||
auto account (node->ledger.any.block_account (transaction, request->end));
|
auto account (node->ledger.any.block_account (transaction, request->end));
|
||||||
if (account != request->start.as_account ())
|
if (account.value_or (0) != request->start.as_account ())
|
||||||
{
|
{
|
||||||
node->logger.debug (nano::log::type::bulk_pull_server, "Request for block that is not on account chain: {} not on {}", request->end.to_string (), request->start.to_account ());
|
node->logger.debug (nano::log::type::bulk_pull_server, "Request for block that is not on account chain: {} not on {}", request->end.to_string (), request->start.to_account ());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ void nano::frontier_req_client::run (nano::account const & start_account_a, uint
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nano::frontier_req request{ node->network_params.network };
|
nano::frontier_req request{ node->network_params.network };
|
||||||
request.start = (start_account_a.is_zero () || start_account_a.number () == std::numeric_limits<nano::uint256_t>::max ()) ? start_account_a : start_account_a.number () + 1;
|
request.start = (start_account_a.is_zero () || start_account_a.number () == std::numeric_limits<nano::uint256_t>::max ()) ? start_account_a.number () : start_account_a.number () + 1;
|
||||||
request.age = frontiers_age_a;
|
request.age = frontiers_age_a;
|
||||||
request.count = count_a;
|
request.count = count_a;
|
||||||
current = start_account_a;
|
current = start_account_a;
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ bool nano::bootstrap_attempt_lazy::process_block_lazy (std::shared_ptr<nano::blo
|
||||||
if (!lazy_blocks_processed (hash))
|
if (!lazy_blocks_processed (hash))
|
||||||
{
|
{
|
||||||
// Search for new dependencies
|
// Search for new dependencies
|
||||||
if (block_a->source_field () && !node->block_or_pruned_exists (block_a->source_field ().value ()) && block_a->source_field ().value () != node->network_params.ledger.genesis->account ())
|
if (block_a->source_field () && !node->block_or_pruned_exists (block_a->source_field ().value ()) && block_a->source_field ().value () != node->network_params.ledger.genesis->account ().as_union ())
|
||||||
{
|
{
|
||||||
lazy_add (block_a->source_field ().value (), retry_limit);
|
lazy_add (block_a->source_field ().value (), retry_limit);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -789,7 +789,7 @@ nano::bootstrap_ascending::service::verify_result nano::bootstrap_ascending::ser
|
||||||
case query_type::blocks_by_account:
|
case query_type::blocks_by_account:
|
||||||
{
|
{
|
||||||
// Open & state blocks always contain account field
|
// Open & state blocks always contain account field
|
||||||
if (first->account_field () != tag.start.as_account ())
|
if (first->account_field ().value_or (0) != tag.start.as_account ())
|
||||||
{
|
{
|
||||||
// TODO: Stat & log
|
// TODO: Stat & log
|
||||||
return verify_result::invalid;
|
return verify_result::invalid;
|
||||||
|
|
|
||||||
|
|
@ -2462,7 +2462,7 @@ public:
|
||||||
// Report opens as a receive
|
// Report opens as a receive
|
||||||
tree.put ("type", "receive");
|
tree.put ("type", "receive");
|
||||||
}
|
}
|
||||||
if (block_a.hashables.source != handler.node.ledger.constants.genesis->account ())
|
if (block_a.hashables.source != handler.node.ledger.constants.genesis->account ().as_union ())
|
||||||
{
|
{
|
||||||
bool error_or_pruned (false);
|
bool error_or_pruned (false);
|
||||||
auto amount = handler.node.ledger.any.block_amount (transaction, hash);
|
auto amount = handler.node.ledger.any.block_amount (transaction, hash);
|
||||||
|
|
|
||||||
|
|
@ -555,7 +555,7 @@ public:
|
||||||
void open_block (nano::open_block const & block_a)
|
void open_block (nano::open_block const & block_a)
|
||||||
{
|
{
|
||||||
type = "Receive";
|
type = "Receive";
|
||||||
if (block_a.hashables.source != ledger.constants.genesis->account ())
|
if (block_a.hashables.source != ledger.constants.genesis->account ().as_union ())
|
||||||
{
|
{
|
||||||
auto account_l = ledger.any.block_account (transaction, block_a.hashables.source);
|
auto account_l = ledger.any.block_account (transaction, block_a.hashables.source);
|
||||||
auto amount_l = ledger.any.block_amount (transaction, block_a.hash ());
|
auto amount_l = ledger.any.block_amount (transaction, block_a.hash ());
|
||||||
|
|
|
||||||
|
|
@ -2628,7 +2628,7 @@ TEST (rpc, wallet_frontiers)
|
||||||
frontiers.push_back (nano::account (i->second.get<std::string> ("")));
|
frontiers.push_back (nano::account (i->second.get<std::string> ("")));
|
||||||
}
|
}
|
||||||
ASSERT_EQ (1, frontiers.size ());
|
ASSERT_EQ (1, frontiers.size ());
|
||||||
ASSERT_EQ (node->latest (nano::dev::genesis_key.pub), frontiers[0]);
|
ASSERT_EQ (node->latest (nano::dev::genesis_key.pub), frontiers[0].as_union ());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST (rpc, work_validate)
|
TEST (rpc, work_validate)
|
||||||
|
|
|
||||||
|
|
@ -21,61 +21,6 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::uint256_union>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::uint256_union const & value_a) const
|
|
||||||
{
|
|
||||||
return std::hash<::nano::uint256_union> () (value_a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::block_hash>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::block_hash const & value_a) const
|
|
||||||
{
|
|
||||||
return std::hash<::nano::block_hash> () (value_a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::hash_or_account>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::hash_or_account const & data_a) const
|
|
||||||
{
|
|
||||||
return std::hash<::nano::hash_or_account> () (data_a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::public_key>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::public_key const & value_a) const
|
|
||||||
{
|
|
||||||
return std::hash<::nano::public_key> () (value_a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::uint512_union>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::uint512_union const & value_a) const
|
|
||||||
{
|
|
||||||
return std::hash<::nano::uint512_union> () (value_a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct hash<::nano::qualified_root>
|
|
||||||
{
|
|
||||||
size_t operator() (::nano::qualified_root const & value_a) const
|
|
||||||
{
|
|
||||||
return std::hash<::nano::qualified_root> () (value_a);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace nano
|
namespace nano
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1093,7 +1093,7 @@ public:
|
||||||
}
|
}
|
||||||
void open_block (nano::open_block const & block_a) override
|
void open_block (nano::open_block const & block_a) override
|
||||||
{
|
{
|
||||||
if (block_a.source_field ().value () != ledger.constants.genesis->account ())
|
if (block_a.source_field ().value () != ledger.constants.genesis->account ().as_union ())
|
||||||
{
|
{
|
||||||
result[0] = block_a.source_field ().value ();
|
result[0] = block_a.source_field ().value ();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,9 +67,9 @@ namespace std
|
||||||
template <>
|
template <>
|
||||||
struct hash<::nano::pending_key>
|
struct hash<::nano::pending_key>
|
||||||
{
|
{
|
||||||
size_t operator() (::nano::pending_key const & data_a) const
|
size_t operator() (::nano::pending_key const & value) const
|
||||||
{
|
{
|
||||||
return hash<::nano::uint512_union>{}({ ::nano::uint256_union{ data_a.account.number () }, data_a.hash });
|
return hash<::nano::uint512_union>{}({ ::nano::uint256_union{ value.account.number () }, value.hash });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue