mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
Add BasicView::txs memberspace interface
This commit is contained in:
@@ -632,6 +632,39 @@ bool Ledger::saveValidatedLedger (bool current)
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::shared_ptr<STTx const>
|
||||
deserializeTx (SHAMapItem const& item)
|
||||
{
|
||||
SerialIter sit(item.slice());
|
||||
return std::make_shared<STTx const>(sit);
|
||||
}
|
||||
|
||||
std::pair<std::shared_ptr<
|
||||
STTx const>, std::shared_ptr<
|
||||
STObject const>>
|
||||
deserializeTxPlusMeta (SHAMapItem const& item)
|
||||
{
|
||||
std::pair<std::shared_ptr<
|
||||
STTx const>, std::shared_ptr<
|
||||
STObject const>> result;
|
||||
SerialIter sit(item.slice());
|
||||
{
|
||||
SerialIter s(sit.getSlice(
|
||||
sit.getVLDataLength()));
|
||||
result.first = std::make_shared<
|
||||
STTx const>(s);
|
||||
}
|
||||
{
|
||||
SerialIter s(sit.getSlice(
|
||||
sit.getVLDataLength()));
|
||||
result.second = std::make_shared<
|
||||
STObject const>(s, sfMetadata);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load a ledger from the database.
|
||||
*
|
||||
@@ -923,6 +956,80 @@ Ledger::read (Keylet const& k) const
|
||||
return std::move(sle);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class Ledger::tx_iterator_impl
|
||||
: public BasicView::iterator_impl
|
||||
{
|
||||
private:
|
||||
SHAMap::iterator iter_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
tx_iterator_impl (SHAMap::iterator iter)
|
||||
: iter_(iter)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
copy() const override
|
||||
{
|
||||
return std::make_unique<
|
||||
tx_iterator_impl>(
|
||||
iter_);
|
||||
}
|
||||
|
||||
bool
|
||||
equal (iterator_impl const& impl) const override
|
||||
{
|
||||
auto const& other = dynamic_cast<
|
||||
tx_iterator_impl const&>(impl);
|
||||
return iter_ == other.iter_;
|
||||
}
|
||||
|
||||
void
|
||||
increment() override
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
|
||||
txs_type::value_type
|
||||
dereference() const override
|
||||
{
|
||||
return deserializeTxPlusMeta(**iter_);
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
Ledger::txEmpty() const
|
||||
{
|
||||
return txMap_->getHash().isZero();
|
||||
}
|
||||
|
||||
auto
|
||||
Ledger::txBegin() const ->
|
||||
std::unique_ptr<iterator_impl>
|
||||
{
|
||||
// Can't iterate open Ledger objects
|
||||
// because they don't have the metadata!
|
||||
assert(closed());
|
||||
return std::make_unique<
|
||||
tx_iterator_impl>(txMap_->begin());
|
||||
}
|
||||
|
||||
auto
|
||||
Ledger::txEnd() const ->
|
||||
std::unique_ptr<iterator_impl>
|
||||
{
|
||||
// Can't iterate open Ledger objects
|
||||
// because they don't have the metadata!
|
||||
assert(closed());
|
||||
return std::make_unique<
|
||||
tx_iterator_impl>(txMap_->end());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
Ledger::unchecked_erase(
|
||||
uint256 const& key)
|
||||
|
||||
@@ -140,6 +140,15 @@ public:
|
||||
std::shared_ptr<SLE const>
|
||||
read (Keylet const& k) const override;
|
||||
|
||||
bool
|
||||
txEmpty() const override;
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txBegin() const override;
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txEnd() const override;
|
||||
|
||||
bool
|
||||
unchecked_erase (uint256 const& key) override;
|
||||
|
||||
@@ -418,14 +427,15 @@ public:
|
||||
static std::map< std::uint32_t, std::pair<uint256, uint256> >
|
||||
getHashesByIndex (std::uint32_t minSeq, std::uint32_t maxSeq);
|
||||
|
||||
protected:
|
||||
private:
|
||||
class tx_iterator_impl;
|
||||
|
||||
void saveValidatedLedgerAsync(Job&, bool current)
|
||||
{
|
||||
saveValidatedLedger(current);
|
||||
}
|
||||
bool saveValidatedLedger (bool current);
|
||||
|
||||
private:
|
||||
// ledger close flags
|
||||
static const std::uint32_t sLCF_NoConsensusTime = 1;
|
||||
|
||||
@@ -485,6 +495,29 @@ private:
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Deserialize a SHAMapItem containing a single STTx
|
||||
|
||||
Throw:
|
||||
|
||||
May throw on deserializaton error
|
||||
*/
|
||||
std::shared_ptr<STTx const>
|
||||
deserializeTx (SHAMapItem const& item);
|
||||
|
||||
/** Deserialize a SHAMapItem containing STTx + STObject metadata
|
||||
|
||||
The SHAMap must contain two variable length
|
||||
serialization objects.
|
||||
|
||||
Throw:
|
||||
|
||||
May throw on deserializaton error
|
||||
*/
|
||||
std::pair<std::shared_ptr<
|
||||
STTx const>, std::shared_ptr<
|
||||
STObject const>>
|
||||
deserializeTxPlusMeta (SHAMapItem const& item);
|
||||
|
||||
std::tuple<Ledger::pointer, std::uint32_t, uint256>
|
||||
loadLedgerHelper(std::string const& sqlSuffix);
|
||||
|
||||
|
||||
@@ -84,8 +84,9 @@ private:
|
||||
// The SLEs and Serializers in here are
|
||||
// shared between copy-constructed instances
|
||||
using item_list = std::map<uint256, Item>;
|
||||
using tx_list = hardened_hash_map<
|
||||
uint256, std::pair<std::shared_ptr<
|
||||
// List of tx, key order
|
||||
using tx_map = std::map<uint256,
|
||||
std::pair<std::shared_ptr<
|
||||
Serializer const>, std::shared_ptr<
|
||||
Serializer const>>>;
|
||||
|
||||
@@ -94,7 +95,7 @@ private:
|
||||
BasicView const& base_;
|
||||
ViewFlags flags_ = tapNONE;
|
||||
ViewInfo info_;
|
||||
tx_list txs_;
|
||||
tx_map txs_;
|
||||
item_list items_;
|
||||
std::uint32_t destroyedCoins_ = 0;
|
||||
boost::optional<STAmount> deliverAmount_;
|
||||
@@ -193,6 +194,16 @@ public:
|
||||
std::shared_ptr<SLE const>
|
||||
read (Keylet const& k) const override;
|
||||
|
||||
virtual
|
||||
bool
|
||||
txEmpty() const override;
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txBegin() const override;
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txEnd() const override;
|
||||
|
||||
bool
|
||||
unchecked_erase(
|
||||
uint256 const& key) override;
|
||||
@@ -301,6 +312,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
class tx_iterator_impl;
|
||||
|
||||
static
|
||||
bool
|
||||
threadTx (TxMeta& meta,
|
||||
|
||||
@@ -170,6 +170,93 @@ MetaView::read (Keylet const& k) const
|
||||
return sle;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class MetaView::tx_iterator_impl
|
||||
: public BasicView::iterator_impl
|
||||
{
|
||||
private:
|
||||
bool metadata_;
|
||||
tx_map::const_iterator iter_;
|
||||
|
||||
public:
|
||||
explicit
|
||||
tx_iterator_impl (bool metadata,
|
||||
tx_map::const_iterator iter)
|
||||
: metadata_(metadata)
|
||||
, iter_(iter)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
copy() const override
|
||||
{
|
||||
return std::make_unique<
|
||||
tx_iterator_impl>(
|
||||
metadata_, iter_);
|
||||
}
|
||||
|
||||
bool
|
||||
equal (iterator_impl const& impl) const override
|
||||
{
|
||||
auto const& other = dynamic_cast<
|
||||
tx_iterator_impl const&>(impl);
|
||||
return iter_ == other.iter_;
|
||||
}
|
||||
|
||||
void
|
||||
increment() override
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
|
||||
txs_type::value_type
|
||||
dereference() const override
|
||||
{
|
||||
txs_type::value_type result;
|
||||
{
|
||||
SerialIter sit(
|
||||
iter_->second.first->slice());
|
||||
result.first = std::make_shared<
|
||||
STTx const>(sit);
|
||||
}
|
||||
if (metadata_)
|
||||
{
|
||||
SerialIter sit(
|
||||
iter_->second.second->slice());
|
||||
result.second = std::make_shared<
|
||||
STObject const>(sit, sfMetadata);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
bool
|
||||
MetaView::txEmpty() const
|
||||
{
|
||||
return txs_.empty();
|
||||
}
|
||||
|
||||
auto
|
||||
MetaView::txBegin() const ->
|
||||
std::unique_ptr<iterator_impl>
|
||||
{
|
||||
return std::make_unique<
|
||||
tx_iterator_impl>(
|
||||
closed(), txs_.cbegin());
|
||||
}
|
||||
|
||||
auto
|
||||
MetaView::txEnd() const ->
|
||||
std::unique_ptr<iterator_impl>
|
||||
{
|
||||
return std::make_unique<
|
||||
tx_iterator_impl>(
|
||||
closed(), txs_.cend());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
MetaView::unchecked_erase (uint256 const& key)
|
||||
{
|
||||
@@ -293,9 +380,7 @@ MetaView::txInsert (uint256 const& key,
|
||||
if (txs_.count(key) ||
|
||||
base_.txExists(key))
|
||||
LogicError("duplicate_tx: " + to_string(key));
|
||||
txs_.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(key),
|
||||
std::forward_as_tuple(
|
||||
txs_.emplace(key, std::make_pair(
|
||||
txn, metaData));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <ripple/protocol/Protocol.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <ripple/protocol/STLedgerEntry.h>
|
||||
#include <ripple/protocol/STObject.h>
|
||||
#include <ripple/protocol/STTx.h>
|
||||
#include <ripple/protocol/TER.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/ledger/View.h>
|
||||
@@ -99,15 +101,27 @@ struct ViewInfo
|
||||
and transaction items. There is no checkpointing
|
||||
or calculation of metadata.
|
||||
|
||||
A raw interace is provided for mutable ledgers.
|
||||
A raw interace is provided for mutable ledgers,
|
||||
this is used internally by implementations and
|
||||
should not be called directly.
|
||||
*/
|
||||
// VFALCO Rename unchecked functions to raw
|
||||
class BasicView
|
||||
{
|
||||
protected:
|
||||
class iterator_impl;
|
||||
|
||||
public:
|
||||
using key_type = uint256;
|
||||
|
||||
using mapped_type =
|
||||
std::shared_ptr<SLE const>;
|
||||
|
||||
BasicView()
|
||||
: txs(*this)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~BasicView() = default;
|
||||
|
||||
/** Returns information about the ledger. */
|
||||
@@ -191,6 +205,21 @@ public:
|
||||
std::shared_ptr<SLE const>
|
||||
read (Keylet const& k) const = 0;
|
||||
|
||||
// used by the implementation
|
||||
virtual
|
||||
bool
|
||||
txEmpty() const = 0;
|
||||
|
||||
// used by the implementation
|
||||
virtual
|
||||
std::unique_ptr<iterator_impl>
|
||||
txBegin() const = 0;
|
||||
|
||||
// used by the implementation
|
||||
virtual
|
||||
std::unique_ptr<iterator_impl>
|
||||
txEnd() const = 0;
|
||||
|
||||
/** Unconditionally erase a state item.
|
||||
|
||||
Requirements:
|
||||
@@ -266,7 +295,11 @@ public:
|
||||
std::size_t
|
||||
txCount() const = 0;
|
||||
|
||||
/** Returns `true` if a tx exists in the tx map. */
|
||||
/** Returns `true` if a tx exists in the tx map.
|
||||
|
||||
A tx exists in the map if it is part of the
|
||||
base ledger, or if it is a newly inserted tx.
|
||||
*/
|
||||
virtual
|
||||
bool
|
||||
txExists (uint256 const& key) const = 0;
|
||||
@@ -290,9 +323,62 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// A Forward Range container
|
||||
// representing the list of transactions
|
||||
//
|
||||
class txs_type
|
||||
{
|
||||
private:
|
||||
friend class BasicView;
|
||||
|
||||
BasicView& view_;
|
||||
|
||||
explicit
|
||||
txs_type (BasicView& view)
|
||||
: view_ (view)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/** ForwardIterator to access transactions */
|
||||
class iterator;
|
||||
using const_iterator = iterator;
|
||||
|
||||
/** Transaction followed by optional metadata. */
|
||||
using value_type = std::pair<
|
||||
std::shared_ptr<STTx const>,
|
||||
std::shared_ptr<STObject const>>;
|
||||
|
||||
txs_type() = delete;
|
||||
txs_type (txs_type const&) = delete;
|
||||
txs_type& operator= (txs_type const&) = delete;
|
||||
|
||||
bool
|
||||
empty() const;
|
||||
|
||||
/** Return iterator to the beginning of the tx list.
|
||||
|
||||
Meets the requirements of `ForwardIterator`
|
||||
*/
|
||||
iterator
|
||||
begin() const;
|
||||
|
||||
/** Return iterator to one past the end of the tx list.
|
||||
|
||||
Meets the requirements of `ForwardIterator`
|
||||
*/
|
||||
iterator
|
||||
end() const;
|
||||
};
|
||||
|
||||
// Memberspace
|
||||
// The list of transactions.
|
||||
txs_type const txs;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Called to adjust returned balances
|
||||
// This is required to support PaymentView
|
||||
|
||||
virtual
|
||||
STAmount
|
||||
balanceHook (AccountID const& account,
|
||||
@@ -305,6 +391,175 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class BasicView::iterator_impl
|
||||
{
|
||||
public:
|
||||
iterator_impl() = default;
|
||||
iterator_impl(iterator_impl const&) = delete;
|
||||
iterator_impl& operator=(iterator_impl const&) = delete;
|
||||
|
||||
virtual
|
||||
~iterator_impl() = default;
|
||||
|
||||
virtual
|
||||
std::unique_ptr<iterator_impl>
|
||||
copy() const = 0;
|
||||
|
||||
virtual
|
||||
bool
|
||||
equal (iterator_impl const& impl) const = 0;
|
||||
|
||||
virtual
|
||||
void
|
||||
increment() = 0;
|
||||
|
||||
virtual
|
||||
txs_type::value_type
|
||||
dereference() const = 0;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class BasicView::txs_type::iterator
|
||||
{
|
||||
public:
|
||||
using value_type =
|
||||
BasicView::txs_type::value_type;
|
||||
|
||||
using pointer = value_type const*;
|
||||
|
||||
using reference = value_type const&;
|
||||
|
||||
using difference_type =
|
||||
std::ptrdiff_t;
|
||||
|
||||
using iterator_category =
|
||||
std::forward_iterator_tag;
|
||||
|
||||
iterator() = default;
|
||||
|
||||
iterator (iterator const& other)
|
||||
: view_ (other.view_)
|
||||
, impl_ (other.impl_->copy())
|
||||
, cache_ (other.cache_)
|
||||
{
|
||||
}
|
||||
|
||||
iterator (iterator&& other)
|
||||
: view_ (other.view_)
|
||||
, impl_ (std::move(other.impl_))
|
||||
, cache_ (std::move(other.cache_))
|
||||
{
|
||||
}
|
||||
|
||||
// Used by the implementation
|
||||
explicit
|
||||
iterator (BasicView const& view,
|
||||
std::unique_ptr<
|
||||
iterator_impl> impl)
|
||||
: view_ (&view)
|
||||
, impl_ (std::move(impl))
|
||||
{
|
||||
}
|
||||
|
||||
iterator&
|
||||
operator= (iterator const& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
view_ = other.view_;
|
||||
impl_ = other.impl_->copy();
|
||||
cache_ = other.cache_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator&
|
||||
operator= (iterator&& other)
|
||||
{
|
||||
view_ = other.view_;
|
||||
impl_ = std::move(other.impl_);
|
||||
cache_ = std::move(other.cache_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
operator== (iterator const& other) const
|
||||
{
|
||||
assert(view_ == other.view_);
|
||||
return impl_->equal(*other.impl_);
|
||||
}
|
||||
|
||||
bool
|
||||
operator!= (iterator const& other) const
|
||||
{
|
||||
return ! (*this == other);
|
||||
}
|
||||
|
||||
// Can throw
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
if (! cache_)
|
||||
cache_ = impl_->dereference();
|
||||
return *cache_;
|
||||
}
|
||||
|
||||
// Can throw
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return &**this;
|
||||
}
|
||||
|
||||
iterator&
|
||||
operator++()
|
||||
{
|
||||
impl_->increment();
|
||||
cache_ = boost::none;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator
|
||||
operator++(int)
|
||||
{
|
||||
iterator prev(*view_,
|
||||
impl_->copy());
|
||||
prev.cache_ = std::move(cache_);
|
||||
++(*this);
|
||||
return prev;
|
||||
}
|
||||
|
||||
private:
|
||||
BasicView const* view_ = nullptr;
|
||||
std::unique_ptr<iterator_impl> impl_;
|
||||
boost::optional<value_type> mutable cache_;
|
||||
};
|
||||
|
||||
inline
|
||||
bool
|
||||
BasicView::txs_type::empty() const
|
||||
{
|
||||
return view_.txEmpty();
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
BasicView::txs_type::begin() const ->
|
||||
iterator
|
||||
{
|
||||
return iterator(view_, view_.txBegin());
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
BasicView::txs_type::end() const ->
|
||||
iterator
|
||||
{
|
||||
return iterator(view_, view_.txEnd());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
enum ViewFlags
|
||||
{
|
||||
tapNONE = 0x00,
|
||||
@@ -327,8 +582,8 @@ enum ViewFlags
|
||||
};
|
||||
|
||||
inline
|
||||
ViewFlags operator|(
|
||||
ViewFlags const& lhs,
|
||||
ViewFlags
|
||||
operator|(ViewFlags const& lhs,
|
||||
ViewFlags const& rhs)
|
||||
{
|
||||
return static_cast<ViewFlags>(
|
||||
@@ -338,8 +593,7 @@ ViewFlags operator|(
|
||||
|
||||
inline
|
||||
ViewFlags
|
||||
operator&(
|
||||
ViewFlags const& lhs,
|
||||
operator&(ViewFlags const& lhs,
|
||||
ViewFlags const& rhs)
|
||||
{
|
||||
return static_cast<ViewFlags>(
|
||||
@@ -532,6 +786,24 @@ public:
|
||||
return view_.read(k);
|
||||
}
|
||||
|
||||
bool
|
||||
txEmpty() const override
|
||||
{
|
||||
return view_.txEmpty();
|
||||
}
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txBegin() const override
|
||||
{
|
||||
return view_.txBegin();
|
||||
}
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txEnd() const override
|
||||
{
|
||||
return view_.txEnd();
|
||||
}
|
||||
|
||||
bool
|
||||
unchecked_erase(
|
||||
uint256 const& key) override
|
||||
@@ -637,6 +909,24 @@ public:
|
||||
return view_.read(k);
|
||||
}
|
||||
|
||||
bool
|
||||
txEmpty() const override
|
||||
{
|
||||
return view_.txEmpty();
|
||||
}
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txBegin() const override
|
||||
{
|
||||
return view_.txBegin();
|
||||
}
|
||||
|
||||
std::unique_ptr<iterator_impl>
|
||||
txEnd() const override
|
||||
{
|
||||
return view_.txEnd();
|
||||
}
|
||||
|
||||
bool
|
||||
unchecked_erase(
|
||||
uint256 const& key) override
|
||||
|
||||
Reference in New Issue
Block a user