mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
Modernize base_uint:
* Add construction and assignment from a generic contiguous container. Both compile-time and run time safety checks are made to ensure the safety of this conversion. * Remove base_uint::copyFrom. The generic copy assignment operator now does this functionality with enhanced safety and better syntax. * Remove construction from and dedendence on Blob. The generic constructor and assignment now handle this functionality. * Fix client code to adhere to this new API. * Removed the use of fromVoid in PeerImp.cpp as it was an inappropriate use of this dangerous API. The generic container constructors do it with enhanced safety and better syntax. * Rename data member pn to data_ and make it private. * Remove constraint from hash_append * Remove array_type alias
This commit is contained in:
committed by
Manoj doshi
parent
de99e79bf1
commit
773dcd1d48
@@ -114,14 +114,10 @@ void OrderBookDB::update(
|
||||
sle->getFieldH256 (sfRootIndex) == sle->key())
|
||||
{
|
||||
Book book;
|
||||
book.in.currency.copyFrom(sle->getFieldH160(
|
||||
sfTakerPaysCurrency));
|
||||
book.in.account.copyFrom(sle->getFieldH160 (
|
||||
sfTakerPaysIssuer));
|
||||
book.out.account.copyFrom(sle->getFieldH160(
|
||||
sfTakerGetsIssuer));
|
||||
book.out.currency.copyFrom (sle->getFieldH160(
|
||||
sfTakerGetsCurrency));
|
||||
book.in.currency = sle->getFieldH160(sfTakerPaysCurrency);
|
||||
book.in.account = sle->getFieldH160(sfTakerPaysIssuer);
|
||||
book.out.account = sle->getFieldH160(sfTakerGetsIssuer);
|
||||
book.out.currency = sle->getFieldH160(sfTakerGetsCurrency);
|
||||
|
||||
uint256 index = getBookBase (book);
|
||||
if (seen.insert (index).second)
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
void restart (bool multiQuality)
|
||||
{
|
||||
if (multiQuality)
|
||||
current = 0; // Restart book searching.
|
||||
current = beast::zero; // Restart book searching.
|
||||
else
|
||||
restartNeeded = true; // Restart at same quality.
|
||||
}
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
if (current != beast::zero)
|
||||
return false;
|
||||
|
||||
current.copyFrom (getBookBase (book));
|
||||
next.copyFrom (getQualityNext (current));
|
||||
current = getBookBase(book);
|
||||
next = getQualityNext(current);
|
||||
|
||||
// TODO(tom): it seems impossible that any actual offers with
|
||||
// quality == 0 could occur - we should disallow them, and clear
|
||||
|
||||
@@ -89,7 +89,7 @@ TER PathCursor::advanceNode (bool const bReverse) const
|
||||
JLOG (j_.trace())
|
||||
<< "advanceNode: No more offers.";
|
||||
|
||||
node().offerIndex_ = 0;
|
||||
node().offerIndex_ = beast::zero;
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -177,7 +177,7 @@ TER PathCursor::advanceNode (bool const bReverse) const
|
||||
{
|
||||
// Ran off end of offers.
|
||||
node().bEntryAdvance = false; // Done.
|
||||
node().offerIndex_ = 0; // Report no more entries.
|
||||
node().offerIndex_ = beast::zero; // Report no more entries.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
#ifndef RIPPLE_BASICS_BASE_UINT_H_INCLUDED
|
||||
#define RIPPLE_BASICS_BASE_UINT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/basics/strHex.h>
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <ripple/beast/cxx17/type_traits.h>
|
||||
#include <ripple/beast/utility/Zero.h>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
@@ -37,6 +37,27 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class Container, class = std::void_t<>>
|
||||
struct is_contiguous_container
|
||||
: std::false_type
|
||||
{};
|
||||
|
||||
template <class Container>
|
||||
struct is_contiguous_container<Container,
|
||||
std::void_t
|
||||
<
|
||||
decltype(std::declval<Container const>().size()),
|
||||
decltype(std::declval<Container const>().data()),
|
||||
typename Container::value_type
|
||||
>>
|
||||
: std::true_type
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// This class stores its values internally in big-endian form
|
||||
|
||||
template <std::size_t Bits, class Tag = void>
|
||||
@@ -48,14 +69,12 @@ class base_uint
|
||||
static_assert (Bits >= 64,
|
||||
"The length of a base_uint in bits must be at least 64.");
|
||||
|
||||
protected:
|
||||
static constexpr std::size_t WIDTH = Bits / 32;
|
||||
|
||||
// This is really big-endian in byte order.
|
||||
// We sometimes use std::uint32_t for speed.
|
||||
|
||||
using array_type = std::array<std::uint32_t, WIDTH>;
|
||||
array_type pn;
|
||||
std::array<std::uint32_t, WIDTH> data_;
|
||||
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -64,7 +83,7 @@ public:
|
||||
//
|
||||
|
||||
static std::size_t constexpr bytes = Bits / 8;
|
||||
static_assert(sizeof(array_type) == bytes, "");
|
||||
static_assert(sizeof(data_) == bytes, "");
|
||||
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
@@ -79,8 +98,8 @@ public:
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
using tag_type = Tag;
|
||||
|
||||
pointer data() { return reinterpret_cast<pointer>(pn.data ()); }
|
||||
const_pointer data() const { return reinterpret_cast<const_pointer>(pn.data ()); }
|
||||
pointer data() { return reinterpret_cast<pointer>(data_.data ()); }
|
||||
const_pointer data() const { return reinterpret_cast<const_pointer>(data_.data ()); }
|
||||
|
||||
|
||||
iterator begin() { return data(); }
|
||||
@@ -112,7 +131,7 @@ private:
|
||||
|
||||
explicit base_uint (void const* data, VoidHelper)
|
||||
{
|
||||
memcpy (pn.data (), data, bytes);
|
||||
memcpy (data_.data (), data, bytes);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -126,25 +145,35 @@ public:
|
||||
*this = beast::zero;
|
||||
}
|
||||
|
||||
explicit base_uint (Blob const& vch)
|
||||
{
|
||||
assert (vch.size () == size ());
|
||||
|
||||
if (vch.size () == size ())
|
||||
memcpy (pn.data (), vch.data (), size ());
|
||||
else
|
||||
*this = beast::zero;
|
||||
}
|
||||
|
||||
explicit base_uint (std::uint64_t b)
|
||||
{
|
||||
*this = b;
|
||||
}
|
||||
|
||||
template <class OtherTag>
|
||||
void copyFrom (base_uint<Bits, OtherTag> const& other)
|
||||
template <class Container,
|
||||
class = std::enable_if_t
|
||||
<
|
||||
detail::is_contiguous_container<Container>::value &&
|
||||
std::is_trivially_copyable<typename Container::value_type>::value
|
||||
>>
|
||||
explicit base_uint(Container const& c)
|
||||
{
|
||||
memcpy (pn.data (), other.data(), bytes);
|
||||
assert(c.size()*sizeof(typename Container::value_type) == size());
|
||||
std::memcpy(data_.data(), c.data(), size());
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
std::enable_if_t
|
||||
<
|
||||
detail::is_contiguous_container<Container>::value &&
|
||||
std::is_trivially_copyable<typename Container::value_type>::value,
|
||||
base_uint&
|
||||
>
|
||||
operator=(Container const& c)
|
||||
{
|
||||
assert(c.size()*sizeof(typename Container::value_type) == size());
|
||||
std::memcpy(data_.data(), c.data(), size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Construct from a raw pointer.
|
||||
@@ -159,7 +188,7 @@ public:
|
||||
int signum() const
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
if (pn[i] != 0)
|
||||
if (data_[i] != 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -175,7 +204,7 @@ public:
|
||||
base_uint ret;
|
||||
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
ret.pn[i] = ~pn[i];
|
||||
ret.data_[i] = ~data_[i];
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -190,15 +219,15 @@ public:
|
||||
};
|
||||
// Put in least significant bits.
|
||||
ul = boost::endian::native_to_big(uHost);
|
||||
pn[WIDTH-2] = u[0];
|
||||
pn[WIDTH-1] = u[1];
|
||||
data_[WIDTH-2] = u[0];
|
||||
data_[WIDTH-1] = u[1];
|
||||
return *this;
|
||||
}
|
||||
|
||||
base_uint& operator^= (const base_uint& b)
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
pn[i] ^= b.pn[i];
|
||||
data_[i] ^= b.data_[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -206,7 +235,7 @@ public:
|
||||
base_uint& operator&= (const base_uint& b)
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
pn[i] &= b.pn[i];
|
||||
data_[i] &= b.data_[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -214,7 +243,7 @@ public:
|
||||
base_uint& operator|= (const base_uint& b)
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
pn[i] |= b.pn[i];
|
||||
data_[i] |= b.data_[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -224,9 +253,9 @@ public:
|
||||
// prefix operator
|
||||
for (int i = WIDTH - 1; i >= 0; --i)
|
||||
{
|
||||
pn[i] = boost::endian::native_to_big (boost::endian::big_to_native(pn[i]) + 1);
|
||||
|
||||
if (pn[i] != 0)
|
||||
data_[i] = boost::endian::native_to_big
|
||||
(boost::endian::big_to_native(data_[i]) + 1);
|
||||
if (data_[i] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -246,8 +275,9 @@ public:
|
||||
{
|
||||
for (int i = WIDTH - 1; i >= 0; --i)
|
||||
{
|
||||
auto prev = pn[i];
|
||||
pn[i] = boost::endian::native_to_big (boost::endian::big_to_native(pn[i]) - 1);
|
||||
auto prev = data_[i];
|
||||
data_[i] =
|
||||
boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
|
||||
|
||||
if (prev != 0)
|
||||
break;
|
||||
@@ -271,23 +301,22 @@ public:
|
||||
|
||||
for (int i = WIDTH; i--;)
|
||||
{
|
||||
std::uint64_t n = carry + boost::endian::big_to_native(pn[i]) +
|
||||
boost::endian::big_to_native(b.pn[i]);
|
||||
std::uint64_t n = carry + boost::endian::big_to_native(data_[i]) +
|
||||
boost::endian::big_to_native(b.data_[i]);
|
||||
|
||||
pn[i] = boost::endian::native_to_big (static_cast<std::uint32_t>(n));
|
||||
data_[i] = boost::endian::native_to_big (static_cast<std::uint32_t>(n));
|
||||
carry = n >> 32;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Hasher,
|
||||
class = std::enable_if_t<Hasher::endian != beast::endian::native>>
|
||||
template <class Hasher>
|
||||
friend void hash_append(
|
||||
Hasher& h, base_uint const& a) noexcept
|
||||
{
|
||||
// Do not allow any endian transformations on this memory
|
||||
h(a.pn.data (), sizeof(a.pn));
|
||||
h(a.data_.data (), sizeof(a.data_));
|
||||
}
|
||||
|
||||
/** Parse a hex string into a base_uint
|
||||
@@ -298,7 +327,7 @@ public:
|
||||
{
|
||||
unsigned char* pOut = begin ();
|
||||
|
||||
for (int i = 0; i < sizeof (pn); ++i)
|
||||
for (int i = 0; i < sizeof (data_); ++i)
|
||||
{
|
||||
auto hi = charUnHex(*psz++);
|
||||
if (hi == -1)
|
||||
@@ -391,7 +420,7 @@ public:
|
||||
|
||||
base_uint<Bits, Tag>& operator=(beast::Zero)
|
||||
{
|
||||
pn.fill(0);
|
||||
data_.fill(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define RIPPLE_CRYPTO_GENERATEDETERMINISTICKEY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/Blob.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef RIPPLE_NODESTORE_NODEOBJECT_H_INCLUDED
|
||||
#define RIPPLE_NODESTORE_NODEOBJECT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/basics/CountedObject.h>
|
||||
#include <ripple/protocol/Protocol.h>
|
||||
|
||||
|
||||
@@ -1578,8 +1578,8 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
|
||||
return;
|
||||
}
|
||||
|
||||
auto const proposeHash = uint256::fromVoid(set.currenttxhash().data());
|
||||
auto const prevLedger = uint256::fromVoid(set.previousledger().data());
|
||||
uint256 const proposeHash{set.currenttxhash()};
|
||||
uint256 const prevLedger{set.previousledger()};
|
||||
|
||||
PublicKey const publicKey {makeSlice(set.nodepubkey())};
|
||||
NetClock::time_point const closeTime { NetClock::duration{set.closetime()} };
|
||||
|
||||
@@ -34,7 +34,7 @@ private:
|
||||
// But an STAccount is always 160 bits, so we can store it with less
|
||||
// overhead in a ripple::uint160. However, so the serialized format of the
|
||||
// STAccount stays unchanged, we serialize and deserialize like an STBlob.
|
||||
uint160 value_;
|
||||
AccountID value_;
|
||||
bool default_;
|
||||
|
||||
public:
|
||||
@@ -101,14 +101,12 @@ public:
|
||||
AccountID
|
||||
value() const noexcept
|
||||
{
|
||||
AccountID result;
|
||||
result.copyFrom (value_);
|
||||
return result;
|
||||
return value_;
|
||||
}
|
||||
|
||||
void setValue (AccountID const& v)
|
||||
{
|
||||
value_.copyFrom (v);
|
||||
value_ = v;
|
||||
default_ = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
template <typename Tag>
|
||||
void setValue (base_uint<Bits, Tag> const& v)
|
||||
{
|
||||
value_.copyFrom(v);
|
||||
value_ = v;
|
||||
}
|
||||
|
||||
value_type const&
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define RIPPLE_PROTOCOL_SERIALIZER_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/Buffer.h>
|
||||
#include <ripple/basics/safe_cast.h>
|
||||
|
||||
@@ -148,7 +148,7 @@ calcAccountID (PublicKey const& pk)
|
||||
AccountID const&
|
||||
xrpAccount()
|
||||
{
|
||||
static AccountID const account(0);
|
||||
static AccountID const account(beast::zero);
|
||||
return account;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,9 +60,9 @@ STAccount::STAccount (SerialIter& sit, SField const& name)
|
||||
|
||||
STAccount::STAccount (SField const& n, AccountID const& v)
|
||||
: STBase (n)
|
||||
, value_(v)
|
||||
, default_ (false)
|
||||
{
|
||||
value_.copyFrom (v);
|
||||
}
|
||||
|
||||
std::string STAccount::getText () const
|
||||
|
||||
@@ -106,12 +106,12 @@ STAmount::STAmount(SerialIter& sit, SField const& name)
|
||||
}
|
||||
|
||||
Issue issue;
|
||||
issue.currency.copyFrom (sit.get160 ());
|
||||
issue.currency = sit.get160();
|
||||
|
||||
if (isXRP (issue.currency))
|
||||
Throw<std::runtime_error> ("invalid native currency");
|
||||
|
||||
issue.account.copyFrom (sit.get160 ());
|
||||
issue.account = sit.get160();
|
||||
|
||||
if (isXRP (issue.account))
|
||||
Throw<std::runtime_error> ("invalid native account");
|
||||
|
||||
@@ -91,13 +91,13 @@ STPathSet::STPathSet (SerialIter& sit, SField const& name)
|
||||
AccountID issuer;
|
||||
|
||||
if (hasAccount)
|
||||
account.copyFrom (sit.get160 ());
|
||||
account = sit.get160();
|
||||
|
||||
if (hasCurrency)
|
||||
currency.copyFrom (sit.get160 ());
|
||||
currency = sit.get160();
|
||||
|
||||
if (hasIssuer)
|
||||
issuer.copyFrom (sit.get160 ());
|
||||
issuer = sit.get160();
|
||||
|
||||
path.emplace_back (account, currency, issuer, hasCurrency);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ Currency to_currency(std::string const& code)
|
||||
|
||||
Currency const& xrpCurrency()
|
||||
{
|
||||
static Currency const currency(0);
|
||||
static Currency const currency(beast::zero);
|
||||
return currency;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <complex>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
@@ -57,6 +59,8 @@ struct base_uint_test : beast::unit_test::suite
|
||||
|
||||
void run() override
|
||||
{
|
||||
static_assert(!std::is_constructible<test96, std::complex<double>>::value, "");
|
||||
static_assert(!std::is_assignable<test96&, std::complex<double>>::value, "");
|
||||
// used to verify set insertion (hashing required)
|
||||
std::unordered_set<test96, hardened_hash<>> uset;
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
{
|
||||
blob b;
|
||||
hex_to_binary (s.begin (), s.end (), b);
|
||||
return uint256::fromVoid(b.data());
|
||||
return uint256{b};
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <ripple/beast/xor_shift_engine.h>
|
||||
#include <ripple/beast/unit_test.h>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
@@ -115,12 +116,12 @@ public:
|
||||
digest_test ()
|
||||
{
|
||||
beast::xor_shift_engine g(19207813);
|
||||
std::uint8_t buf[32];
|
||||
std::array<std::uint8_t, 32> buf;
|
||||
|
||||
for (int i = 0; i < 1000000; i++)
|
||||
{
|
||||
beast::rngfill (buf, sizeof(buf), g);
|
||||
dataset1.push_back (uint256::fromVoid (buf));
|
||||
beast::rngfill (buf.data(), buf.size(), g);
|
||||
dataset1.push_back (uint256{buf});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user