Files
xahaud/src/ripple/app/ledger/LedgerEntrySet.h
Vinnie Falco babaac9305 Refactor Ledger and support classes:
This performs a deep refactor on the Ledger class and its supporting
classes, in preparation for the move to shared_ptr<SLE const> in
places where the SLE is immutable and we are currently using
shared_ptr<SLE>.

Member functions are converted to free functions, the SLECache is an
explicit parameter, one line convenience functions are removed to
streamline the interface. Some callers are changed to use <SLE const>
instead of <SLE>

SLECache:
* Moved to its own header file

RippleState:
* Remove unused functions
* Store the SLE as const
* Simplify callers

AccountState:
* Remove unused members
* Simplify existing members

Ledger:
* Replace writeBack with insert and update
* Remove unused functions
* Remove LedgerStateParams
* Move getLastFullLedger to Application
* add entryCacheI, exists, fetch, erase
* Use boost::optional where it makes sense
* Make member functions free functions

Free functions:
* fetch: cache-aware SLE retrieval
* forEachItem, forEachItemAfter
* (various)
2015-06-08 17:25:16 -07:00

388 lines
12 KiB
C++

//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_APP_LEDGER_LEDGERENTRYSET_H_INCLUDED
#define RIPPLE_APP_LEDGER_LEDGERENTRYSET_H_INCLUDED
#include <ripple/app/ledger/Ledger.h>
#include <ripple/app/ledger/DeferredCredits.h>
#include <ripple/basics/CountedObject.h>
#include <ripple/protocol/STLedgerEntry.h>
#include <boost/optional.hpp>
namespace ripple {
// VFALCO Does this belong here? Is it correctly named?
enum TransactionEngineParams
{
tapNONE = 0x00,
// Signature already checked
tapNO_CHECK_SIGN = 0x01,
// Transaction is running against an open ledger
// true = failures are not forwarded, check transaction fee
// false = debit ledger for consumed funds
tapOPEN_LEDGER = 0x10,
// This is not the transaction's last pass
// Transaction can be retried, soft failures allowed
tapRETRY = 0x20,
// Transaction came from a privileged source
tapADMIN = 0x400,
};
enum LedgerEntryAction
{
taaNONE,
taaCACHED, // Unmodified.
taaMODIFY, // Modifed, must have previously been taaCACHED.
taaDELETE, // Delete, must have previously been taaDELETE or taaMODIFY.
taaCREATE, // Newly created.
};
enum FreezeHandling
{
fhIGNORE_FREEZE,
fhZERO_IF_FROZEN
};
class LedgerEntrySetEntry
: public CountedObject <LedgerEntrySetEntry>
{
public:
static char const* getCountedObjectName () { return "LedgerEntrySetEntry"; }
SLE::pointer mEntry;
LedgerEntryAction mAction;
int mSeq;
LedgerEntrySetEntry (SLE::ref e, LedgerEntryAction a, int s)
: mEntry (e)
, mAction (a)
, mSeq (s)
{
}
};
/** An LES is a LedgerEntrySet.
It's a view into a ledger used while a transaction is processing.
The transaction manipulates the LES rather than the ledger
(because it's cheaper, can be checkpointed, and so on). When the
transaction finishes, the LES is committed into the ledger to make
the modifications. The transaction metadata is built from the LES too.
*/
/** @{ */
class LedgerEntrySet
: public CountedObject <LedgerEntrySet>
{
public:
static char const* getCountedObjectName () { return "LedgerEntrySet"; }
LedgerEntrySet (
Ledger::ref ledger, TransactionEngineParams tep, bool immutable = false)
: mLedger (ledger), mParams (tep), mSeq (0), mImmutable (immutable)
{
}
LedgerEntrySet () : mParams (tapNONE), mSeq (0), mImmutable (false)
{
}
// Make a duplicate of this set.
LedgerEntrySet duplicate () const;
// Swap the contents of two sets
void swapWith (LedgerEntrySet&);
void invalidate ()
{
mLedger.reset ();
mDeferredCredits.reset ();
}
bool isValid () const
{
return mLedger != nullptr;
}
int getSeq () const
{
return mSeq;
}
void bumpSeq ()
{
++mSeq;
}
void init (Ledger::ref ledger, uint256 const& transactionID,
std::uint32_t ledgerID, TransactionEngineParams params);
void clear ();
Ledger::pointer& getLedger ()
{
return mLedger;
}
// basic entry functions
SLE::pointer getEntry (uint256 const& index, LedgerEntryAction&);
void entryCache (SLE::ref); // Add this entry to the cache
void entryCreate (SLE::ref); // This entry will be created
void entryDelete (SLE::ref); // This entry will be deleted
void entryModify (SLE::ref); // This entry will be modified
// higher-level ledger functions
SLE::pointer entryCreate (LedgerEntryType letType, uint256 const& uIndex);
SLE::pointer entryCache (LedgerEntryType letType, uint256 const& key);
std::shared_ptr<SLE const>
entryCacheI (LedgerEntryType letType, uint256 const& uIndex);
// Directory functions.
TER dirAdd (
std::uint64_t& uNodeDir, // Node of entry.
uint256 const& uRootIndex,
uint256 const& uLedgerIndex,
std::function<void (SLE::ref, bool)> fDescriber);
TER dirDelete (
const bool bKeepRoot,
const std::uint64_t& uNodeDir, // Node item is mentioned in.
uint256 const& uRootIndex,
uint256 const& uLedgerIndex, // Item being deleted
const bool bStable,
const bool bSoft);
bool dirFirst (uint256 const& uRootIndex, SLE::pointer& sleNode,
unsigned int & uDirEntry, uint256 & uEntryIndex);
bool dirFirst (uint256 const& uRootIndex, std::shared_ptr<SLE const>& sleNode,
unsigned int & uDirEntry, uint256 & uEntryIndex);
bool dirNext (uint256 const& uRootIndex, SLE::pointer& sleNode,
unsigned int & uDirEntry, uint256 & uEntryIndex);
bool dirNext (uint256 const& uRootIndex, std::shared_ptr<SLE const>& sleNode,
unsigned int & uDirEntry, uint256 & uEntryIndex);
bool dirIsEmpty (uint256 const& uDirIndex);
TER dirCount (uint256 const& uDirIndex, std::uint32_t & uCount);
uint256 getNextLedgerIndex (uint256 const& uHash);
uint256 getNextLedgerIndex (uint256 const& uHash, uint256 const& uEnd);
/** @{ */
void incrementOwnerCount (SLE::ref sleAccount);
void incrementOwnerCount (Account const& owner);
void increaseOwnerCount (SLE::ref sleAccount, std::uint32_t howMuch);
/** @} */
/** @{ */
void decrementOwnerCount (SLE::ref sleAccount);
void decrementOwnerCount (Account const& owner);
void decreaseOwnerCount (SLE::ref sleAccount, std::uint32_t howMuch);
/** @} */
// Offer functions.
TER offerDelete (SLE::pointer);
TER offerDelete (uint256 const& offerIndex)
{
return offerDelete( entryCache (ltOFFER, offerIndex));
}
// Balance functions.
bool isFrozen (
Account const& account,
Currency const& currency,
Account const& issuer);
bool isGlobalFrozen (Account const& issuer);
void enableDeferredCredits (bool enable=true);
bool areCreditsDeferred () const;
TER rippleCredit (
Account const& uSenderID, Account const& uReceiverID,
const STAmount & saAmount, bool bCheckIssuer = true);
STAmount accountHolds (
Account const& account, Currency const& currency,
Account const& issuer, FreezeHandling freezeHandling);
STAmount accountFunds (
Account const& account, const STAmount & saDefault, FreezeHandling freezeHandling);
TER accountSend (
Account const& uSenderID, Account const& uReceiverID,
const STAmount & saAmount);
TER trustCreate (
const bool bSrcHigh,
Account const& uSrcAccountID,
Account const& uDstAccountID,
uint256 const& uIndex,
SLE::ref sleAccount,
const bool bAuth,
const bool bNoRipple,
const bool bFreeze,
STAmount const& saSrcBalance,
STAmount const& saSrcLimit,
const std::uint32_t uSrcQualityIn = 0,
const std::uint32_t uSrcQualityOut = 0);
TER trustDelete (
SLE::ref sleRippleState, Account const& uLowAccountID,
Account const& uHighAccountID);
Json::Value getJson (int) const;
void calcRawMeta (Serializer&, TER result, std::uint32_t index);
// iterator functions
using iterator = std::map<uint256, LedgerEntrySetEntry>::iterator;
using const_iterator = std::map<uint256, LedgerEntrySetEntry>::const_iterator;
bool empty () const
{
return mEntries.empty ();
}
const_iterator cbegin () const
{
return mEntries.cbegin ();
}
const_iterator cend () const
{
return mEntries.cend ();
}
const_iterator begin () const
{
return mEntries.cbegin ();
}
const_iterator end () const
{
return mEntries.cend ();
}
iterator begin ()
{
return mEntries.begin ();
}
iterator end ()
{
return mEntries.end ();
}
void setDeliveredAmount (STAmount const& amt)
{
mSet.setDeliveredAmount (amt);
}
TER issue_iou (Account const& account,
STAmount const& amount, Issue const& issue);
TER redeem_iou (Account const& account,
STAmount const& amount, Issue const& issue);
TER transfer_xrp (Account const& from, Account const& to, STAmount const& amount);
private:
Ledger::pointer mLedger;
std::map<uint256, LedgerEntrySetEntry> mEntries; // cannot be unordered!
// Defers credits made to accounts until later
boost::optional<DeferredCredits> mDeferredCredits;
using NodeToLedgerEntry = hash_map<uint256, SLE::pointer>;
TransactionMetaSet mSet;
TransactionEngineParams mParams;
int mSeq;
bool mImmutable;
LedgerEntrySet (
Ledger::ref ledger, const std::map<uint256, LedgerEntrySetEntry>& e,
const TransactionMetaSet & s, int m, boost::optional<DeferredCredits> const& ft) :
mLedger (ledger), mEntries (e), mDeferredCredits (ft), mSet (s), mParams (tapNONE),
mSeq (m), mImmutable (false)
{}
SLE::pointer getForMod (
uint256 const& node, Ledger::ref ledger,
NodeToLedgerEntry& newMods);
bool threadTx (
const RippleAddress & threadTo, Ledger::ref ledger,
NodeToLedgerEntry& newMods);
bool threadTx (
SLE::ref threadTo, Ledger::ref ledger, NodeToLedgerEntry& newMods);
bool threadOwners (std::shared_ptr<SLE const> const& node,
Ledger::ref ledger, NodeToLedgerEntry& newMods);
TER rippleSend (
Account const& uSenderID, Account const& uReceiverID,
const STAmount & saAmount, STAmount & saActual);
STAmount rippleHolds (
Account const& account, Currency const& currency,
Account const& issuer, FreezeHandling zeroIfFrozen);
STAmount rippleTransferFee (
Account const& from, Account const& to,
Account const& issuer, STAmount const& saAmount);
bool checkState (SLE::pointer state, bool bSenderHigh,
Account const& sender, STAmount const& before, STAmount const& after);
STAmount adjustedBalance (Account const& main,
Account const& other,
STAmount const& amount) const;
void cacheCredit (Account const& sender,
Account const& receiver,
STAmount const& amount);
};
using LedgerView = LedgerEntrySet;
/** @} */
//------------------------------------------------------------------------------
class ScopedDeferCredits
{
private:
LedgerEntrySet& les_;
bool enabled_;
public:
ScopedDeferCredits(LedgerEntrySet& l);
~ScopedDeferCredits ();
};
// NIKB FIXME: move these to the right place
std::uint32_t
rippleTransferRate (LedgerEntrySet& ledger, Account const& issuer);
std::uint32_t
rippleTransferRate (LedgerEntrySet& ledger, Account const& uSenderID,
Account const& uReceiverID, Account const& issuer);
} // ripple
#endif