Use spaceship comparisons
This commit is contained in:
parent
7f5c394ca5
commit
aefd7c18fb
11 changed files with 160 additions and 125 deletions
|
|
@ -2406,7 +2406,7 @@ TEST (ledger, state_account)
|
|||
.work (*pool.generate (nano::dev::genesis->hash ()))
|
||||
.build ();
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -286,11 +286,6 @@ 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;
|
||||
|
|
@ -355,11 +350,6 @@ bool nano::uint512_union::decode_hex (std::string const & text)
|
|||
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];
|
||||
|
|
@ -446,26 +436,6 @@ nano::uint128_union::uint128_union (nano::uint128_t const & number_a)
|
|||
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;
|
||||
|
|
@ -811,36 +781,11 @@ std::string nano::hash_or_account::to_account () const
|
|||
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::stringstream stream;
|
||||
|
|
@ -963,16 +908,6 @@ 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);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <compare>
|
||||
#include <ostream>
|
||||
|
||||
#include <fmt/ostream.h>
|
||||
|
|
@ -23,29 +24,32 @@ class uint128_union
|
|||
{
|
||||
public:
|
||||
uint128_union () = default;
|
||||
uint128_union (uint64_t);
|
||||
uint128_union (nano::uint128_t const &);
|
||||
|
||||
/**
|
||||
* Decode from hex string
|
||||
* @warning Aborts at runtime if the input is invalid
|
||||
*/
|
||||
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;
|
||||
explicit uint128_union (std::string const &);
|
||||
|
||||
void encode_hex (std::string &) const;
|
||||
bool decode_hex (std::string const &);
|
||||
void encode_dec (std::string &) const;
|
||||
bool decode_dec (std::string const &, bool = false);
|
||||
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, std::locale const & locale) const;
|
||||
|
||||
nano::uint128_t number () const;
|
||||
void clear ();
|
||||
bool is_zero () const;
|
||||
|
||||
std::string to_string () const;
|
||||
std::string to_string_dec () const;
|
||||
|
||||
public:
|
||||
union
|
||||
{
|
||||
std::array<uint8_t, 16> bytes;
|
||||
|
|
@ -53,6 +57,24 @@ public:
|
|||
std::array<uint32_t, 4> dwords;
|
||||
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");
|
||||
|
||||
|
|
@ -62,37 +84,48 @@ class amount : public uint128_union
|
|||
public:
|
||||
using uint128_union::uint128_union;
|
||||
|
||||
auto operator<=> (nano::amount const & other) const
|
||||
{
|
||||
return uint128_union::operator<=> (other);
|
||||
}
|
||||
operator nano::uint128_t () const
|
||||
{
|
||||
return number ();
|
||||
}
|
||||
};
|
||||
|
||||
class raw_key;
|
||||
|
||||
class uint256_union
|
||||
{
|
||||
public:
|
||||
uint256_union () = default;
|
||||
uint256_union (uint64_t);
|
||||
uint256_union (uint256_t const &);
|
||||
|
||||
/**
|
||||
* Decode from hex string
|
||||
* @warning Aborts at runtime if the input is invalid
|
||||
*/
|
||||
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 &);
|
||||
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;
|
||||
bool decode_hex (std::string const &);
|
||||
void encode_dec (std::string &) const;
|
||||
bool decode_dec (std::string const &);
|
||||
|
||||
nano::uint256_t number () const;
|
||||
void clear ();
|
||||
bool is_zero () const;
|
||||
std::string to_string () const;
|
||||
nano::uint256_t number () const;
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
public:
|
||||
union
|
||||
{
|
||||
std::array<uint8_t, 32> bytes;
|
||||
|
|
@ -101,23 +134,25 @@ public:
|
|||
std::array<uint64_t, 4> qwords;
|
||||
std::array<uint128_union, 2> owords;
|
||||
};
|
||||
|
||||
public: // Keep operators inlined
|
||||
std::strong_ordering operator<=> (nano::uint256_union const & other) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
|
@ -129,9 +164,24 @@ class block_hash final : public uint256_union
|
|||
{
|
||||
public:
|
||||
using uint256_union::uint256_union;
|
||||
|
||||
operator nano::link const & () const;
|
||||
operator nano::root const & () const;
|
||||
operator nano::hash_or_account const & () const;
|
||||
|
||||
public: // Keep operators inlined
|
||||
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
|
||||
|
|
@ -152,8 +202,24 @@ public:
|
|||
operator nano::link const & () const;
|
||||
operator nano::root const & () const;
|
||||
operator nano::hash_or_account const & () const;
|
||||
bool operator== (std::nullptr_t) const;
|
||||
bool operator!= (std::nullptr_t) const;
|
||||
|
||||
public: // Keep operators inlined
|
||||
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
|
||||
|
|
@ -172,19 +238,13 @@ public:
|
|||
|
||||
bool is_zero () const;
|
||||
void clear ();
|
||||
|
||||
std::string to_string () const;
|
||||
bool decode_hex (std::string const &);
|
||||
bool decode_account (std::string const &);
|
||||
std::string to_account () const;
|
||||
|
||||
nano::account const & as_account () const;
|
||||
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;
|
||||
|
||||
public:
|
||||
union
|
||||
{
|
||||
std::array<uint8_t, 32> bytes;
|
||||
|
|
@ -192,6 +252,32 @@ public:
|
|||
nano::account account;
|
||||
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;
|
||||
}
|
||||
operator nano::uint256_t () const
|
||||
{
|
||||
return raw.number ();
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// A link can either be a destination account or source hash
|
||||
|
|
@ -218,22 +304,27 @@ public:
|
|||
~raw_key ();
|
||||
void decrypt (nano::uint256_union const &, nano::raw_key const &, uint128_union const &);
|
||||
};
|
||||
|
||||
class uint512_union
|
||||
{
|
||||
public:
|
||||
uint512_union () = default;
|
||||
uint512_union (nano::uint256_union const &, nano::uint256_union const &);
|
||||
uint512_union (nano::uint512_t const &);
|
||||
bool operator== (nano::uint512_union const &) const;
|
||||
bool operator!= (nano::uint512_union const &) const;
|
||||
|
||||
nano::uint512_union & operator^= (nano::uint512_union const &);
|
||||
|
||||
void encode_hex (std::string &) const;
|
||||
bool decode_hex (std::string const &);
|
||||
|
||||
void clear ();
|
||||
bool is_zero () const;
|
||||
|
||||
nano::uint512_t number () const;
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
public:
|
||||
union
|
||||
{
|
||||
std::array<uint8_t, 64> bytes;
|
||||
|
|
@ -241,6 +332,24 @@ public:
|
|||
std::array<uint64_t, 8> qwords;
|
||||
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");
|
||||
|
||||
|
|
@ -381,15 +490,6 @@ struct hash<::nano::qualified_root>
|
|||
return hash<::nano::uint512_union> () (data_a);
|
||||
}
|
||||
};
|
||||
|
||||
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 ();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace boost
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ void nano::bulk_pull_client::received_block (boost::system::error_code ec, std::
|
|||
// Is block expected?
|
||||
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 (...)
|
||||
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)
|
||||
{
|
||||
expected = block->previous ();
|
||||
|
|
@ -394,7 +394,7 @@ void nano::bulk_pull_server::set_current_end ()
|
|||
if (!request->end.is_zero ())
|
||||
{
|
||||
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 ());
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void nano::frontier_req_client::run (nano::account const & start_account_a, uint
|
|||
return;
|
||||
}
|
||||
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.count = count_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))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -789,7 +789,7 @@ nano::bootstrap_ascending::service::verify_result nano::bootstrap_ascending::ser
|
|||
case query_type::blocks_by_account:
|
||||
{
|
||||
// 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
|
||||
return verify_result::invalid;
|
||||
|
|
|
|||
|
|
@ -2462,7 +2462,7 @@ public:
|
|||
// Report opens as a 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);
|
||||
auto amount = handler.node.ledger.any.block_amount (transaction, hash);
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ public:
|
|||
void open_block (nano::open_block const & block_a)
|
||||
{
|
||||
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 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> ("")));
|
||||
}
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -1093,7 +1093,7 @@ public:
|
|||
}
|
||||
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 ();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue