Add Rules to ReadView:

An instance of Rules provides information on the tx
processing rules in a particular ledger.

* OpenView allows rules to be set on construction.

Conflicts:
	src/ripple/unity/ledger.cpp
This commit is contained in:
Vinnie Falco
2015-07-16 09:54:10 -07:00
parent eb49e1bf47
commit 0cf58cc505
19 changed files with 269 additions and 56 deletions

View File

@@ -192,7 +192,7 @@ Ledger::Ledger (create_genesis_t, Config const& config)
updateHash();
setClosed();
setAccepted();
setFees(config);
setup(config);
}
Ledger::Ledger (uint256 const& parentHash,
@@ -240,7 +240,7 @@ Ledger::Ledger (uint256 const& parentHash,
txMap_->setImmutable ();
stateMap_->setImmutable ();
setFees(config);
setup(config);
}
// Create a new ledger that's a snapshot of this one
@@ -296,7 +296,7 @@ Ledger::Ledger (void const* data,
{
SerialIter sit (data, size);
setRaw (sit, hasPrefix);
// We can't set the fees until the stateMap is populated
// Can't set up until the stateMap is filled in
}
Ledger::Ledger (std::uint32_t ledgerSeq,
@@ -312,7 +312,7 @@ Ledger::Ledger (std::uint32_t ledgerSeq,
info_.seq = ledgerSeq;
info_.closeTime = closeTime;
info_.closeTimeResolution = ledgerDefaultTimeResolution;
setFees(config);
setup(config);
}
//------------------------------------------------------------------------------
@@ -332,7 +332,7 @@ void Ledger::setImmutable ()
txMap_->setImmutable ();
if (stateMap_)
stateMap_->setImmutable ();
setFees (getConfig ());
setup(getConfig ());
}
void Ledger::updateHash()
@@ -1066,7 +1066,7 @@ Ledger::rawTxInsert (uint256 const& key,
}
void
Ledger::setFees (Config const& config)
Ledger::setup (Config const& config)
{
fees_.base = config.FEE_DEFAULT;
fees_.units = config.TRANSACTION_FEE_BASE;
@@ -1089,6 +1089,7 @@ Ledger::setFees (Config const& config)
if (sle->getFieldIndex (sfReserveIncrement) != -1)
fees_.increment = sle->getFieldU32 (sfReserveIncrement);
}
rules_ = Rules(*this);
}
std::shared_ptr<SLE>

View File

@@ -142,6 +142,12 @@ public:
return fees_;
}
Rules const&
rules() const override
{
return rules_;
}
bool
exists (Keylet const& k) const override;
@@ -379,7 +385,7 @@ private:
bool saveValidatedLedger (bool current);
void
setFees (Config const& config);
setup (Config const& config);
std::shared_ptr<SLE>
peek (Keylet const& k) const;
@@ -406,6 +412,7 @@ private:
std::mutex mutable mutex_;
Fees fees_;
Rules rules_;
LedgerInfo info_;
// Ripple cost of the reference transaction

View File

@@ -143,14 +143,16 @@ public:
The current view is atomically set to the
new open view.
@param rules The rules for the open ledger
@param ledger A new closed ledger
*/
void
accept(std::shared_ptr<Ledger const> const& ledger,
OrderedTxs const& locals, bool retriesFirst,
OrderedTxs& retries, ApplyFlags flags,
IHashRouter& router,
std::string const& suffix = "");
accept (Rules const& rules,
std::shared_ptr<Ledger const> const& ledger,
OrderedTxs const& locals, bool retriesFirst,
OrderedTxs& retries, ApplyFlags flags,
IHashRouter& router,
std::string const& suffix = "");
/** Algorithm for applying transactions.
@@ -174,8 +176,8 @@ private:
};
std::shared_ptr<OpenView>
create (std::shared_ptr<
Ledger const> const& ledger);
create (Rules const& rules,
std::shared_ptr<Ledger const> const& ledger);
static
Result

View File

@@ -1157,8 +1157,15 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
ledgerMaster_.pushLedger (newLCL, newOL);
#if RIPPLE_OPEN_LEDGER
getApp().openLedger().accept(newLCL,
localTx, anyDisputes, retries, tapNONE,
auto const lastVal =
getApp().getLedgerMaster().getValidatedLedger();
boost::optional<Rules> rules;
if (lastVal)
rules.emplace(*lastVal);
else
rules.emplace();
getApp().openLedger().accept(*rules,
newLCL, localTx, anyDisputes, retries, tapNONE,
getApp().getHashRouter(), "consensus");
getApp().openLedger().verify(*newOL, "consensus after");
#endif

View File

@@ -32,7 +32,7 @@ OpenLedger::OpenLedger(std::shared_ptr<
: j_ (journal)
, cache_ (cache)
, config_ (config)
, current_ (create(ledger))
, current_ (create(ledger->rules(), ledger))
{
}
@@ -73,15 +73,15 @@ OpenLedger::modify (std::function<
}
void
OpenLedger::accept(std::shared_ptr<
Ledger const> const& ledger,
OpenLedger::accept(Rules const& rules,
std::shared_ptr<Ledger const> const& ledger,
OrderedTxs const& locals, bool retriesFirst,
OrderedTxs& retries, ApplyFlags flags,
IHashRouter& router, std::string const& suffix)
{
JLOG(j_.error) <<
"accept ledger " << ledger->seq() << " " << suffix;
auto next = create(ledger);
auto next = create(rules, ledger);
if (retriesFirst)
{
// Handle disputed tx, outside lock
@@ -121,11 +121,11 @@ OpenLedger::accept(std::shared_ptr<
//------------------------------------------------------------------------------
std::shared_ptr<OpenView>
OpenLedger::create(std::shared_ptr<
Ledger const> const& ledger)
OpenLedger::create (Rules const& rules,
std::shared_ptr<Ledger const> const& ledger)
{
return std::make_shared<OpenView>(
open_ledger, std::make_shared<
open_ledger, rules, std::make_shared<
CachedLedger const>(ledger,
cache_));
}

View File

@@ -1322,7 +1322,14 @@ void NetworkOPsImp::switchLastClosedLedger (
#if RIPPLE_OPEN_LEDGER
auto retries = localTx;
getApp().openLedger().accept(
auto const lastVal =
getApp().getLedgerMaster().getValidatedLedger();
boost::optional<Rules> rules;
if (lastVal)
rules.emplace(*lastVal);
else
rules.emplace();
getApp().openLedger().accept(*rules,
newLCL, OrderedTxs({}), false, retries,
tapNONE, getApp().getHashRouter(), "jump");
getApp().openLedger().verify(

View File

@@ -28,6 +28,7 @@ RippleLineCache::RippleLineCache(
{
// We want the caching that OpenView provides
// And we need to own a shared_ptr to the input view
// VFALCO TODO This should be a CachedLedger
mLedger = std::make_shared<OpenView>(&*ledger, ledger);
}

View File

@@ -53,8 +53,8 @@ public:
ApplyViewImpl (ApplyViewImpl&&) = default;
#endif
ApplyViewImpl (ReadView const* base,
ApplyFlags flags);
ApplyViewImpl(
ReadView const* base, ApplyFlags flags);
/** Apply the transaction.

View File

@@ -77,6 +77,12 @@ public:
return base_.fees();
}
Rules const&
rules() const override
{
return base_.rules();
}
boost::optional<key_type>
succ (key_type const& key, boost::optional<
key_type> last = boost::none) const override

View File

@@ -54,6 +54,7 @@ private:
Serializer const>, std::shared_ptr<
Serializer const>>>;
Rules rules_;
txs_map txs_;
LedgerInfo info_;
ReadView const* base_;
@@ -69,6 +70,7 @@ public:
OpenView (OpenView&& other)
: ReadView (std::move(other))
, TxsRawView (std::move(other))
, rules_ (std::move(other.rules_))
, txs_ (std::move(other.txs_))
, info_ (std::move(other.info_))
, base_ (std::move(other.base_))
@@ -108,16 +110,20 @@ public:
ownership of a copy of `hold` until
the MetaView is destroyed.
Calls to rules() will return the
rules provided on construction.
The tx list starts empty and will contain
all newly inserted tx.
*/
/** @{ */
OpenView (open_ledger_t, ReadView const* base,
std::shared_ptr<void const> hold = nullptr);
OpenView (open_ledger_t,
ReadView const* base, Rules const& rules,
std::shared_ptr<void const> hold = nullptr);
OpenView (open_ledger_t, std::shared_ptr<
ReadView const> const& base)
: OpenView (open_ledger, &*base, base)
OpenView (open_ledger_t, Rules const& rules,
std::shared_ptr<ReadView const> const& base)
: OpenView (open_ledger, &*base, rules, base)
{
}
/** @} */
@@ -128,6 +134,8 @@ public:
The LedgerInfo is copied from the base.
The rules are inherited from the base.
The tx list starts empty and will contain
all newly inserted tx.
*/
@@ -154,6 +162,9 @@ public:
Fees const&
fees() const override;
Rules const&
rules() const override;
bool
exists (Keylet const& k) const override;

View File

@@ -107,8 +107,7 @@ public:
PaymentSandbox (PaymentSandbox&&) = default;
#endif
PaymentSandbox (ReadView const* base,
ApplyFlags flags)
PaymentSandbox (ReadView const* base, ApplyFlags flags)
: ApplyViewBase (base, flags)
{
}
@@ -134,14 +133,14 @@ public:
/** @{ */
explicit
PaymentSandbox (PaymentSandbox const* base)
: ApplyViewBase (base, base->flags())
: ApplyViewBase(base, base->flags())
, ps_ (base)
{
}
explicit
PaymentSandbox (PaymentSandbox* base)
: ApplyViewBase (base, base->flags())
: ApplyViewBase(base, base->flags())
, ps_ (base)
{
}

View File

@@ -104,17 +104,59 @@ struct LedgerInfo
std::uint32_t closeTime = 0;
};
// ledger close flags
static
std::uint32_t const sLCF_NoConsensusTime = 1;
//------------------------------------------------------------------------------
inline
bool getCloseAgree (LedgerInfo const& info)
class DigestAwareReadView;
/** Rules controlling protocol behavior. */
class Rules
{
return (info.closeFlags & sLCF_NoConsensusTime) == 0;
}
private:
class Impl;
void addRaw (LedgerInfo const&, Serializer&);
std::shared_ptr<Impl const> impl_;
public:
Rules (Rules const&) = default;
Rules& operator= (Rules const&) = default;
/** Construct an empty rule set.
These are the rules reflected by
the genesis ledger.
*/
Rules() = default;
/** Construct rules from a ledger.
The ledger contents are analyzed for rules
and amendments and extracted to the object.
*/
explicit
Rules (DigestAwareReadView const& ledger);
/** Returns `true` if a feature is enabled. */
bool
enabled (uint256 const& feature) const;
/** Returns `true` if these rules don't match the ledger. */
bool
changed (DigestAwareReadView const& ledger) const;
/** Returns `true` if two rule sets are identical.
@note This is for diagnostics. To determine if new
rules should be constructed, call changed() first instead.
*/
bool
operator== (Rules const&) const;
bool
operator!= (Rules const& other) const
{
return ! (*this == other);
}
};
//------------------------------------------------------------------------------
@@ -214,6 +256,11 @@ public:
Fees const&
fees() const = 0;
/** Returns the tx processing rules. */
virtual
Rules const&
rules() const = 0;
/** Determine if a state item exists.
@note This can be more efficient than calling read.
@@ -344,6 +391,20 @@ public:
digest (key_type const& key) const = 0;
};
//------------------------------------------------------------------------------
// ledger close flags
static
std::uint32_t const sLCF_NoConsensusTime = 1;
inline
bool getCloseAgree (LedgerInfo const& info)
{
return (info.closeFlags & sLCF_NoConsensusTime) == 0;
}
void addRaw (LedgerInfo const&, Serializer&);
} // ripple
#include <ripple/ledger/detail/ReadViewFwdRange.ipp>

View File

@@ -49,14 +49,13 @@ public:
Sandbox (Sandbox&&) = default;
#endif
Sandbox (ReadView const* base,
ApplyFlags flags)
Sandbox (ReadView const* base, ApplyFlags flags)
: ApplyViewBase (base, flags)
{
}
Sandbox (ApplyView const* base)
: Sandbox (base, base->flags())
: Sandbox(base, base->flags())
{
}

View File

@@ -52,8 +52,8 @@ public:
ApplyViewBase (ApplyViewBase&&) = default;
#endif
ApplyViewBase (ReadView const* base,
ApplyFlags flags);
ApplyViewBase(
ReadView const* base, ApplyFlags flags);
// ReadView
@@ -63,6 +63,9 @@ public:
Fees const&
fees() const override;
Rules const&
rules() const override;
bool
exists (Keylet const& k) const override;

View File

@@ -25,8 +25,7 @@ namespace ripple {
namespace detail {
ApplyViewBase::ApplyViewBase(
ReadView const* base,
ApplyFlags flags)
ReadView const* base, ApplyFlags flags)
: flags_ (flags)
, base_ (base)
{
@@ -46,6 +45,12 @@ ApplyViewBase::fees() const
return base_->fees();
}
Rules const&
ApplyViewBase::rules() const
{
return base_->rules();
}
bool
ApplyViewBase::exists (Keylet const& k) const
{

View File

@@ -20,12 +20,12 @@
#include <BeastConfig.h>
#include <ripple/ledger/ApplyViewImpl.h>
#include <ripple/basics/contract.h>
#include <cassert>
namespace ripple {
ApplyViewImpl::ApplyViewImpl(
ReadView const* base,
ApplyFlags flags)
ReadView const* base, ApplyFlags flags)
: ApplyViewBase (base, flags)
{
}

View File

@@ -89,9 +89,10 @@ public:
//------------------------------------------------------------------------------
OpenView::OpenView (open_ledger_t,
ReadView const* base,
ReadView const* base, Rules const& rules,
std::shared_ptr<void const> hold)
: info_ (base->info())
: rules_ (rules)
, info_ (base->info())
, base_ (base)
, hold_ (std::move(hold))
{
@@ -102,7 +103,8 @@ OpenView::OpenView (open_ledger_t,
OpenView::OpenView (ReadView const* base,
std::shared_ptr<void const> hold)
: info_ (base->info())
: rules_ (base->rules())
, info_ (base->info())
, base_ (base)
, hold_ (std::move(hold))
{
@@ -138,6 +140,12 @@ OpenView::fees() const
return base_->fees();
}
Rules const&
OpenView::rules() const
{
return rules_;
}
bool
OpenView::exists (Keylet const& k) const
{

View File

@@ -19,9 +19,105 @@
#include <BeastConfig.h>
#include <ripple/ledger/ReadView.h>
#include <boost/optional.hpp>
namespace ripple {
class Rules::Impl
{
private:
std::unordered_set<uint256,
hardened_hash<>> set_;
boost::optional<uint256> digest_;
public:
Impl (DigestAwareReadView const& ledger)
{
auto const k = keylet::amendments();
digest_ = ledger.digest(k.key);
if (! digest_)
return;
auto const sle = ledger.read(k);
if (! sle)
{
// LogicError() ?
return;
}
for (auto const& item :
sle->getFieldV256(sfAmendments))
set_.insert(item);
}
bool
enabled (uint256 const& feature) const
{
return set_.count(feature) > 0;
}
bool
changed (DigestAwareReadView const& ledger) const
{
auto const digest =
ledger.digest(keylet::amendments().key);
if (! digest && ! digest_)
return false;
if (! digest || ! digest_)
return true;
return *digest != *digest_;
}
bool
operator== (Impl const& other) const
{
if (! digest_ && ! other.digest_)
return true;
if (! digest_ || ! other.digest_)
return false;
return *digest_ == *other.digest_;
}
};
//------------------------------------------------------------------------------
Rules::Rules (DigestAwareReadView const& ledger)
: impl_(std::make_shared<Impl>(ledger))
{
}
bool
Rules::enabled (uint256 const& feature) const
{
if (! impl_)
return false;
return impl_->enabled(feature);
}
bool
Rules::changed (DigestAwareReadView const& ledger) const
{
if (! impl_)
return static_cast<bool>(
ledger.digest(keylet::amendments().key));
return impl_->changed(ledger);
}
bool
Rules::operator== (Rules const& other) const
{
#if 0
if (! impl_ && ! other.impl_)
return true;
if (! impl_ || ! other.impl_)
return false;
return *impl_ == *other.impl_;
#else
return impl_.get() == other.impl_.get();
#endif
}
//------------------------------------------------------------------------------
ReadView::sles_type::sles_type(
ReadView const& view)
: ReadViewFwdRange(view)

View File

@@ -117,7 +117,7 @@ Env::close(NetClock::time_point const& closeTime)
closeTime.time_since_epoch ()).count (),
ledgerPossibleTimeResolutions[0], false);
OrderedTxs locals({});
openLedger.accept(next, locals,
openLedger.accept(next->rules(), next, locals,
false, retries, applyFlags(), *router);
closed_ = next;
cachedSLEs_.expire();