Cleanup and simplifications to SHAMap:

SHAMapTreeNode
* Remove SHAMapTreeNode::pointer and SHAMapTreeNode::ref.
* Add std includes necessary to make the header standalone.
* Remove implementation from the SHAMapTreeNode declaration.
* Make clear what part of SHAMapTreeNode is:
  1) Truly public.
  2) Used only by SHAMap.
  3) Truly private to SHAMapTreeNode.

SHAMapItem
* Remove SHAMapItem::pointer and SHAMapItem::ref.
* Add std includes necessary to make the header standalone.
* Remove implementation from the SHAMapItem declaration.
* Make clear what part of SHAMapItem is:
  1) Truly public.
  2) Used only by SHAMapTreeNode.
  3) Truly private to SHAMapItem.

SHAMapSyncFilter
* Add override for SHAMapSyncFilter-derived functions.
* Add missing header.
* Default the destructor and delete the SHAMapSyncFilter copy members.

SHAMapNodeID
* Remove unused mHash member.
* Remove unused std::hash and boost::hash specializations.
* Remove unused constructor.
* Remove unused comparison with uint256.
* Remove unused getNodeID (int depth, uint256 const& hash).
* Remove virtual specifier from getString().
* Fix operator<= and operator>=.
* Document what API is used outside of SHAMap.
* Move inline definitions outside of the class declaration.

SHAMapMissingNode
* Make SHAMapType a enum class to prevent unwanted conversions.
* Remove needless ~SHAMapMissingNode() declaration/definition.
* Add referenced std includes.

SHAMapAddNode
* Make SHAMapAddNode (int good, int bad, int duplicate) ctor private.
* Move all member function definitions out of the class declaration.
* Remove dependence on beast::lexicalCastThrow.
* Make getGood() const.
* Make get() const.
* Add #include <string>.

SHAMap
* Remove unused enum STATE_MAP_BUCKETS.
* Remove unused getCountedObjectName().
* Remove SHAMap::pointer
* Remove SHAMap::ref
* Remove unused fetchPackEntry_t.
* Remove inline member function definitions from class declaration.
* Remove unused getTrustedPath.
* Remove unused getPath.
* Remove unused visitLeavesInternal.
* Make SHAMapState an enum class.
* Explicitly delete SHAMap copy members.
* Reduce access to nested types as much as possible.
* Normalize member data names to one style.

* Change last of the typedefs to usings under shamap.
* Reorder some includes ripple-first, beast-second.
* Declare a few constructions from make_shared with auto.
* Mark those SHAMap member functions which can be, with const.

* Add missing includes
This commit is contained in:
Howard Hinnant
2015-02-09 22:06:07 -05:00
committed by Vinnie Falco
parent 315a8b6b60
commit ec1e6b9385
54 changed files with 1048 additions and 1296 deletions

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include <BeastConfig.h>
#include <beast/module/core/text/LexicalCast.h>
#include <ripple/app/consensus/DisputedTx.h>
#include <ripple/app/consensus/LedgerConsensus.h>
#include <ripple/app/ledger/InboundLedgers.h>
@@ -319,7 +320,8 @@ public:
@return Pointer to the transaction tree if we got it, else
nullptr.
*/
SHAMap::pointer getTransactionTree (uint256 const& hash, bool doAcquire)
std::shared_ptr<SHAMap>
getTransactionTree (uint256 const& hash, bool doAcquire)
{
auto it = mAcquired.find (hash);
@@ -328,7 +330,7 @@ public:
if (mState == lcsPRE_CLOSE)
{
SHAMap::pointer currentMap
std::shared_ptr<SHAMap> currentMap
= getApp().getLedgerMaster ().getCurrentLedger ()
->peekTransactionMap ();
@@ -350,8 +352,8 @@ public:
{
if (hash.isZero ())
{
SHAMap::pointer empty = std::make_shared<SHAMap> (
smtTRANSACTION, getApp().family(),
auto empty = std::make_shared<SHAMap> (
SHAMapType::TRANSACTION, getApp().family(),
deprecatedLogs().journal("SHAMap"));
mapCompleteInternal (hash, empty, false);
return empty;
@@ -362,7 +364,7 @@ public:
}
}
return SHAMap::pointer ();
return std::shared_ptr<SHAMap> ();
}
/**
@@ -372,7 +374,8 @@ public:
@param map the transaction set.
@param acquired true if we have acquired the transaction set.
*/
void mapComplete (uint256 const& hash, SHAMap::ref map, bool acquired)
void mapComplete (uint256 const& hash, std::shared_ptr<SHAMap> const& map,
bool acquired)
{
try
{
@@ -387,7 +390,8 @@ public:
}
}
void mapCompleteInternal (uint256 const& hash, SHAMap::ref map, bool acquired)
void mapCompleteInternal (uint256 const& hash,
std::shared_ptr<SHAMap> const& map, bool acquired)
{
CondLog (acquired, lsINFO, LedgerConsensus)
<< "We have acquired TXS " << hash;
@@ -904,7 +908,7 @@ public:
<< newPosition->getCurrentHash ();
currentPosition = newPosition;
SHAMap::pointer set
std::shared_ptr<SHAMap> set
= getTransactionTree (newPosition->getCurrentHash (), true);
if (set)
@@ -998,7 +1002,7 @@ private:
@param set Our consensus set
*/
void accept (SHAMap::pointer set)
void accept (std::shared_ptr<SHAMap> set)
{
{
@@ -1282,7 +1286,8 @@ private:
@param m1 One transaction set
@param m2 The other transaction set
*/
void createDisputes (SHAMap::ref m1, SHAMap::ref m2)
void createDisputes (std::shared_ptr<SHAMap> const& m1,
std::shared_ptr<SHAMap> const& m2)
{
if (m1->getHash() == m2->getHash())
return;
@@ -1381,7 +1386,8 @@ private:
@param map A disputed position
@param peers peers which are taking the position map
*/
void adjustCount (SHAMap::ref map, const std::vector<NodeID>& peers)
void adjustCount (std::shared_ptr<SHAMap> const& map,
const std::vector<NodeID>& peers)
{
for (auto& it : mDisputes)
{
@@ -1512,13 +1518,13 @@ private:
*/
void takeInitialPosition (Ledger& initialLedger)
{
SHAMap::pointer initialSet;
std::shared_ptr<SHAMap> initialSet;
if ((getConfig ().RUN_STANDALONE || (mProposing && mHaveCorrectLCL))
&& ((mPreviousLedger->getLedgerSeq () % 256) == 0))
{
// previous ledger was flag ledger
SHAMap::pointer preSet
std::shared_ptr<SHAMap> preSet
= initialLedger.peekTransactionMap ()->snapShot (true);
m_feeVote.doVoting (mPreviousLedger, preSet);
getApp().getAmendmentTable ().doVoting (mPreviousLedger, preSet);
@@ -1604,7 +1610,7 @@ private:
peerCutoff -= boost::posix_time::seconds (PROPOSE_FRESHNESS);
bool changes = false;
SHAMap::pointer ourPosition;
std::shared_ptr<SHAMap> ourPosition;
// std::vector<uint256> addedTx, removedTx;
// Verify freshness of peer positions and compute close times
@@ -1889,7 +1895,7 @@ private:
*/
void beginAccept (bool synchronous)
{
SHAMap::pointer consensusSet
std::shared_ptr<SHAMap> consensusSet
= mAcquired[mOurPosition->getCurrentHash ()];
if (!consensusSet)
@@ -1963,7 +1969,7 @@ private:
hash_map<NodeID, LedgerProposal::pointer> mPeerPositions;
// Transaction Sets, indexed by hash of transaction tree
hash_map<uint256, SHAMap::pointer> mAcquired;
hash_map<uint256, std::shared_ptr<SHAMap>> mAcquired;
hash_map<uint256, TransactionAcquire::pointer> mAcquiring;
// Peer sets
@@ -2069,15 +2075,15 @@ int applyTransaction (TransactionEngine& engine
@param retriableTransactions collect failed transactions in this set
@param openLgr true if applyLedger is open, else false.
*/
void applyTransactions (SHAMap::ref set, Ledger::ref applyLedger,
Ledger::ref checkLedger, CanonicalTXSet& retriableTransactions,
bool openLgr)
void applyTransactions (std::shared_ptr<SHAMap> const& set,
Ledger::ref applyLedger, Ledger::ref checkLedger,
CanonicalTXSet& retriableTransactions, bool openLgr)
{
TransactionEngine engine (applyLedger);
if (set)
{
for (SHAMapItem::pointer item = set->peekFirstItem (); !!item;
for (std::shared_ptr<SHAMapItem> item = set->peekFirstItem (); !!item;
item = set->peekNextItem (item->getTag ()))
{
// If the checkLedger doesn't have the transaction

View File

@@ -53,11 +53,11 @@ public:
virtual uint256 getLCL () = 0;
virtual SHAMap::pointer getTransactionTree (uint256 const& hash,
virtual std::shared_ptr<SHAMap> getTransactionTree (uint256 const& hash,
bool doAcquire) = 0;
virtual void mapComplete (uint256 const& hash, SHAMap::ref map,
bool acquired) = 0;
virtual void mapComplete (uint256 const& hash,
std::shared_ptr<SHAMap> const& map, bool acquired) = 0;
virtual bool stillNeedTXSet (uint256 const& hash) = 0;
@@ -97,7 +97,7 @@ make_LedgerConsensus (LedgerConsensus::clock_type& clock, LocalTxs& localtx,
std::uint32_t closeTime, FeeVote& feeVote);
void
applyTransactions(SHAMap::ref set, Ledger::ref applyLedger,
applyTransactions(std::shared_ptr<SHAMap> const& set, Ledger::ref applyLedger,
Ledger::ref checkLedger,
CanonicalTXSet& retriableTransactions, bool openLgr);

View File

@@ -35,7 +35,7 @@ AcceptedLedger::AcceptedLedger (Ledger::ref ledger) : mLedger (ledger)
{
SHAMap& txSet = *ledger->peekTransactionMap ();
for (SHAMapItem::pointer item = txSet.peekFirstItem (); item;
for (std::shared_ptr<SHAMapItem> item = txSet.peekFirstItem (); item;
item = txSet.peekNextItem (item->getTag ()))
{
SerialIter sit (item->peekSerializer ());

View File

@@ -36,11 +36,11 @@ public:
SHAMapNodeID const& id,
uint256 const& nodeHash,
Blob& nodeData,
SHAMapTreeNode::TNType);
SHAMapTreeNode::TNType) override;
bool haveNode (SHAMapNodeID const& id,
uint256 const& nodeHash,
Blob& nodeData);
Blob& nodeData) override;
};
} // ripple

View File

@@ -43,11 +43,11 @@ public:
SHAMapNodeID const& id,
uint256 const& nodeHash,
Blob& nodeData,
SHAMapTreeNode::TNType);
SHAMapTreeNode::TNType) override;
bool haveNode (SHAMapNodeID const& id,
uint256 const& nodeHash,
Blob& nodeData);
Blob& nodeData) override;
private:
NodeCache& m_nodeCache;

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h>
#include <ripple/app/ledger/DirectoryEntryIterator.h>
#include <ripple/basics/Log.h>
#include <ripple/protocol/JsonFields.h>
namespace ripple {

View File

@@ -24,6 +24,7 @@
#include <ripple/basics/Log.h>
#include <ripple/core/JobQueue.h>
#include <beast/cxx14/memory.h> // <memory>
#include <beast/module/core/text/LexicalCast.h>
namespace ripple {

View File

@@ -42,6 +42,7 @@
#include <ripple/json/to_string.h>
#include <ripple/nodestore/Database.h>
#include <ripple/protocol/HashPrefix.h>
#include <beast/module/core/text/LexicalCast.h>
#include <beast/unit_test/suite.h>
namespace ripple {
@@ -58,9 +59,9 @@ Ledger::Ledger (RippleAddress const& masterID, std::uint64_t startAmount)
, mValidHash (false)
, mAccepted (false)
, mImmutable (false)
, mTransactionMap (std::make_shared <SHAMap> (smtTRANSACTION,
, mTransactionMap (std::make_shared <SHAMap> (SHAMapType::TRANSACTION,
getApp().family(), deprecatedLogs().journal("SHAMap")))
, mAccountStateMap (std::make_shared <SHAMap> (smtSTATE,
, mAccountStateMap (std::make_shared <SHAMap> (SHAMapType::STATE,
getApp().family(), deprecatedLogs().journal("SHAMap")))
{
// special case: put coins in root account
@@ -104,9 +105,9 @@ Ledger::Ledger (uint256 const& parentHash,
, mAccepted (false)
, mImmutable (true)
, mTransactionMap (std::make_shared <SHAMap> (
smtTRANSACTION, transHash, getApp().family(),
SHAMapType::TRANSACTION, transHash, getApp().family(),
deprecatedLogs().journal("SHAMap")))
, mAccountStateMap (std::make_shared <SHAMap> (smtSTATE, accountHash,
, mAccountStateMap (std::make_shared <SHAMap> (SHAMapType::STATE, accountHash,
getApp().family(), deprecatedLogs().journal("SHAMap")))
{
updateHash ();
@@ -167,7 +168,7 @@ Ledger::Ledger (bool /* dummy */,
, mValidHash (false)
, mAccepted (false)
, mImmutable (false)
, mTransactionMap (std::make_shared <SHAMap> (smtTRANSACTION,
, mTransactionMap (std::make_shared <SHAMap> (SHAMapType::TRANSACTION,
getApp().family(), deprecatedLogs().journal("SHAMap")))
, mAccountStateMap (prevLedger.mAccountStateMap->snapShot (true))
{
@@ -236,10 +237,10 @@ Ledger::Ledger (std::uint32_t ledgerSeq, std::uint32_t closeTime)
mAccepted (false),
mImmutable (false),
mTransactionMap (std::make_shared <SHAMap> (
smtTRANSACTION, getApp().family(),
SHAMapType::TRANSACTION, getApp().family(),
deprecatedLogs().journal("SHAMap"))),
mAccountStateMap (std::make_shared <SHAMap> (
smtSTATE, getApp().family(),
SHAMapType::STATE, getApp().family(),
deprecatedLogs().journal("SHAMap")))
{
initializeFees ();
@@ -340,9 +341,9 @@ void Ledger::setRaw (Serializer& s, bool hasPrefix)
if (mValidHash)
{
mTransactionMap = std::make_shared<SHAMap> (smtTRANSACTION, mTransHash,
mTransactionMap = std::make_shared<SHAMap> (SHAMapType::TRANSACTION, mTransHash,
getApp().family(), deprecatedLogs().journal("SHAMap"));
mAccountStateMap = std::make_shared<SHAMap> (smtSTATE, mAccountHash,
mAccountStateMap = std::make_shared<SHAMap> (SHAMapType::STATE, mAccountHash,
getApp().family(), deprecatedLogs().journal("SHAMap"));
}
}
@@ -454,7 +455,7 @@ bool Ledger::addTransaction (
Transaction::pointer Ledger::getTransaction (uint256 const& transID) const
{
SHAMapTreeNode::TNType type;
SHAMapItem::pointer item = mTransactionMap->peekItem (transID, type);
std::shared_ptr<SHAMapItem> item = mTransactionMap->peekItem (transID, type);
if (!item)
return Transaction::pointer ();
@@ -490,7 +491,7 @@ Transaction::pointer Ledger::getTransaction (uint256 const& transID) const
}
STTx::pointer Ledger::getSTransaction (
SHAMapItem::ref item, SHAMapTreeNode::TNType type)
std::shared_ptr<SHAMapItem> const& item, SHAMapTreeNode::TNType type)
{
SerialIter sit (item->peekSerializer ());
@@ -508,7 +509,7 @@ STTx::pointer Ledger::getSTransaction (
}
STTx::pointer Ledger::getSMTransaction (
SHAMapItem::ref item, SHAMapTreeNode::TNType type,
std::shared_ptr<SHAMapItem> const& item, SHAMapTreeNode::TNType type,
TransactionMetaSet::pointer& txMeta) const
{
SerialIter sit (item->peekSerializer ());
@@ -537,7 +538,7 @@ bool Ledger::getTransaction (
TransactionMetaSet::pointer& meta) const
{
SHAMapTreeNode::TNType type;
SHAMapItem::pointer item = mTransactionMap->peekItem (txID, type);
std::shared_ptr<SHAMapItem> item = mTransactionMap->peekItem (txID, type);
if (!item)
return false;
@@ -582,7 +583,7 @@ bool Ledger::getTransactionMeta (
uint256 const& txID, TransactionMetaSet::pointer& meta) const
{
SHAMapTreeNode::TNType type;
SHAMapItem::pointer item = mTransactionMap->peekItem (txID, type);
std::shared_ptr<SHAMapItem> item = mTransactionMap->peekItem (txID, type);
if (!item)
return false;
@@ -600,7 +601,7 @@ bool Ledger::getTransactionMeta (
bool Ledger::getMetaHex (uint256 const& transID, std::string& hex) const
{
SHAMapTreeNode::TNType type;
SHAMapItem::pointer item = mTransactionMap->peekItem (transID, type);
std::shared_ptr<SHAMapItem> item = mTransactionMap->peekItem (transID, type);
if (!item)
return false;
@@ -1204,7 +1205,7 @@ LedgerStateParms Ledger::writeBack (LedgerStateParms parms, SLE::ref entry)
SLE::pointer Ledger::getSLE (uint256 const& uHash) const
{
SHAMapItem::pointer node = mAccountStateMap->peekItem (uHash);
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekItem (uHash);
if (!node)
return SLE::pointer ();
@@ -1216,7 +1217,7 @@ SLE::pointer Ledger::getSLEi (uint256 const& uId) const
{
uint256 hash;
SHAMapItem::pointer node = mAccountStateMap->peekItem (uId, hash);
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekItem (uId, hash);
if (!node)
return SLE::pointer ();
@@ -1346,7 +1347,7 @@ bool Ledger::visitAccountItems (
}
static void visitHelper (
std::function<void (SLE::ref)>& function, SHAMapItem::ref item)
std::function<void (SLE::ref)>& function, std::shared_ptr<SHAMapItem> const& item)
{
function (std::make_shared<SLE> (item->peekSerializer (), item->getTag ()));
}
@@ -1375,25 +1376,25 @@ void Ledger::visitStateItems (std::function<void (SLE::ref)> function) const
uint256 Ledger::getFirstLedgerIndex () const
{
SHAMapItem::pointer node = mAccountStateMap->peekFirstItem ();
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekFirstItem ();
return node ? node->getTag () : uint256 ();
}
uint256 Ledger::getLastLedgerIndex () const
{
SHAMapItem::pointer node = mAccountStateMap->peekLastItem ();
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekLastItem ();
return node ? node->getTag () : uint256 ();
}
uint256 Ledger::getNextLedgerIndex (uint256 const& uHash) const
{
SHAMapItem::pointer node = mAccountStateMap->peekNextItem (uHash);
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekNextItem (uHash);
return node ? node->getTag () : uint256 ();
}
uint256 Ledger::getNextLedgerIndex (uint256 const& uHash, uint256 const& uEnd) const
{
SHAMapItem::pointer node = mAccountStateMap->peekNextItem (uHash);
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekNextItem (uHash);
if ((!node) || (node->getTag () > uEnd))
return uint256 ();
@@ -1403,13 +1404,13 @@ uint256 Ledger::getNextLedgerIndex (uint256 const& uHash, uint256 const& uEnd) c
uint256 Ledger::getPrevLedgerIndex (uint256 const& uHash) const
{
SHAMapItem::pointer node = mAccountStateMap->peekPrevItem (uHash);
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekPrevItem (uHash);
return node ? node->getTag () : uint256 ();
}
uint256 Ledger::getPrevLedgerIndex (uint256 const& uHash, uint256 const& uBegin) const
{
SHAMapItem::pointer node = mAccountStateMap->peekNextItem (uHash);
std::shared_ptr<SHAMapItem> node = mAccountStateMap->peekNextItem (uHash);
if ((!node) || (node->getTag () < uBegin))
return uint256 ();
@@ -1430,7 +1431,7 @@ SLE::pointer Ledger::getASNodeI (uint256 const& nodeID, LedgerEntryType let) con
SLE::pointer Ledger::getASNode (
LedgerStateParms& parms, uint256 const& nodeID, LedgerEntryType let) const
{
SHAMapItem::pointer account = mAccountStateMap->peekItem (nodeID);
std::shared_ptr<SHAMapItem> account = mAccountStateMap->peekItem (nodeID);
if (!account)
{

View File

@@ -251,11 +251,11 @@ public:
boost::posix_time::ptime getCloseTime () const;
// low level functions
SHAMap::ref peekTransactionMap () const
std::shared_ptr<SHAMap> const& peekTransactionMap () const
{
return mTransactionMap;
}
SHAMap::ref peekAccountStateMap () const
std::shared_ptr<SHAMap> const& peekAccountStateMap () const
{
return mAccountStateMap;
}
@@ -286,9 +286,9 @@ public:
bool getMetaHex (uint256 const& transID, std::string & hex) const;
static STTx::pointer getSTransaction (
SHAMapItem::ref, SHAMapTreeNode::TNType);
std::shared_ptr<SHAMapItem> const&, SHAMapTreeNode::TNType);
STTx::pointer getSMTransaction (
SHAMapItem::ref, SHAMapTreeNode::TNType,
std::shared_ptr<SHAMapItem> const&, SHAMapTreeNode::TNType,
TransactionMetaSet::pointer & txMeta) const;
// high-level functions
@@ -486,8 +486,8 @@ private:
// Ripple cost of the reference transaction
std::uint64_t mBaseFee;
SHAMap::pointer mTransactionMap;
SHAMap::pointer mAccountStateMap;
std::shared_ptr<SHAMap> mTransactionMap;
std::shared_ptr<SHAMap> mAccountStateMap;
typedef RippleMutex StaticLockType;
typedef std::lock_guard <StaticLockType> StaticScopedLockType;

View File

@@ -1,330 +0,0 @@
//------------------------------------------------------------------------------
/*
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.
*/
//==============================================================================
#include <ripple/app/ledger/Ledger.h>
#include <ripple/app/consensus/LedgerConsensus.h>
#include <ripple/app/ledger/LedgerTiming.h>
#include <ripple/app/misc/CanonicalTXSet.h>
#include <ripple/app/transactors/Transactor.h>
#include <ripple/basics/seconds_clock.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/RippleAddress.h>
#include <ripple/protocol/STParsedJSON.h>
#include <ripple/protocol/TxFlags.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class Ledger_test : public beast::unit_test::suite
{
using TestAccount = std::pair<RippleAddress, unsigned>;
struct Amount
{
Amount (double value_, std::string currency_, TestAccount issuer_)
: value(value_)
, currency(currency_)
, issuer(issuer_)
{
}
double value;
std::string currency;
TestAccount issuer;
Json::Value
getJson() const
{
Json::Value tx_json;
tx_json[jss::currency] = currency;
tx_json[jss::issuer] = issuer.first.humanAccountID();
tx_json[jss::value] = std::to_string(value);
return tx_json;
}
};
// Helper function to parse a transaction in Json, sign it with account,
// and return it as a STTx
STTx
parseTransaction(TestAccount& account, Json::Value const& tx_json)
{
STParsedJSONObject parsed (std::string (jss::tx_json), tx_json);
std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
expect(sopTrans != nullptr);
sopTrans->setFieldVL(sfSigningPubKey, account.first.getAccountPublic());
return STTx(*sopTrans);
}
// Helper function to apply a transaction to a ledger
void
applyTransaction(Ledger::pointer const& ledger, STTx const& tx)
{
TransactionEngine engine(ledger);
bool didApply = false;
auto r = engine.applyTransaction(tx, tapOPEN_LEDGER | tapNO_CHECK_SIGN,
didApply);
expect(r == tesSUCCESS);
expect(didApply);
}
// Create genesis ledger from a start amount in drops, and the public
// master RippleAddress
Ledger::pointer
createGenesisLedger(std::uint64_t start_amount_drops, TestAccount const& master)
{
Ledger::pointer ledger = std::make_shared<Ledger>(master.first,
start_amount_drops);
ledger->updateHash();
ledger->setClosed();
expect(ledger->assertSane());
return ledger;
}
// Create an account represented by public RippleAddress and private
// RippleAddress
TestAccount
createAccount()
{
static RippleAddress const seed
= RippleAddress::createSeedGeneric ("masterpassphrase");
static RippleAddress const generator
= RippleAddress::createGeneratorPublic (seed);
static int iSeq = -1;
++iSeq;
return std::make_pair(RippleAddress::createAccountPublic(generator, iSeq),
std::uint64_t(0));
}
void
freezeAccount(TestAccount& account, Ledger::pointer const& ledger)
{
Json::Value tx_json;
tx_json[jss::TransactionType] = "AccountSet";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Account] = account.first.humanAccountID();
tx_json[jss::SetFlag] = asfGlobalFreeze;
tx_json[jss::Sequence] = ++account.second;
STTx tx = parseTransaction(account, tx_json);
applyTransaction(ledger, tx);
}
void
unfreezeAccount(TestAccount& account, Ledger::pointer const& ledger)
{
Json::Value tx_json;
tx_json[jss::TransactionType] = "AccountSet";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Account] = account.first.humanAccountID();
tx_json[jss::ClearFlag] = asfGlobalFreeze;
tx_json[jss::Sequence] = ++account.second;
STTx tx = parseTransaction(account, tx_json);
applyTransaction(ledger, tx);
}
void
makePayment(TestAccount& from, TestAccount const& to,
std::uint64_t amountDrops,
Ledger::pointer const& ledger)
{
Json::Value tx_json;
tx_json[jss::Account] = from.first.humanAccountID();
tx_json[jss::Amount] = std::to_string(amountDrops);
tx_json[jss::Destination] = to.first.humanAccountID();
tx_json[jss::TransactionType] = "Payment";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Sequence] = ++from.second;
tx_json[jss::Flags] = tfUniversal;
STTx tx = parseTransaction(from, tx_json);
applyTransaction(ledger, tx);
}
void
makePayment(TestAccount& from, TestAccount const& to,
std::string const& currency, std::string const& amount,
Ledger::pointer const& ledger)
{
Json::Value tx_json;
tx_json[jss::Account] = from.first.humanAccountID();
tx_json[jss::Amount] = Amount(std::stod(amount), currency, to).getJson();
tx_json[jss::Destination] = to.first.humanAccountID();
tx_json[jss::TransactionType] = "Payment";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Sequence] = ++from.second;
tx_json[jss::Flags] = tfUniversal;
STTx tx = parseTransaction(from, tx_json);
applyTransaction(ledger, tx);
}
void
createOffer(TestAccount& from, Amount const& in, Amount const& out,
Ledger::pointer ledger)
{
Json::Value tx_json;
tx_json[jss::TransactionType] = "OfferCreate";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Account] = from.first.humanAccountID();
tx_json[jss::TakerPays] = in.getJson();
tx_json[jss::TakerGets] = out.getJson();
tx_json[jss::Sequence] = ++from.second;
STTx tx = parseTransaction(from, tx_json);
applyTransaction(ledger, tx);
}
// As currently implemented, this will cancel only the last offer made
// from this account.
void
cancelOffer(TestAccount& from, Ledger::pointer ledger)
{
Json::Value tx_json;
tx_json[jss::TransactionType] = "OfferCancel";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Account] = from.first.humanAccountID();
tx_json[jss::OfferSequence] = from.second;
tx_json[jss::Sequence] = ++from.second;
STTx tx = parseTransaction(from, tx_json);
applyTransaction(ledger, tx);
}
void
makeTrustSet(TestAccount& from, TestAccount const& issuer,
std::string const& currency, double amount,
Ledger::pointer const& ledger)
{
Json::Value tx_json;
tx_json[jss::Account] = from.first.humanAccountID();
Json::Value& limitAmount = tx_json[jss::LimitAmount];
limitAmount[jss::currency] = currency;
limitAmount[jss::issuer] = issuer.first.humanAccountID();
limitAmount[jss::value] = std::to_string(amount);
tx_json[jss::TransactionType] = "TrustSet";
tx_json[jss::Fee] = std::to_string(10);
tx_json[jss::Sequence] = ++from.second;
tx_json[jss::Flags] = tfClearNoRipple;
STTx tx = parseTransaction(from, tx_json);
applyTransaction(ledger, tx);
}
Ledger::pointer
close_and_advance(Ledger::pointer ledger, Ledger::pointer LCL)
{
SHAMap::pointer set = ledger->peekTransactionMap();
CanonicalTXSet retriableTransactions(set->getHash());
Ledger::pointer newLCL = std::make_shared<Ledger>(false, *LCL);
// Set up to write SHAMap changes to our database,
// perform updates, extract changes
applyTransactions(set, newLCL, newLCL, retriableTransactions, false);
newLCL->updateSkipList();
newLCL->setClosed();
newLCL->peekAccountStateMap()->flushDirty(
hotACCOUNT_NODE, newLCL->getLedgerSeq());
newLCL->peekTransactionMap()->flushDirty(
hotTRANSACTION_NODE, newLCL->getLedgerSeq());
using namespace std::chrono;
auto const epoch_offset = days(10957); // 2000-01-01
std::uint32_t closeTime = time_point_cast<seconds> // now
(system_clock::now()-epoch_offset).
time_since_epoch().count();
int CloseResolution = seconds(LEDGER_TIME_ACCURACY).count();
bool closeTimeCorrect = true;
newLCL->setAccepted(closeTime, CloseResolution, closeTimeCorrect);
return newLCL;
}
void test_genesisLedger ()
{
std::uint64_t const xrp = std::mega::num;
// Create master account
auto master = createAccount();
// Create genesis ledger
Ledger::pointer LCL = createGenesisLedger(100000*xrp, master);
// Create open scratch ledger
Ledger::pointer ledger = std::make_shared<Ledger>(false, *LCL);
// Create user accounts
auto gw1 = createAccount();
auto gw2 = createAccount();
auto gw3 = createAccount();
auto alice = createAccount();
auto mark = createAccount();
// Fund gw1, gw2, gw3, alice, mark from master
makePayment(master, gw1, 5000*xrp, ledger);
makePayment(master, gw2, 4000*xrp, ledger);
makePayment(master, gw3, 3000*xrp, ledger);
makePayment(master, alice, 2000*xrp, ledger);
makePayment(master, mark, 1000*xrp, ledger);
LCL = close_and_advance(ledger, LCL);
ledger = std::make_shared<Ledger>(false, *LCL);
// alice trusts FOO/gw1
makeTrustSet(alice, gw1, "FOO", 1, ledger);
// mark trusts FOO/gw2
makeTrustSet(mark, gw2, "FOO", 1, ledger);
// mark trusts FOO/gw3
makeTrustSet(mark, gw3, "FOO", 1, ledger);
// gw2 pays mark with FOO
makePayment(gw2, mark, "FOO", ".1", ledger);
// gw3 pays mark with FOO
makePayment(gw3, mark, "FOO", ".2", ledger);
// gw1 pays alice with FOO
makePayment(gw1, alice, "FOO", ".3", ledger);
LCL = close_and_advance(ledger, LCL);
ledger = std::make_shared<Ledger>(false, *LCL);
createOffer(mark, Amount(1, "FOO", gw1), Amount(1, "FOO", gw2), ledger);
createOffer(mark, Amount(1, "FOO", gw2), Amount(1, "FOO", gw3), ledger);
cancelOffer(mark, ledger);
freezeAccount(alice, ledger);
LCL = close_and_advance(ledger, LCL);
ledger = std::make_shared<Ledger>(false, *LCL);
makePayment(alice, mark, 1*xrp, ledger);
LCL = close_and_advance(ledger, LCL);
ledger = std::make_shared<Ledger>(false, *LCL);
}
void test_getQuality ()
{
uint256 uBig (
"D2DC44E5DC189318DB36EF87D2104CDF0A0FE3A4B698BEEE55038D7EA4C68000");
expect (6125895493223874560 == getQuality (uBig));
}
public:
void run ()
{
test_genesisLedger ();
test_getQuality ();
}
};
BEAST_DEFINE_TESTSUITE(Ledger,ripple_app,ripple);
} // ripple

View File

@@ -24,6 +24,7 @@
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/main/Application.h>
#include <ripple/core/LoadFeeTrack.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/Protocol.h>
#include <ripple/protocol/RippleLedgerHash.h>
#include <beast/threads/Thread.h>

View File

@@ -213,13 +213,13 @@ void LedgerHistory::handleMismatch (LedgerHash const& built, LedgerHash const& v
std::vector <SHAMapItemInfo> builtTx, validTx;
// Get built ledger hashes and metadata
builtLedger->peekTransactionMap()->visitLeaves(
[&builtTx](SHAMapItem::ref item)
[&builtTx](std::shared_ptr<SHAMapItem> const& item)
{
builtTx.push_back({item->getTag(), item->peekData()});
});
// Get valid ledger hashes and metadata
validLedger->peekTransactionMap()->visitLeaves(
[&validTx](SHAMapItem::ref item)
[&validTx](std::shared_ptr<SHAMapItem> const& item)
{
validTx.push_back({item->getTag(), item->peekData()});
});

View File

@@ -176,7 +176,7 @@ void fillJson (Object& json, LedgerFill const& fill)
else
{
accountStateMap->visitLeaves(
[&array, &count] (SHAMapItem::ref smi)
[&array, &count] (std::shared_ptr<SHAMapItem> const& smi)
{
count.yield();
array.append (to_string(smi->getTag ()));

View File

@@ -63,6 +63,7 @@
#include <ripple/validators/make_Manager.h>
#include <ripple/unity/git_id.h>
#include <beast/asio/io_latency_probe.h>
#include <beast/module/core/text/LexicalCast.h>
#include <beast/module/core/thread/DeadlineTimer.h>
#include <boost/asio/signal_set.hpp>
#include <fstream>
@@ -1254,7 +1255,7 @@ bool ApplicationImp::loadOldLedger (
if (replay)
{
// inject transaction(s) from the replayLedger into our open ledger
SHAMap::ref txns = replayLedger->peekTransactionMap();
std::shared_ptr<SHAMap> const& txns = replayLedger->peekTransactionMap();
// Get a mutable snapshot of the open ledger
Ledger::pointer cur = getLedgerMaster().getCurrentLedger();

View File

@@ -23,6 +23,7 @@
#include <ripple/basics/StringUtilities.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/JsonFields.h>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>

View File

@@ -208,7 +208,8 @@ public:
virtual void
doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) = 0;
virtual void
doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) = 0;
doVoting (Ledger::ref lastClosedLedger,
std::shared_ptr<SHAMap> const& initialPosition) = 0;
};
std::unique_ptr<AmendmentTable> make_AmendmentTable (

View File

@@ -23,6 +23,7 @@
#include <ripple/app/misc/Validations.h>
#include <ripple/app/data/DatabaseCon.h>
#include <ripple/core/ConfigSections.h>
#include <ripple/protocol/JsonFields.h>
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <algorithm>
@@ -95,7 +96,8 @@ public:
Json::Value getJson (uint256 const&) override;
void doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) override;
void doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) override;
void doVoting (Ledger::ref lastClosedLedger,
std::shared_ptr<SHAMap> const& initialPosition) override;
amendmentList_t getVetoed();
amendmentList_t getEnabled();
@@ -518,7 +520,7 @@ AmendmentTableImpl<AppApiFacade>::doValidation (Ledger::ref lastClosedLedger,
template<class AppApiFacade>
void
AmendmentTableImpl<AppApiFacade>::doVoting (Ledger::ref lastClosedLedger,
SHAMap::ref initialPosition)
std::shared_ptr<SHAMap> const& initialPosition)
{
// LCL must be flag ledger
@@ -566,7 +568,7 @@ AmendmentTableImpl<AppApiFacade>::doVoting (Ledger::ref lastClosedLedger,
Serializer s;
trans.add (s, true);
#if RIPPLE_PROPOSE_AMENDMENTS
SHAMapItem::pointer tItem = std::make_shared<SHAMapItem> (txID, s.peekData ());
auto tItem = std::make_shared<SHAMapItem> (txID, s.peekData ());
if (!initialPosition->addGiveItem (tItem, true, false))
{
if (m_journal.warning) m_journal.warning <<

View File

@@ -67,7 +67,7 @@ public:
virtual
void
doVoting (Ledger::ref lastClosedLedger,
SHAMap::ref initialPosition) = 0;
std::shared_ptr<SHAMap> const& initialPosition) = 0;
};
/** Build FeeVote::Setup from a config section. */

View File

@@ -102,7 +102,7 @@ public:
void
doVoting (Ledger::ref lastClosedLedger,
SHAMap::ref initialPosition) override;
std::shared_ptr<SHAMap> const& initialPosition) override;
};
//--------------------------------------------------------------------------
@@ -145,7 +145,7 @@ FeeVoteImpl::doValidation (Ledger::ref lastClosedLedger,
void
FeeVoteImpl::doVoting (Ledger::ref lastClosedLedger,
SHAMap::ref initialPosition)
std::shared_ptr<SHAMap> const& initialPosition)
{
// LCL must be flag ledger
assert ((lastClosedLedger->getLedgerSeq () % 256) == 0);
@@ -228,8 +228,7 @@ FeeVoteImpl::doVoting (Ledger::ref lastClosedLedger,
Serializer s;
trans.add (s, true);
SHAMapItem::pointer tItem = std::make_shared<SHAMapItem> (
txID, s.peekData ());
auto tItem = std::make_shared<SHAMapItem> (txID, s.peekData ());
if (!initialPosition->addGiveItem (tItem, true, false))
{

View File

@@ -56,6 +56,7 @@
#include <ripple/resource/Fees.h>
#include <ripple/resource/Gossip.h>
#include <ripple/resource/Manager.h>
#include <beast/module/core/text/LexicalCast.h>
#include <beast/module/core/thread/DeadlineTimer.h>
#include <beast/module/core/system/SystemStats.h>
#include <beast/cxx14/memory.h> // <memory>
@@ -292,13 +293,13 @@ public:
bool recvValidation (
STValidation::ref val, std::string const& source);
void takePosition (int seq, SHAMap::ref position);
SHAMap::pointer getTXMap (uint256 const& hash);
void takePosition (int seq, std::shared_ptr<SHAMap> const& position);
std::shared_ptr<SHAMap> getTXMap (uint256 const& hash);
bool hasTXSet (
const std::shared_ptr<Peer>& peer, uint256 const& set,
protocol::TxSetStatus status);
void mapComplete (uint256 const& hash, SHAMap::ref map);
void mapComplete (uint256 const& hash, std::shared_ptr<SHAMap> const& map);
bool stillNeedTXSet (uint256 const& hash);
void makeFetchPack (
Job&, std::weak_ptr<Peer> peer,
@@ -577,7 +578,7 @@ private:
STValidation::pointer mLastValidation;
// Recent positions taken
std::map<uint256, std::pair<int, SHAMap::pointer> > mRecentPositions;
std::map<uint256, std::pair<int, std::shared_ptr<SHAMap>>> mRecentPositions;
SubInfoMapType mSubAccount;
SubInfoMapType mSubRTAccount;
@@ -1657,7 +1658,8 @@ void NetworkOPsImp::processTrustedProposal (
}
// Must be called while holding the master lock
SHAMap::pointer NetworkOPsImp::getTXMap (uint256 const& hash)
std::shared_ptr<SHAMap>
NetworkOPsImp::getTXMap (uint256 const& hash)
{
auto it = mRecentPositions.find (hash);
@@ -1665,13 +1667,14 @@ SHAMap::pointer NetworkOPsImp::getTXMap (uint256 const& hash)
return it->second.second;
if (!haveConsensusObject ())
return SHAMap::pointer ();
return std::shared_ptr<SHAMap> ();
return mConsensus->getTransactionTree (hash, false);
}
// Must be called while holding the master lock
void NetworkOPsImp::takePosition (int seq, SHAMap::ref position)
void
NetworkOPsImp::takePosition (int seq, std::shared_ptr<SHAMap> const& position)
{
mRecentPositions[position->getHash ()] = std::make_pair (seq, position);
@@ -1726,7 +1729,9 @@ bool NetworkOPsImp::stillNeedTXSet (uint256 const& hash)
return mConsensus->stillNeedTXSet (hash);
}
void NetworkOPsImp::mapComplete (uint256 const& hash, SHAMap::ref map)
void
NetworkOPsImp::mapComplete (uint256 const& hash,
std::shared_ptr<SHAMap> const& map)
{
if (haveConsensusObject ())
mConsensus->mapComplete (hash, map, true);

View File

@@ -217,14 +217,16 @@ public:
virtual bool recvValidation (STValidation::ref val,
std::string const& source) = 0;
virtual void takePosition (int seq, SHAMap::ref position) = 0;
virtual void takePosition (int seq,
std::shared_ptr<SHAMap> const& position) = 0;
virtual SHAMap::pointer getTXMap (uint256 const& hash) = 0;
virtual std::shared_ptr<SHAMap> getTXMap (uint256 const& hash) = 0;
virtual bool hasTXSet (const std::shared_ptr<Peer>& peer,
uint256 const& set, protocol::TxSetStatus status) = 0;
virtual void mapComplete (uint256 const& hash, SHAMap::ref map) = 0;
virtual void mapComplete (uint256 const& hash,
std::shared_ptr<SHAMap> const& map) = 0;
virtual bool stillNeedTXSet (uint256 const& hash) = 0;

View File

@@ -31,6 +31,7 @@
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/UintTypes.h>
#include <beast/module/core/text/LexicalCast.h>
#include <boost/log/trivial.hpp>
#include <tuple>

View File

@@ -22,6 +22,7 @@
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/main/Application.h>
#include <ripple/core/JobQueue.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/resource/Fees.h>
namespace ripple {

View File

@@ -23,6 +23,7 @@
#include <ripple/basics/Log.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/JsonFields.h>
#include <boost/lexical_cast.hpp>
namespace ripple {

View File

@@ -31,6 +31,7 @@
#include <ripple/core/Config.h>
#include <ripple/core/LoadFeeTrack.h>
#include <ripple/net/HTTPClient.h>
#include <ripple/protocol/JsonFields.h>
#include <beast/module/core/thread/DeadlineTimer.h>
#include <beast/cxx14/memory.h> // <memory>
#include <boost/algorithm/string.hpp>

View File

@@ -234,7 +234,7 @@ makeTrustSet(TestAccount& from, TestAccount const& issuer,
Ledger::pointer
close_and_advance(Ledger::pointer ledger, Ledger::pointer LCL)
{
SHAMap::pointer set = ledger->peekTransactionMap();
std::shared_ptr<SHAMap> set = ledger->peekTransactionMap();
CanonicalTXSet retriableTransactions(set->getHash());
Ledger::pointer newLCL = std::make_shared<Ledger>(false, *LCL);
// Set up to write SHAMap changes to our database,

View File

@@ -40,7 +40,7 @@ TransactionAcquire::TransactionAcquire (uint256 const& hash, clock_type& clock)
deprecatedLogs().journal("TransactionAcquire"))
, mHaveRoot (false)
{
mMap = std::make_shared<SHAMap> (smtTRANSACTION, hash,
mMap = std::make_shared<SHAMap> (SHAMapType::TRANSACTION, hash,
getApp().family(), deprecatedLogs().journal("SHAMap"));
mMap->setUnbacked ();
}
@@ -49,7 +49,7 @@ TransactionAcquire::~TransactionAcquire ()
{
}
static void TACompletionHandler (uint256 hash, SHAMap::pointer map)
static void TACompletionHandler (uint256 hash, std::shared_ptr<SHAMap> map)
{
{
Application::ScopedLockType lock (getApp ().getMasterLock ());
@@ -63,7 +63,7 @@ static void TACompletionHandler (uint256 hash, SHAMap::pointer map)
void TransactionAcquire::done ()
{
// We hold a PeerSet lock and so cannot acquire the master lock here
SHAMap::pointer map;
std::shared_ptr<SHAMap> map;
if (mFailed)
{

View File

@@ -41,7 +41,7 @@ public:
TransactionAcquire (uint256 const& hash, clock_type& clock);
~TransactionAcquire ();
SHAMap::ref getMap ()
std::shared_ptr<SHAMap> const& getMap ()
{
return mMap;
}
@@ -50,7 +50,7 @@ public:
const std::list< Blob >& data, Peer::ptr const&);
private:
SHAMap::pointer mMap;
std::shared_ptr<SHAMap> mMap;
bool mHaveRoot;
void onTimer (bool progress, ScopedLockType& peerSetLock);

View File

@@ -59,7 +59,7 @@ Transaction::pointer TransactionMaster::fetch (uint256 const& txnID, bool checkD
return txn;
}
STTx::pointer TransactionMaster::fetch (SHAMapItem::ref item,
STTx::pointer TransactionMaster::fetch (std::shared_ptr<SHAMapItem> const& item,
SHAMapTreeNode::TNType type,
bool checkDisk, std::uint32_t uCommitLedger)
{

View File

@@ -34,7 +34,7 @@ public:
TransactionMaster ();
Transaction::pointer fetch (uint256 const& , bool checkDisk);
STTx::pointer fetch (SHAMapItem::ref item, SHAMapTreeNode:: TNType type,
STTx::pointer fetch (std::shared_ptr<SHAMapItem> const& item, SHAMapTreeNode:: TNType type,
bool checkDisk, std::uint32_t uCommitLedger);
// return value: true = we had the transaction already

View File

@@ -34,6 +34,7 @@
#include <ripple/resource/Fees.h>
#include <ripple/server/ServerHandler.h>
#include <ripple/protocol/BuildInfo.h>
#include <ripple/protocol/JsonFields.h>
#include <beast/streams/debug_ostream.h>
#include <beast/weak_fn.h>
#include <boost/asio/io_service.hpp>
@@ -1719,7 +1720,7 @@ void
PeerImp::getLedger (std::shared_ptr<protocol::TMGetLedger> const& m)
{
protocol::TMGetLedger& packet = *m;
SHAMap::pointer map;
std::shared_ptr<SHAMap> map;
protocol::TMLedgerData reply;
bool fatLeaves = true, fatRoot = false;
@@ -1949,7 +1950,7 @@ PeerImp::getLedger (std::shared_ptr<protocol::TMGetLedger> const& m)
reply.add_nodes ()->set_nodedata (
nData.getDataPtr (), nData.getLength ());
SHAMap::pointer map = ledger->peekAccountStateMap ();
std::shared_ptr<SHAMap> map = ledger->peekAccountStateMap ();
if (map && map->getHash ().isNonZero ())
{

View File

@@ -21,6 +21,7 @@
#include <ripple/basics/Log.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/STAccount.h>
#include <ripple/protocol/STLedgerEntry.h>
#include <boost/format.hpp>

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h>
#include <ripple/basics/Log.h>
#include <ripple/protocol/HashPrefix.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/Protocol.h>
#include <ripple/protocol/STAccount.h>
#include <ripple/protocol/STArray.h>

View File

@@ -19,6 +19,7 @@
#include <BeastConfig.h>
#include <ripple/app/misc/SHAMapStore.h>
#include <beast/module/core/text/LexicalCast.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/format.hpp>

View File

@@ -19,6 +19,7 @@
#include <BeastConfig.h>
#include <ripple/app/misc/AmendmentTable.h>
#include <beast/module/core/text/LexicalCast.h>
namespace ripple {

View File

@@ -79,7 +79,7 @@ Json::Value doLedgerData (RPC::Context& context)
for (;;)
{
SHAMapItem::pointer item = map.peekNextItem (resumePoint);
std::shared_ptr<SHAMapItem> item = map.peekNextItem (resumePoint);
if (!item)
break;
resumePoint = item->getTag();

View File

@@ -37,7 +37,7 @@ template <class Key>
class BasicFullBelowCache
{
private:
typedef KeyCache <Key> CacheType;
using CacheType = KeyCache <Key>;
public:
enum
@@ -46,9 +46,9 @@ public:
,defaultCacheExpirationSeconds = 120
};
typedef Key key_type;
typedef typename CacheType::size_type size_type;
typedef typename CacheType::clock_type clock_type;
using key_type = Key;
using size_type = typename CacheType::size_type;
using clock_type = typename CacheType::clock_type ;
/** Construct the cache.

View File

@@ -114,10 +114,10 @@ The `fetchNodeExternalNT()` method goes through three phases:
in the historic data stored by the data base. The call to
to `fetch(hash)` does that work for us.
3. Finally, if mLedgerSeq is non-zero and we did't locate the node in the
3. Finally, if ledgerSeq_ is non-zero and we did't locate the node in the
historic data, then we call a MissingNodeHandler.
The non-zero mLedgerSeq indicates that the SHAMap is a complete map that
The non-zero ledgerSeq_ indicates that the SHAMap is a complete map that
belongs to a historic ledger with the given (non-zero) sequence number.
So, if all expected data is always present, the MissingNodeHandler should
never be executed.

View File

@@ -28,6 +28,7 @@
#include <ripple/shamap/SHAMapNodeID.h>
#include <ripple/shamap/SHAMapSyncFilter.h>
#include <ripple/shamap/SHAMapTreeNode.h>
#include <ripple/shamap/TreeNodeCache.h>
#include <ripple/basics/UnorderedContainers.h>
#include <ripple/nodestore/Database.h>
#include <ripple/nodestore/NodeObject.h>
@@ -37,41 +38,15 @@
#include <boost/thread/shared_mutex.hpp>
#include <stack>
namespace std {
template <>
struct hash <ripple::SHAMapNodeID>
{
std::size_t operator() (ripple::SHAMapNodeID const& value) const
{
return value.getMHash ();
}
};
}
//------------------------------------------------------------------------------
namespace boost {
template <>
struct hash <ripple::SHAMapNodeID> : std::hash <ripple::SHAMapNodeID>
{
};
}
//------------------------------------------------------------------------------
namespace ripple {
enum SHAMapState
enum class SHAMapState
{
smsModifying = 0, // Objects can be added and removed (like an open ledger)
smsImmutable = 1, // Map cannot be changed (like a closed ledger)
smsSynching = 2, // Map's hash is locked in, valid nodes can be added (like a peer's closing ledger)
smsFloating = 3, // Map is free to change hash (like a synching open ledger)
smsInvalid = 4, // Map is known not to be valid (usually synching a corrupt ledger)
Modifying = 0, // Objects can be added and removed (like an open ledger)
Immutable = 1, // Map cannot be changed (like a closed ledger)
Synching = 2, // Map's hash is locked in, valid nodes can be added (like a peer's closing ledger)
Floating = 3, // Map is free to change hash (like a synching open ledger)
Invalid = 4, // Map is known not to be valid (usually synching a corrupt ledger)
};
/** Function object which handles missing nodes. */
@@ -106,31 +81,22 @@ private:
Family& f_;
beast::Journal journal_;
std::uint32_t mSeq;
std::uint32_t mLedgerSeq; // sequence number of ledger this is part of
SHAMapTreeNode::pointer root;
SHAMapState mState;
SHAMapType mType;
bool mBacked = true; // Map is backed by the database
std::uint32_t seq_;
std::uint32_t ledgerSeq_; // sequence number of ledger this is part of
std::shared_ptr<SHAMapTreeNode> root_;
SHAMapState state_;
SHAMapType type_;
bool backed_ = true; // Map is backed by the database
public:
enum
{
STATE_MAP_BUCKETS = 1024
};
using DeltaItem = std::pair<std::shared_ptr<SHAMapItem>,
std::shared_ptr<SHAMapItem>>;
using Delta = std::map<uint256, DeltaItem>;
static char const* getCountedObjectName () { return "SHAMap"; }
~SHAMap ();
SHAMap(SHAMap const&) = delete;
SHAMap& operator=(SHAMap const&) = delete;
typedef std::shared_ptr<SHAMap> pointer;
typedef const std::shared_ptr<SHAMap>& ref;
typedef std::pair<SHAMapItem::pointer, SHAMapItem::pointer> DeltaItem;
typedef std::pair<SHAMapItem::ref, SHAMapItem::ref> DeltaRef;
typedef std::map<uint256, DeltaItem> Delta;
typedef std::stack<std::pair<SHAMapTreeNode::pointer, SHAMapNodeID>> SharedPtrNodeStack;
public:
// build new map
SHAMap (
SHAMapType t,
@@ -145,55 +111,44 @@ public:
Family& f,
beast::Journal journal);
~SHAMap ();
// Returns a new map that's a snapshot of this one.
// Handles copy on write for mutable snapshots.
SHAMap::pointer snapShot (bool isMutable);
void setLedgerSeq (std::uint32_t lseq)
{
mLedgerSeq = lseq;
}
std::shared_ptr<SHAMap> snapShot (bool isMutable) const;
void setLedgerSeq (std::uint32_t lseq);
bool fetchRoot (uint256 const& hash, SHAMapSyncFilter * filter);
// normal hash access functions
bool hasItem (uint256 const& id);
bool delItem (uint256 const& id);
bool addItem (SHAMapItem const& i, bool isTransaction, bool hasMeta);
uint256 getHash () const
{
return root->getNodeHash ();
}
uint256 getHash () const;
// save a copy if you have a temporary anyway
bool updateGiveItem (SHAMapItem::ref, bool isTransaction, bool hasMeta);
bool addGiveItem (SHAMapItem::ref, bool isTransaction, bool hasMeta);
bool updateGiveItem (std::shared_ptr<SHAMapItem> const&, bool isTransaction, bool hasMeta);
bool addGiveItem (std::shared_ptr<SHAMapItem> const&, bool isTransaction, bool hasMeta);
// save a copy if you only need a temporary
SHAMapItem::pointer peekItem (uint256 const& id);
SHAMapItem::pointer peekItem (uint256 const& id, uint256 & hash);
SHAMapItem::pointer peekItem (uint256 const& id, SHAMapTreeNode::TNType & type);
std::shared_ptr<SHAMapItem> peekItem (uint256 const& id);
std::shared_ptr<SHAMapItem> peekItem (uint256 const& id, uint256 & hash);
std::shared_ptr<SHAMapItem> peekItem (uint256 const& id, SHAMapTreeNode::TNType & type);
// traverse functions
SHAMapItem::pointer peekFirstItem ();
SHAMapItem::pointer peekFirstItem (SHAMapTreeNode::TNType & type);
SHAMapItem::pointer peekLastItem ();
SHAMapItem::pointer peekNextItem (uint256 const& );
SHAMapItem::pointer peekNextItem (uint256 const& , SHAMapTreeNode::TNType & type);
SHAMapItem::pointer peekPrevItem (uint256 const& );
std::shared_ptr<SHAMapItem> peekFirstItem ();
std::shared_ptr<SHAMapItem> peekFirstItem (SHAMapTreeNode::TNType & type);
std::shared_ptr<SHAMapItem> peekLastItem ();
std::shared_ptr<SHAMapItem> peekNextItem (uint256 const& );
std::shared_ptr<SHAMapItem> peekNextItem (uint256 const& , SHAMapTreeNode::TNType & type);
std::shared_ptr<SHAMapItem> peekPrevItem (uint256 const& );
void visitNodes (std::function<bool (SHAMapTreeNode&)> const&);
void visitLeaves(std::function<void (SHAMapItem::ref)> const&);
void visitLeaves(std::function<void (std::shared_ptr<SHAMapItem> const&)> const&);
// comparison/sync functions
void getMissingNodes (std::vector<SHAMapNodeID>& nodeIDs, std::vector<uint256>& hashes, int max,
SHAMapSyncFilter * filter);
bool getNodeFat (SHAMapNodeID node, std::vector<SHAMapNodeID>& nodeIDs,
std::list<Blob >& rawNode, bool fatRoot, bool fatLeaves);
bool getRootNode (Serializer & s, SHANodeFormat format);
bool getRootNode (Serializer & s, SHANodeFormat format) const;
std::vector<uint256> getNeededHashes (int max, SHAMapSyncFilter * filter);
SHAMapAddNode addRootNode (uint256 const& hash, Blob const& rootNode, SHANodeFormat format,
SHAMapSyncFilter * filter);
@@ -203,37 +158,19 @@ public:
SHAMapSyncFilter * filter);
// status functions
void setImmutable ()
{
assert (mState != smsInvalid);
mState = smsImmutable;
}
bool isSynching () const
{
return (mState == smsFloating) || (mState == smsSynching);
}
void setSynching ()
{
mState = smsSynching;
}
void clearSynching ()
{
mState = smsModifying;
}
bool isValid ()
{
return mState != smsInvalid;
}
void setImmutable ();
bool isSynching () const;
void setSynching ();
void clearSynching ();
bool isValid () const;
// caution: otherMap must be accessed only by this function
// return value: true=successfully completed, false=too different
bool compare (SHAMap::ref otherMap, Delta & differences, int maxCount);
bool compare (std::shared_ptr<SHAMap> const& otherMap,
Delta& differences, int maxCount); // HINNANT should be const
int flushDirty (NodeObjectType t, std::uint32_t seq);
int unshare ();
void walkMap (std::vector<SHAMapMissingNode>& missingNodes, int maxMissing);
bool deepCompare (SHAMap & other);
typedef std::pair <uint256, Blob> fetchPackEntry_t;
@@ -243,41 +180,36 @@ public:
void getFetchPack (SHAMap * have, bool includeLeaves, int max,
std::function<void (uint256 const&, const Blob&)>);
void setUnbacked ()
{
mBacked = false;
}
void setUnbacked ();
void dump (bool withHashes = false);
void dump (bool withHashes = false) const;
private:
// trusted path operations - prove a particular node is in a particular ledger
std::list<Blob > getTrustedPath (uint256 const& index);
using SharedPtrNodeStack =
std::stack<std::pair<std::shared_ptr<SHAMapTreeNode>, SHAMapNodeID>>;
using DeltaRef = std::pair<std::shared_ptr<SHAMapItem> const&,
std::shared_ptr<SHAMapItem> const&> ;
bool getPath (uint256 const& index, std::vector< Blob >& nodes, SHANodeFormat format);
int unshare ();
// tree node cache operations
SHAMapTreeNode::pointer getCache (uint256 const& hash);
void canonicalize (uint256 const& hash, SHAMapTreeNode::pointer&);
std::shared_ptr<SHAMapTreeNode> getCache (uint256 const& hash) const;
void canonicalize (uint256 const& hash, std::shared_ptr<SHAMapTreeNode>&) const;
// database operations
SHAMapTreeNode::pointer fetchNodeFromDB (uint256 const& hash);
SHAMapTreeNode::pointer fetchNodeNT (uint256 const& hash);
SHAMapTreeNode::pointer fetchNodeNT (
std::shared_ptr<SHAMapTreeNode> fetchNodeFromDB (uint256 const& hash);
std::shared_ptr<SHAMapTreeNode> fetchNodeNT (uint256 const& hash);
std::shared_ptr<SHAMapTreeNode> fetchNodeNT (
SHAMapNodeID const& id,
uint256 const& hash,
SHAMapSyncFilter *filter);
SHAMapTreeNode::pointer fetchNode (uint256 const& hash);
SHAMapTreeNode::pointer checkFilter (uint256 const& hash, SHAMapNodeID const& id,
SHAMapSyncFilter* filter);
std::shared_ptr<SHAMapTreeNode> fetchNode (uint256 const& hash);
std::shared_ptr<SHAMapTreeNode> checkFilter (uint256 const& hash, SHAMapNodeID const& id,
SHAMapSyncFilter* filter) const;
/** Update hashes up to the root */
void dirtyUp (SharedPtrNodeStack& stack,
uint256 const& target, SHAMapTreeNode::pointer terminal);
uint256 const& target, std::shared_ptr<SHAMapTreeNode> terminal);
/** Get the path from the root to the specified node */
SharedPtrNodeStack
@@ -287,14 +219,14 @@ private:
SHAMapTreeNode* walkToPointer (uint256 const& id);
/** Unshare the node, allowing it to be modified */
void unshareNode (SHAMapTreeNode::pointer&, SHAMapNodeID const& nodeID);
void unshareNode (std::shared_ptr<SHAMapTreeNode>&, SHAMapNodeID const& nodeID);
/** prepare a node to be modified before flushing */
void preFlushNode (SHAMapTreeNode::pointer& node);
void preFlushNode (std::shared_ptr<SHAMapTreeNode>& node) const;
/** write and canonicalize modified node */
void writeNode (NodeObjectType t, std::uint32_t seq,
SHAMapTreeNode::pointer& node);
std::shared_ptr<SHAMapTreeNode>& node) const;
SHAMapTreeNode* firstBelow (SHAMapTreeNode*);
SHAMapTreeNode* lastBelow (SHAMapTreeNode*);
@@ -303,12 +235,12 @@ private:
// Get a child of the specified node
SHAMapTreeNode* descend (SHAMapTreeNode*, int branch);
SHAMapTreeNode* descendThrow (SHAMapTreeNode*, int branch);
SHAMapTreeNode::pointer descend (SHAMapTreeNode::ref, int branch);
SHAMapTreeNode::pointer descendThrow (SHAMapTreeNode::ref, int branch);
std::shared_ptr<SHAMapTreeNode> descend (std::shared_ptr<SHAMapTreeNode> const&, int branch);
std::shared_ptr<SHAMapTreeNode> descendThrow (std::shared_ptr<SHAMapTreeNode> const&, int branch);
// Descend with filter
SHAMapTreeNode* descendAsync (SHAMapTreeNode* parent, int branch,
SHAMapNodeID const& childID, SHAMapSyncFilter* filter, bool& pending);
SHAMapNodeID const& childID, SHAMapSyncFilter* filter, bool& pending) const;
std::pair <SHAMapTreeNode*, SHAMapNodeID>
descend (SHAMapTreeNode* parent, SHAMapNodeID const& parentID,
@@ -316,23 +248,77 @@ private:
// Non-storing
// Does not hook the returned node to its parent
SHAMapTreeNode::pointer descendNoStore (SHAMapTreeNode::ref, int branch);
std::shared_ptr<SHAMapTreeNode> descendNoStore (std::shared_ptr<SHAMapTreeNode> const&, int branch);
/** If there is only one leaf below this node, get its contents */
SHAMapItem::pointer onlyBelow (SHAMapTreeNode*);
std::shared_ptr<SHAMapItem> onlyBelow (SHAMapTreeNode*);
bool hasInnerNode (SHAMapNodeID const& nodeID, uint256 const& hash);
bool hasLeafNode (uint256 const& tag, uint256 const& hash);
bool walkBranch (SHAMapTreeNode* node,
SHAMapItem::ref otherMapItem, bool isFirstMap,
std::shared_ptr<SHAMapItem> const& otherMapItem, bool isFirstMap,
Delta & differences, int & maxCount);
void visitLeavesInternal (std::function<void (SHAMapItem::ref item)>& function);
int walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq);
};
inline
void
SHAMap::setLedgerSeq (std::uint32_t lseq)
{
ledgerSeq_ = lseq;
}
inline
uint256
SHAMap::getHash () const
{
return root_->getNodeHash ();
}
inline
void
SHAMap::setImmutable ()
{
assert (state_ != SHAMapState::Invalid);
state_ = SHAMapState::Immutable;
}
inline
bool
SHAMap::isSynching () const
{
return (state_ == SHAMapState::Floating) || (state_ == SHAMapState::Synching);
}
inline
void
SHAMap::setSynching ()
{
state_ = SHAMapState::Synching;
}
inline
void
SHAMap::clearSynching ()
{
state_ = SHAMapState::Modifying;
}
inline
bool
SHAMap::isValid () const
{
return state_ != SHAMapState::Invalid;
}
inline
void
SHAMap::setUnbacked ()
{
backed_ = false;
}
}
#endif

View File

@@ -20,120 +20,172 @@
#ifndef RIPPLE_SHAMAP_SHAMAPADDNODE_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPADDNODE_H_INCLUDED
#include <beast/module/core/text/LexicalCast.h>
#include <string>
namespace ripple {
// results of adding nodes
class SHAMapAddNode
{
private:
int mGood;
int mBad;
int mDuplicate;
public:
SHAMapAddNode ()
SHAMapAddNode ();
void incInvalid ();
void incUseful ();
void incDuplicate ();
void reset ();
int getGood () const;
bool isGood () const;
bool isInvalid () const;
bool isUseful () const;
std::string get () const;
SHAMapAddNode& operator+= (SHAMapAddNode const& n);
static SHAMapAddNode duplicate ();
static SHAMapAddNode useful ();
static SHAMapAddNode invalid ();
private:
SHAMapAddNode (int good, int bad, int duplicate);
};
inline
SHAMapAddNode::SHAMapAddNode ()
: mGood (0)
, mBad (0)
, mDuplicate (0)
{
}
{
}
SHAMapAddNode (int good, int bad, int duplicate)
: mGood(good)
, mBad(bad)
, mDuplicate(duplicate)
{
}
inline
SHAMapAddNode::SHAMapAddNode (int good, int bad, int duplicate)
: mGood (good)
, mBad (bad)
, mDuplicate (duplicate)
{
}
void incInvalid ()
{
inline
void
SHAMapAddNode::incInvalid ()
{
++mBad;
}
void incUseful ()
{
}
inline
void
SHAMapAddNode::incUseful ()
{
++mGood;
}
void incDuplicate ()
{
}
inline
void
SHAMapAddNode::incDuplicate ()
{
++mDuplicate;
}
}
void reset ()
{
inline
void
SHAMapAddNode::reset ()
{
mGood = mBad = mDuplicate = 0;
}
}
int getGood ()
{
inline
int
SHAMapAddNode::getGood () const
{
return mGood;
}
}
bool isInvalid () const
{
inline
bool
SHAMapAddNode::isInvalid () const
{
return mBad > 0;
}
bool isUseful () const
{
return mGood > 0;
}
}
SHAMapAddNode& operator+= (SHAMapAddNode const& n)
{
inline
bool
SHAMapAddNode::isUseful () const
{
return mGood > 0;
}
inline
SHAMapAddNode&
SHAMapAddNode::operator+= (SHAMapAddNode const& n)
{
mGood += n.mGood;
mBad += n.mBad;
mDuplicate += n.mDuplicate;
return *this;
}
}
bool isGood () const
{
inline
bool
SHAMapAddNode::isGood () const
{
return (mGood + mDuplicate) > mBad;
}
}
static SHAMapAddNode duplicate ()
{
inline
SHAMapAddNode
SHAMapAddNode::duplicate ()
{
return SHAMapAddNode (0, 0, 1);
}
static SHAMapAddNode useful ()
{
return SHAMapAddNode (1, 0, 0);
}
static SHAMapAddNode invalid ()
{
return SHAMapAddNode (0, 1, 0);
}
}
std::string get ()
{
inline
SHAMapAddNode
SHAMapAddNode::useful ()
{
return SHAMapAddNode (1, 0, 0);
}
inline
SHAMapAddNode
SHAMapAddNode::invalid ()
{
return SHAMapAddNode (0, 1, 0);
}
inline
std::string
SHAMapAddNode::get () const
{
std::string ret;
if (mGood > 0)
{
ret.append("good:");
ret.append(beast::lexicalCastThrow<std::string>(mGood));
ret.append(std::to_string(mGood));
}
if (mBad > 0)
{
if (!ret.empty())
ret.append(" ");
ret.append("bad:");
ret.append(beast::lexicalCastThrow<std::string>(mBad));
ret.append(std::to_string(mBad));
}
if (mDuplicate > 0)
{
if (!ret.empty())
ret.append(" ");
ret.append("dupe:");
ret.append(beast::lexicalCastThrow<std::string>(mDuplicate));
ret.append(std::to_string(mDuplicate));
}
if (ret.empty ())
ret = "no nodes processed";
return ret;
}
private:
int mGood;
int mBad;
int mDuplicate;
};
}
}

View File

@@ -20,77 +20,89 @@
#ifndef RIPPLE_SHAMAP_SHAMAPITEM_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPITEM_H_INCLUDED
#include <ripple/basics/CountedObject.h>
#include <ripple/protocol/Serializer.h>
#include <ripple/basics/base_uint.h>
#include <beast/utility/Journal.h>
#include <memory>
#include <cstddef>
namespace ripple {
// an item stored in a SHAMap
class SHAMapItem
: public CountedObject <SHAMapItem>
{
public:
static char const* getCountedObjectName () { return "SHAMapItem"; }
typedef std::shared_ptr<SHAMapItem> pointer;
typedef const std::shared_ptr<SHAMapItem>& ref;
public:
explicit SHAMapItem (uint256 const& tag)
: mTag (tag)
{
}
// tag computed from hash of data
explicit SHAMapItem (Blob const& data);
SHAMapItem (uint256 const& tag, Blob const & data);
SHAMapItem (uint256 const& tag, Serializer const& s);
std::size_t
size() const
{
return mData.peekData().size();
}
void const*
data() const
{
return mData.peekData().data();
}
uint256 const& getTag() const
{
return mTag;
}
Blob const& peekData() const
{
return mData.peekData();
}
Serializer& peekSerializer()
{
return mData;
}
void addRaw (Blob& s) const
{
s.insert (s.end (), mData.begin (), mData.end ());
}
// VFALCO Why is this virtual?
virtual void dump (beast::Journal journal);
private:
uint256 mTag;
Serializer mData;
public:
explicit SHAMapItem (uint256 const& tag);
SHAMapItem (uint256 const& tag, Blob const & data);
SHAMapItem (uint256 const& tag, Serializer const& s);
uint256 const& getTag() const;
Blob const& peekData() const;
Serializer& peekSerializer();
public: // public only to SHAMapTreeNode
std::size_t size() const;
private:
explicit SHAMapItem (Blob const& data);
void const* data() const;
void addRaw (Blob& s) const;
void dump (beast::Journal journal);
};
inline
SHAMapItem::SHAMapItem (uint256 const& tag)
: mTag (tag)
{
}
inline
std::size_t
SHAMapItem::size() const
{
return mData.peekData().size();
}
inline
void const*
SHAMapItem::data() const
{
return mData.peekData().data();
}
inline
uint256 const&
SHAMapItem::getTag() const
{
return mTag;
}
inline
Blob const&
SHAMapItem::peekData() const
{
return mData.peekData();
}
inline
Serializer&
SHAMapItem::peekSerializer()
{
return mData;
}
inline
void
SHAMapItem::addRaw (Blob& s) const
{
s.insert (s.end (), mData.begin (), mData.end ());
}
} // ripple
#endif

View File

@@ -21,18 +21,24 @@
#define RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
#include <ripple/basics/base_uint.h>
#include <iosfwd>
#include <stdexcept>
namespace ripple {
enum SHAMapType
enum class SHAMapType
{
smtTRANSACTION = 1, // A tree of transactions
smtSTATE = 2, // A tree of state nodes
smtFREE = 3, // A tree not part of a ledger
TRANSACTION = 1, // A tree of transactions
STATE = 2, // A tree of state nodes
FREE = 3, // A tree not part of a ledger
};
class SHAMapMissingNode : public std::runtime_error
class SHAMapMissingNode
: public std::runtime_error
{
private:
SHAMapType mType;
uint256 mNodeHash;
public:
SHAMapMissingNode (SHAMapType t,
uint256 const& nodeHash)
@@ -42,10 +48,6 @@ public:
{
}
virtual ~SHAMapMissingNode () throw ()
{
}
SHAMapType getMapType () const
{
return mType;
@@ -55,10 +57,6 @@ public:
{
return mNodeHash;
}
private:
SHAMapType mType;
uint256 mNodeHash;
};
extern std::ostream& operator<< (std::ostream&, SHAMapMissingNode const&);

View File

@@ -35,104 +35,133 @@ class SHAMapNodeID
private:
uint256 mNodeID;
int mDepth;
mutable size_t mHash;
public:
SHAMapNodeID () : mDepth (0), mHash (0)
{
}
SHAMapNodeID (int depth, uint256 const& hash);
SHAMapNodeID ();
SHAMapNodeID (void const* ptr, int len);
protected:
SHAMapNodeID (int depth, uint256 const& id, bool)
: mNodeID (id), mDepth (depth), mHash (0)
{
}
public:
int getDepth () const
{
return mDepth;
}
uint256 const& getNodeID () const
{
return mNodeID;
}
bool isValid () const
{
return (mDepth >= 0) && (mDepth < 64);
}
bool isRoot () const
{
return mDepth == 0;
}
size_t getMHash () const
{
if (mHash == 0)
mHash = calculate_hash (mNodeID, mDepth);
return mHash;
}
SHAMapNodeID getParentNodeID () const
{
assert (mDepth);
return SHAMapNodeID (mDepth - 1, mNodeID);
}
SHAMapNodeID getChildNodeID (int m) const;
int selectBranch (uint256 const& hash) const;
bool operator< (const SHAMapNodeID& n) const
{
return std::tie(mDepth, mNodeID) < std::tie(n.mDepth, n.mNodeID);
}
bool operator> (const SHAMapNodeID& n) const {return n < *this;}
bool operator<= (const SHAMapNodeID& n) const {return !(*this < n);}
bool operator>= (const SHAMapNodeID& n) const {return !(n < *this);}
bool operator== (const SHAMapNodeID& n) const
{
return (mDepth == n.mDepth) && (mNodeID == n.mNodeID);
}
bool operator!= (const SHAMapNodeID& n) const {return !(*this == n);}
bool operator== (uint256 const& n) const
{
return n == mNodeID;
}
bool operator!= (uint256 const& n) const {return !(*this == n);}
virtual std::string getString () const;
void dump (beast::Journal journal) const;
static uint256 getNodeID (int depth, uint256 const& hash);
bool isValid () const;
bool isRoot () const;
// Convert to/from wire format (256-bit nodeID, 1-byte depth)
void addIDRaw (Serializer& s) const;
std::string getRawString () const;
static int getRawIDLength (void)
{
return 33;
}
bool operator== (const SHAMapNodeID& n) const;
bool operator!= (const SHAMapNodeID& n) const;
bool operator< (const SHAMapNodeID& n) const;
bool operator> (const SHAMapNodeID& n) const;
bool operator<= (const SHAMapNodeID& n) const;
bool operator>= (const SHAMapNodeID& n) const;
std::string getString () const;
void dump (beast::Journal journal) const;
// Only used by SHAMap and SHAMapTreeNode
uint256 const& getNodeID () const;
SHAMapNodeID getChildNodeID (int m) const;
int selectBranch (uint256 const& hash) const;
int getDepth () const;
private:
static
uint256 const&
Masks (int depth);
SHAMapNodeID (int depth, uint256 const& hash);
static
std::size_t
calculate_hash (uint256 const& node, int depth);
static uint256 const& Masks (int depth);
friend std::ostream& operator<< (std::ostream& out, SHAMapNodeID const& node);
private: // Currently unused
SHAMapNodeID getParentNodeID () const;
};
//------------------------------------------------------------------------------
inline
SHAMapNodeID::SHAMapNodeID ()
: mDepth (0)
{
}
inline
int
SHAMapNodeID::getDepth () const
{
return mDepth;
}
inline
uint256 const&
SHAMapNodeID::getNodeID () const
{
return mNodeID;
}
inline
bool
SHAMapNodeID::isValid () const
{
return (mDepth >= 0) && (mDepth < 64);
}
inline
bool
SHAMapNodeID::isRoot () const
{
return mDepth == 0;
}
inline
SHAMapNodeID
SHAMapNodeID::getParentNodeID () const
{
assert (mDepth);
return SHAMapNodeID (mDepth - 1, mNodeID);
}
inline
bool
SHAMapNodeID::operator< (const SHAMapNodeID& n) const
{
return std::tie(mDepth, mNodeID) < std::tie(n.mDepth, n.mNodeID);
}
inline
bool
SHAMapNodeID::operator> (const SHAMapNodeID& n) const
{
return n < *this;
}
inline
bool
SHAMapNodeID::operator<= (const SHAMapNodeID& n) const
{
return !(n < *this);
}
inline
bool
SHAMapNodeID::operator>= (const SHAMapNodeID& n) const
{
return !(*this < n);
}
inline
bool
SHAMapNodeID::operator== (const SHAMapNodeID& n) const
{
return (mDepth == n.mDepth) && (mNodeID == n.mNodeID);
}
inline
bool
SHAMapNodeID::operator!= (const SHAMapNodeID& n) const
{
return !(*this == n);
}
inline std::ostream& operator<< (std::ostream& out, SHAMapNodeID const& node)
{
return out << node.getString ();

View File

@@ -20,6 +20,7 @@
#ifndef RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
#define RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
#include <ripple/shamap/SHAMapNodeID.h>
#include <ripple/shamap/SHAMapTreeNode.h>
/** Callback for filtering SHAMap during sync. */
@@ -28,7 +29,10 @@ namespace ripple {
class SHAMapSyncFilter
{
public:
virtual ~SHAMapSyncFilter () { }
virtual ~SHAMapSyncFilter () = default;
SHAMapSyncFilter() = default;
SHAMapSyncFilter(SHAMapSyncFilter const&) = delete;
SHAMapSyncFilter& operator=(SHAMapSyncFilter const&) = delete;
// Note that the nodeData is overwritten by this call
virtual void gotNode (bool fromFilter,

View File

@@ -22,14 +22,15 @@
#include <ripple/shamap/SHAMapItem.h>
#include <ripple/shamap/SHAMapNodeID.h>
#include <ripple/shamap/TreeNodeCache.h>
#include <ripple/basics/CountedObject.h>
#include <ripple/basics/TaggedCache.h>
#include <beast/utility/Journal.h>
namespace ripple {
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
class SHAMap;
namespace ripple {
enum SHANodeFormat
{
@@ -39,14 +40,8 @@ enum SHANodeFormat
};
class SHAMapTreeNode
: public CountedObject <SHAMapTreeNode>
{
public:
static char const* getCountedObjectName () { return "SHAMapTreeNode"; }
typedef std::shared_ptr<SHAMapTreeNode> pointer;
typedef const std::shared_ptr<SHAMapTreeNode>& ref;
enum TNType
{
tnERROR = 0,
@@ -56,160 +51,210 @@ public:
tnACCOUNT_STATE = 4
};
private:
uint256 mHash;
uint256 mHashes[16];
std::shared_ptr<SHAMapTreeNode> mChildren[16];
std::shared_ptr<SHAMapItem> mItem;
std::uint32_t mSeq;
TNType mType;
int mIsBranch;
std::uint32_t mFullBelowGen;
static std::mutex childLock;
public:
SHAMapTreeNode (const SHAMapTreeNode&) = delete;
SHAMapTreeNode& operator= (const SHAMapTreeNode&) = delete;
SHAMapTreeNode (std::uint32_t seq); // empty node
SHAMapTreeNode (const SHAMapTreeNode & node, std::uint32_t seq); // copy node from older tree
SHAMapTreeNode (SHAMapItem::ref item, TNType type, std::uint32_t seq);
// raw node functions
SHAMapTreeNode (std::shared_ptr<SHAMapItem> const& item, TNType type, std::uint32_t seq);
SHAMapTreeNode (Blob const & data, std::uint32_t seq,
SHANodeFormat format, uint256 const& hash, bool hashValid);
void addRaw (Serializer&, SHANodeFormat format);
uint256 const& getNodeHash () const;
// node functions
std::uint32_t getSeq () const
{
return mSeq;
}
void setSeq (std::uint32_t s)
{
mSeq = s;
}
uint256 const& getNodeHash () const
{
return mHash;
}
TNType getType () const
{
return mType;
}
// type functions
bool isLeaf () const
{
return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD) ||
(mType == tnACCOUNT_STATE);
}
bool isInner () const
{
return mType == tnINNER;
}
bool isInBounds (SHAMapNodeID const &id) const
{
// Nodes at depth 64 must be leaves
return (!isInner() || (id.getDepth() < 64));
}
bool isValid () const
{
return mType != tnERROR;
}
bool isTransaction () const
{
return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD);
}
bool hasMetaData () const
{
return mType == tnTRANSACTION_MD;
}
bool isAccountState () const
{
return mType == tnACCOUNT_STATE;
}
// inner node functions
bool isInnerNode () const
{
return !mItem;
}
// We are modifying the child hash
bool setChild (int m, uint256 const& hash, std::shared_ptr<SHAMapTreeNode> const& child);
// We are sharing/unsharing the child
public: // public only to SHAMap
bool setChild (int m, uint256 const& hash,
std::shared_ptr<SHAMapTreeNode> const& child);
void shareChild (int m, std::shared_ptr<SHAMapTreeNode> const& child);
bool isEmptyBranch (int m) const
{
return (mIsBranch & (1 << m)) == 0;
}
// node functions
std::uint32_t getSeq () const;
void setSeq (std::uint32_t s);
TNType getType () const;
// type functions
bool isLeaf () const;
bool isInner () const;
bool isInBounds (SHAMapNodeID const &id) const;
bool isValid () const;
// inner node functions
bool isInnerNode () const;
bool isEmptyBranch (int m) const;
bool isEmpty () const;
int getBranchCount () const;
void makeInner ();
uint256 const& getChildHash (int m) const
{
assert ((m >= 0) && (m < 16) && (mType == tnINNER));
return mHashes[m];
}
uint256 const& getChildHash (int m) const;
// item node function
bool hasItem () const
{
return bool(mItem);
}
SHAMapItem::ref peekItem () const
{
return mItem;
}
bool setItem (SHAMapItem::ref i, TNType type);
bool hasItem () const;
std::shared_ptr<SHAMapItem> const& peekItem () const;
bool setItem (std::shared_ptr<SHAMapItem> const& i, TNType type);
// sync functions
bool isFullBelow (std::uint32_t generation) const
{
return mFullBelowGen == generation;
}
void setFullBelowGen (std::uint32_t gen)
{
mFullBelowGen = gen;
}
// VFALCO Why are these virtual?
virtual void dump (SHAMapNodeID const&, beast::Journal journal);
virtual std::string getString (SHAMapNodeID const&) const;
bool isFullBelow (std::uint32_t generation) const;
void setFullBelowGen (std::uint32_t gen);
SHAMapTreeNode* getChildPointer (int branch);
std::shared_ptr<SHAMapTreeNode> getChild (int branch);
void canonicalizeChild (int branch, std::shared_ptr<SHAMapTreeNode>& node);
SHAMapTreeNode::pointer getChild (int branch);
void canonicalizeChild (int branch, SHAMapTreeNode::pointer& node);
// debugging
#ifdef BEAST_DEBUG
void dump (SHAMapNodeID const&, beast::Journal journal);
#endif
std::string getString (SHAMapNodeID const&) const;
private:
// VFALCO TODO remove the use of friend
friend class SHAMap;
uint256 mHash;
uint256 mHashes[16];
SHAMapTreeNode::pointer mChildren[16];
SHAMapItem::pointer mItem;
std::uint32_t mSeq;
TNType mType;
int mIsBranch;
std::uint32_t mFullBelowGen;
bool isTransaction () const;
bool hasMetaData () const;
bool isAccountState () const;
bool updateHash ();
static std::mutex childLock;
};
inline
std::uint32_t
SHAMapTreeNode::getSeq () const
{
return mSeq;
}
inline
void
SHAMapTreeNode::setSeq (std::uint32_t s)
{
mSeq = s;
}
inline
uint256 const&
SHAMapTreeNode::getNodeHash () const
{
return mHash;
}
inline
SHAMapTreeNode::TNType
SHAMapTreeNode::getType () const
{
return mType;
}
inline
bool
SHAMapTreeNode::isLeaf () const
{
return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD) ||
(mType == tnACCOUNT_STATE);
}
inline
bool
SHAMapTreeNode::isInner () const
{
return mType == tnINNER;
}
inline
bool
SHAMapTreeNode::isInBounds (SHAMapNodeID const &id) const
{
// Nodes at depth 64 must be leaves
return (!isInner() || (id.getDepth() < 64));
}
inline
bool
SHAMapTreeNode::isValid () const
{
return mType != tnERROR;
}
inline
bool
SHAMapTreeNode::isTransaction () const
{
return (mType == tnTRANSACTION_NM) || (mType == tnTRANSACTION_MD);
}
inline
bool
SHAMapTreeNode::hasMetaData () const
{
return mType == tnTRANSACTION_MD;
}
inline
bool
SHAMapTreeNode::isAccountState () const
{
return mType == tnACCOUNT_STATE;
}
inline
bool
SHAMapTreeNode::isInnerNode () const
{
return !mItem;
}
inline
bool
SHAMapTreeNode::isEmptyBranch (int m) const
{
return (mIsBranch & (1 << m)) == 0;
}
inline
uint256 const&
SHAMapTreeNode::getChildHash (int m) const
{
assert ((m >= 0) && (m < 16) && (mType == tnINNER));
return mHashes[m];
}
inline
bool
SHAMapTreeNode::hasItem () const
{
return bool(mItem);
}
inline
std::shared_ptr<SHAMapItem> const&
SHAMapTreeNode::peekItem () const
{
return mItem;
}
inline
bool
SHAMapTreeNode::isFullBelow (std::uint32_t generation) const
{
return mFullBelowGen == generation;
}
inline
void
SHAMapTreeNode::setFullBelowGen (std::uint32_t gen)
{
mFullBelowGen = gen;
}
} // ripple
#endif

View File

@@ -31,15 +31,15 @@ SHAMap::SHAMap (
std::uint32_t seq)
: f_ (f)
, journal_(journal)
, mSeq (seq)
, mLedgerSeq (0)
, mState (smsModifying)
, mType (t)
, seq_ (seq)
, ledgerSeq_ (0)
, state_ (SHAMapState::Modifying)
, type_ (t)
{
assert (mSeq != 0);
assert (seq_ != 0);
root = std::make_shared<SHAMapTreeNode> (mSeq);
root->makeInner ();
root_ = std::make_shared<SHAMapTreeNode> (seq_);
root_->makeInner ();
}
SHAMap::SHAMap (
@@ -49,33 +49,33 @@ SHAMap::SHAMap (
beast::Journal journal)
: f_ (f)
, journal_(journal)
, mSeq (1)
, mLedgerSeq (0)
, mState (smsSynching)
, mType (t)
, seq_ (1)
, ledgerSeq_ (0)
, state_ (SHAMapState::Synching)
, type_ (t)
{
root = std::make_shared<SHAMapTreeNode> (mSeq);
root->makeInner ();
root_ = std::make_shared<SHAMapTreeNode> (seq_);
root_->makeInner ();
}
SHAMap::~SHAMap ()
{
mState = smsInvalid;
state_ = SHAMapState::Invalid;
}
SHAMap::pointer SHAMap::snapShot (bool isMutable)
std::shared_ptr<SHAMap>
SHAMap::snapShot (bool isMutable) const
{
SHAMap::pointer ret = std::make_shared<SHAMap> (
mType, f_, journal_);
auto ret = std::make_shared<SHAMap> (type_, f_, journal_);
SHAMap& newMap = *ret;
if (!isMutable)
newMap.mState = smsImmutable;
newMap.state_ = SHAMapState::Immutable;
newMap.mSeq = mSeq + 1;
newMap.root = root;
newMap.seq_ = seq_ + 1;
newMap.root_ = root_;
if ((mState != smsImmutable) || !isMutable)
if ((state_ != SHAMapState::Immutable) || !isMutable)
{
// If either map may change, they cannot share nodes
newMap.unshare ();
@@ -91,7 +91,7 @@ SHAMap::getStack (uint256 const& id, bool include_nonmatching_leaf)
// produce a stack of nodes along the way, with the terminal node at the top
SharedPtrNodeStack stack;
SHAMapTreeNode::pointer node = root;
std::shared_ptr<SHAMapTreeNode> node = root_;
SHAMapNodeID nodeID;
while (!node->isLeaf ())
@@ -116,19 +116,19 @@ SHAMap::getStack (uint256 const& id, bool include_nonmatching_leaf)
void
SHAMap::dirtyUp (SharedPtrNodeStack& stack,
uint256 const& target, SHAMapTreeNode::pointer child)
uint256 const& target, std::shared_ptr<SHAMapTreeNode> child)
{
// walk the tree up from through the inner nodes to the root
// walk the tree up from through the inner nodes to the root_
// update hashes and links
// stack is a path of inner nodes up to, but not including, child
// child can be an inner node or a leaf
assert ((mState != smsSynching) && (mState != smsImmutable));
assert (child && (child->getSeq() == mSeq));
assert ((state_ != SHAMapState::Synching) && (state_ != SHAMapState::Immutable));
assert (child && (child->getSeq() == seq_));
while (!stack.empty ())
{
SHAMapTreeNode::pointer node = stack.top ().first;
std::shared_ptr<SHAMapTreeNode> node = stack.top ().first;
SHAMapNodeID nodeID = stack.top ().second;
stack.pop ();
assert (node->isInnerNode ());
@@ -156,7 +156,7 @@ SHAMap::dirtyUp (SharedPtrNodeStack& stack,
SHAMapTreeNode* SHAMap::walkToPointer (uint256 const& id)
{
SHAMapTreeNode* inNode = root.get ();
SHAMapTreeNode* inNode = root_.get ();
SHAMapNodeID nodeID;
uint256 nodeHash;
@@ -174,11 +174,12 @@ SHAMapTreeNode* SHAMap::walkToPointer (uint256 const& id)
return (inNode->peekItem()->getTag () == id) ? inNode : nullptr;
}
SHAMapTreeNode::pointer SHAMap::fetchNodeFromDB (uint256 const& hash)
std::shared_ptr<SHAMapTreeNode>
SHAMap::fetchNodeFromDB (uint256 const& hash)
{
SHAMapTreeNode::pointer node;
std::shared_ptr<SHAMapTreeNode> node;
if (mBacked)
if (backed_)
{
NodeObject::pointer obj = f_.db().fetch (hash);
if (obj)
@@ -193,13 +194,13 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeFromDB (uint256 const& hash)
{
if (journal_.warning) journal_.warning <<
"Invalid DB node " << hash;
return SHAMapTreeNode::pointer ();
return std::shared_ptr<SHAMapTreeNode> ();
}
}
else if (mLedgerSeq != 0)
else if (ledgerSeq_ != 0)
{
f_.missing_node(mLedgerSeq);
mLedgerSeq = 0;
f_.missing_node(ledgerSeq_);
ledgerSeq_ = 0;
}
}
@@ -207,12 +208,12 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeFromDB (uint256 const& hash)
}
// See if a sync filter has a node
SHAMapTreeNode::pointer SHAMap::checkFilter (
std::shared_ptr<SHAMapTreeNode> SHAMap::checkFilter (
uint256 const& hash,
SHAMapNodeID const& id,
SHAMapSyncFilter* filter)
SHAMapSyncFilter* filter) const
{
SHAMapTreeNode::pointer node;
std::shared_ptr<SHAMapTreeNode> node;
Blob nodeData;
if (filter->haveNode (id, hash, nodeData))
@@ -222,7 +223,7 @@ SHAMapTreeNode::pointer SHAMap::checkFilter (
filter->gotNode (true, id, hash, nodeData, node->getType ());
if (mBacked)
if (backed_)
canonicalize (hash, node);
}
@@ -231,16 +232,16 @@ SHAMapTreeNode::pointer SHAMap::checkFilter (
// Get a node without throwing
// Used on maps where missing nodes are expected
SHAMapTreeNode::pointer SHAMap::fetchNodeNT(
std::shared_ptr<SHAMapTreeNode> SHAMap::fetchNodeNT(
SHAMapNodeID const& id,
uint256 const& hash,
SHAMapSyncFilter* filter)
{
SHAMapTreeNode::pointer node = getCache (hash);
std::shared_ptr<SHAMapTreeNode> node = getCache (hash);
if (node)
return node;
if (mBacked)
if (backed_)
{
node = fetchNodeFromDB (hash);
if (node)
@@ -256,23 +257,23 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeNT(
return node;
}
SHAMapTreeNode::pointer SHAMap::fetchNodeNT (uint256 const& hash)
std::shared_ptr<SHAMapTreeNode> SHAMap::fetchNodeNT (uint256 const& hash)
{
SHAMapTreeNode::pointer node = getCache (hash);
std::shared_ptr<SHAMapTreeNode> node = getCache (hash);
if (!node && mBacked)
if (!node && backed_)
node = fetchNodeFromDB (hash);
return node;
}
// Throw if the node is missing
SHAMapTreeNode::pointer SHAMap::fetchNode (uint256 const& hash)
std::shared_ptr<SHAMapTreeNode> SHAMap::fetchNode (uint256 const& hash)
{
SHAMapTreeNode::pointer node = fetchNodeNT (hash);
std::shared_ptr<SHAMapTreeNode> node = fetchNodeNT (hash);
if (!node)
throw SHAMapMissingNode (mType, hash);
throw SHAMapMissingNode (type_, hash);
return node;
}
@@ -282,17 +283,18 @@ SHAMapTreeNode* SHAMap::descendThrow (SHAMapTreeNode* parent, int branch)
SHAMapTreeNode* ret = descend (parent, branch);
if (! ret && ! parent->isEmptyBranch (branch))
throw SHAMapMissingNode (mType, parent->getChildHash (branch));
throw SHAMapMissingNode (type_, parent->getChildHash (branch));
return ret;
}
SHAMapTreeNode::pointer SHAMap::descendThrow (SHAMapTreeNode::ref parent, int branch)
std::shared_ptr<SHAMapTreeNode>
SHAMap::descendThrow (std::shared_ptr<SHAMapTreeNode> const& parent, int branch)
{
SHAMapTreeNode::pointer ret = descend (parent, branch);
std::shared_ptr<SHAMapTreeNode> ret = descend (parent, branch);
if (! ret && ! parent->isEmptyBranch (branch))
throw SHAMapMissingNode (mType, parent->getChildHash (branch));
throw SHAMapMissingNode (type_, parent->getChildHash (branch));
return ret;
}
@@ -300,10 +302,10 @@ SHAMapTreeNode::pointer SHAMap::descendThrow (SHAMapTreeNode::ref parent, int br
SHAMapTreeNode* SHAMap::descend (SHAMapTreeNode* parent, int branch)
{
SHAMapTreeNode* ret = parent->getChildPointer (branch);
if (ret || !mBacked)
if (ret || !backed_)
return ret;
SHAMapTreeNode::pointer node = fetchNodeNT (parent->getChildHash (branch));
std::shared_ptr<SHAMapTreeNode> node = fetchNodeNT (parent->getChildHash (branch));
if (!node)
return nullptr;
@@ -311,10 +313,11 @@ SHAMapTreeNode* SHAMap::descend (SHAMapTreeNode* parent, int branch)
return node.get ();
}
SHAMapTreeNode::pointer SHAMap::descend (SHAMapTreeNode::ref parent, int branch)
std::shared_ptr<SHAMapTreeNode>
SHAMap::descend (std::shared_ptr<SHAMapTreeNode> const& parent, int branch)
{
SHAMapTreeNode::pointer node = parent->getChild (branch);
if (node || !mBacked)
std::shared_ptr<SHAMapTreeNode> node = parent->getChild (branch);
if (node || !backed_)
return node;
node = fetchNode (parent->getChildHash (branch));
@@ -327,10 +330,11 @@ SHAMapTreeNode::pointer SHAMap::descend (SHAMapTreeNode::ref parent, int branch)
// Gets the node that would be hooked to this branch,
// but doesn't hook it up.
SHAMapTreeNode::pointer SHAMap::descendNoStore (SHAMapTreeNode::ref parent, int branch)
std::shared_ptr<SHAMapTreeNode>
SHAMap::descendNoStore (std::shared_ptr<SHAMapTreeNode> const& parent, int branch)
{
SHAMapTreeNode::pointer ret = parent->getChild (branch);
if (!ret && mBacked)
std::shared_ptr<SHAMapTreeNode> ret = parent->getChild (branch);
if (!ret && backed_)
ret = fetchNode (parent->getChildHash (branch));
return ret;
}
@@ -349,7 +353,7 @@ SHAMap::descend (SHAMapTreeNode * parent, SHAMapNodeID const& parentID,
if (!child)
{
SHAMapTreeNode::pointer childNode = fetchNodeNT (childID, childHash, filter);
std::shared_ptr<SHAMapTreeNode> childNode = fetchNodeNT (childID, childHash, filter);
if (childNode)
{
@@ -362,7 +366,7 @@ SHAMap::descend (SHAMapTreeNode * parent, SHAMapNodeID const& parentID,
}
SHAMapTreeNode* SHAMap::descendAsync (SHAMapTreeNode* parent, int branch,
SHAMapNodeID const& childID, SHAMapSyncFilter * filter, bool & pending)
SHAMapNodeID const& childID, SHAMapSyncFilter * filter, bool & pending) const
{
pending = false;
@@ -372,13 +376,13 @@ SHAMapTreeNode* SHAMap::descendAsync (SHAMapTreeNode* parent, int branch,
uint256 const& hash = parent->getChildHash (branch);
SHAMapTreeNode::pointer ptr = getCache (hash);
std::shared_ptr<SHAMapTreeNode> ptr = getCache (hash);
if (!ptr)
{
if (filter)
ptr = checkFilter (hash, childID, filter);
if (!ptr && mBacked)
if (!ptr && backed_)
{
NodeObject::pointer obj;
if (! f_.db().asyncFetch (hash, obj))
@@ -391,7 +395,7 @@ SHAMapTreeNode* SHAMap::descendAsync (SHAMapTreeNode* parent, int branch,
ptr = std::make_shared <SHAMapTreeNode> (obj->getData(), 0, snfPREFIX, hash, true);
if (mBacked)
if (backed_)
canonicalize (hash, ptr);
}
}
@@ -403,22 +407,22 @@ SHAMapTreeNode* SHAMap::descendAsync (SHAMapTreeNode* parent, int branch,
}
void
SHAMap::unshareNode (SHAMapTreeNode::pointer& node, SHAMapNodeID const& nodeID)
SHAMap::unshareNode (std::shared_ptr<SHAMapTreeNode>& node, SHAMapNodeID const& nodeID)
{
// make sure the node is suitable for the intended operation (copy on write)
assert (node->isValid ());
assert (node->getSeq () <= mSeq);
assert (node->getSeq () <= seq_);
if (node->getSeq () != mSeq)
if (node->getSeq () != seq_)
{
// have a CoW
assert (mState != smsImmutable);
assert (state_ != SHAMapState::Immutable);
node = std::make_shared<SHAMapTreeNode> (*node, mSeq); // here's to the new node, same as the old node
node = std::make_shared<SHAMapTreeNode> (*node, seq_); // here's to the new node, same as the old node
assert (node->isValid ());
if (nodeID.isRoot ())
root = node;
root_ = node;
}
}
@@ -475,7 +479,7 @@ SHAMap::lastBelow (SHAMapTreeNode* node)
while (true);
}
SHAMapItem::pointer
std::shared_ptr<SHAMapItem>
SHAMap::onlyBelow (SHAMapTreeNode* node)
{
// If there is only one item below this node, return it
@@ -488,7 +492,7 @@ SHAMap::onlyBelow (SHAMapTreeNode* node)
if (!node->isEmptyBranch (i))
{
if (nextNode)
return SHAMapItem::pointer ();
return std::shared_ptr<SHAMapItem> ();
nextNode = descendThrow (node, i);
}
@@ -497,24 +501,24 @@ SHAMap::onlyBelow (SHAMapTreeNode* node)
if (!nextNode)
{
assert (false);
return SHAMapItem::pointer ();
return std::shared_ptr<SHAMapItem> ();
}
node = nextNode;
}
// An inner node must have at least one leaf
// below it, unless it's the root
assert (node->hasItem () || (node == root.get ()));
// below it, unless it's the root_
assert (node->hasItem () || (node == root_.get ()));
return node->peekItem ();
}
static const SHAMapItem::pointer no_item;
static const std::shared_ptr<SHAMapItem> no_item;
SHAMapItem::pointer SHAMap::peekFirstItem ()
std::shared_ptr<SHAMapItem> SHAMap::peekFirstItem ()
{
SHAMapTreeNode* node = firstBelow (root.get ());
SHAMapTreeNode* node = firstBelow (root_.get ());
if (!node)
return no_item;
@@ -522,9 +526,9 @@ SHAMapItem::pointer SHAMap::peekFirstItem ()
return node->peekItem ();
}
SHAMapItem::pointer SHAMap::peekFirstItem (SHAMapTreeNode::TNType& type)
std::shared_ptr<SHAMapItem> SHAMap::peekFirstItem (SHAMapTreeNode::TNType& type)
{
SHAMapTreeNode* node = firstBelow (root.get ());
SHAMapTreeNode* node = firstBelow (root_.get ());
if (!node)
return no_item;
@@ -533,9 +537,9 @@ SHAMapItem::pointer SHAMap::peekFirstItem (SHAMapTreeNode::TNType& type)
return node->peekItem ();
}
SHAMapItem::pointer SHAMap::peekLastItem ()
std::shared_ptr<SHAMapItem> SHAMap::peekLastItem ()
{
SHAMapTreeNode* node = lastBelow (root.get ());
SHAMapTreeNode* node = lastBelow (root_.get ());
if (!node)
return no_item;
@@ -543,13 +547,13 @@ SHAMapItem::pointer SHAMap::peekLastItem ()
return node->peekItem ();
}
SHAMapItem::pointer SHAMap::peekNextItem (uint256 const& id)
std::shared_ptr<SHAMapItem> SHAMap::peekNextItem (uint256 const& id)
{
SHAMapTreeNode::TNType type;
return peekNextItem (id, type);
}
SHAMapItem::pointer SHAMap::peekNextItem (uint256 const& id, SHAMapTreeNode::TNType& type)
std::shared_ptr<SHAMapItem> SHAMap::peekNextItem (uint256 const& id, SHAMapTreeNode::TNType& type)
{
// Get a pointer to the next item in the tree after a given item - item need not be in tree
@@ -592,7 +596,7 @@ SHAMapItem::pointer SHAMap::peekNextItem (uint256 const& id, SHAMapTreeNode::TNT
}
// Get a pointer to the previous item in the tree after a given item - item need not be in tree
SHAMapItem::pointer SHAMap::peekPrevItem (uint256 const& id)
std::shared_ptr<SHAMapItem> SHAMap::peekPrevItem (uint256 const& id)
{
auto stack = getStack (id, true);
@@ -625,7 +629,7 @@ SHAMapItem::pointer SHAMap::peekPrevItem (uint256 const& id)
return no_item;
}
SHAMapItem::pointer SHAMap::peekItem (uint256 const& id)
std::shared_ptr<SHAMapItem> SHAMap::peekItem (uint256 const& id)
{
SHAMapTreeNode* leaf = walkToPointer (id);
@@ -635,7 +639,7 @@ SHAMapItem::pointer SHAMap::peekItem (uint256 const& id)
return leaf->peekItem ();
}
SHAMapItem::pointer SHAMap::peekItem (uint256 const& id, SHAMapTreeNode::TNType& type)
std::shared_ptr<SHAMapItem> SHAMap::peekItem (uint256 const& id, SHAMapTreeNode::TNType& type)
{
SHAMapTreeNode* leaf = walkToPointer (id);
@@ -646,7 +650,7 @@ SHAMapItem::pointer SHAMap::peekItem (uint256 const& id, SHAMapTreeNode::TNType&
return leaf->peekItem ();
}
SHAMapItem::pointer SHAMap::peekItem (uint256 const& id, uint256& hash)
std::shared_ptr<SHAMapItem> SHAMap::peekItem (uint256 const& id, uint256& hash)
{
SHAMapTreeNode* leaf = walkToPointer (id);
@@ -668,14 +672,14 @@ bool SHAMap::hasItem (uint256 const& id)
bool SHAMap::delItem (uint256 const& id)
{
// delete the item with this ID
assert (mState != smsImmutable);
assert (state_ != SHAMapState::Immutable);
auto stack = getStack (id, true);
if (stack.empty ())
throw (std::runtime_error ("missing node"));
SHAMapTreeNode::pointer leaf = stack.top ().first;
std::shared_ptr<SHAMapTreeNode> leaf = stack.top ().first;
SHAMapNodeID leafID = stack.top ().second;
stack.pop ();
@@ -687,11 +691,11 @@ bool SHAMap::delItem (uint256 const& id)
// What gets attached to the end of the chain
// (For now, nothing, since we deleted the leaf)
uint256 prevHash;
SHAMapTreeNode::pointer prevNode;
std::shared_ptr<SHAMapTreeNode> prevNode;
while (!stack.empty ())
{
SHAMapTreeNode::pointer node = stack.top ().first;
std::shared_ptr<SHAMapTreeNode> node = stack.top ().first;
SHAMapNodeID nodeID = stack.top ().second;
stack.pop ();
@@ -719,7 +723,7 @@ bool SHAMap::delItem (uint256 const& id)
else if (bc == 1)
{
// If there's only one item, pull up on the thread
SHAMapItem::pointer item = onlyBelow (node.get ());
std::shared_ptr<SHAMapItem> item = onlyBelow (node.get ());
if (item)
{
@@ -754,21 +758,23 @@ bool SHAMap::delItem (uint256 const& id)
return true;
}
bool SHAMap::addGiveItem (SHAMapItem::ref item, bool isTransaction, bool hasMeta)
bool
SHAMap::addGiveItem (std::shared_ptr<SHAMapItem> const& item,
bool isTransaction, bool hasMeta)
{
// add the specified item, does not update
uint256 tag = item->getTag ();
SHAMapTreeNode::TNType type = !isTransaction ? SHAMapTreeNode::tnACCOUNT_STATE :
(hasMeta ? SHAMapTreeNode::tnTRANSACTION_MD : SHAMapTreeNode::tnTRANSACTION_NM);
assert (mState != smsImmutable);
assert (state_ != SHAMapState::Immutable);
auto stack = getStack (tag, true);
if (stack.empty ())
throw (std::runtime_error ("missing node"));
SHAMapTreeNode::pointer node = stack.top ().first;
std::shared_ptr<SHAMapTreeNode> node = stack.top ().first;
SHAMapNodeID nodeID = stack.top ().second;
stack.pop ();
@@ -781,8 +787,7 @@ bool SHAMap::addGiveItem (SHAMapItem::ref item, bool isTransaction, bool hasMeta
// easy case, we end on an inner node
int branch = nodeID.selectBranch (tag);
assert (node->isEmptyBranch (branch));
SHAMapTreeNode::pointer newNode =
std::make_shared<SHAMapTreeNode> (item, type, mSeq);
auto newNode = std::make_shared<SHAMapTreeNode> (item, type, seq_);
if (! node->setChild (branch, newNode->getNodeHash (), newNode))
{
assert (false);
@@ -791,7 +796,7 @@ bool SHAMap::addGiveItem (SHAMapItem::ref item, bool isTransaction, bool hasMeta
else
{
// this is a leaf node that has to be made an inner node holding two items
SHAMapItem::pointer otherItem = node->peekItem ();
std::shared_ptr<SHAMapItem> otherItem = node->peekItem ();
assert (otherItem && (tag != otherItem->getTag ()));
node->makeInner ();
@@ -805,22 +810,22 @@ bool SHAMap::addGiveItem (SHAMapItem::ref item, bool isTransaction, bool hasMeta
// we need a new inner node, since both go on same branch at this level
nodeID = nodeID.getChildNodeID (b1);
node = std::make_shared<SHAMapTreeNode> (mSeq);
node = std::make_shared<SHAMapTreeNode> (seq_);
node->makeInner ();
}
// we can add the two leaf nodes here
assert (node->isInner ());
SHAMapTreeNode::pointer newNode =
std::make_shared<SHAMapTreeNode> (item, type, mSeq);
std::shared_ptr<SHAMapTreeNode> newNode =
std::make_shared<SHAMapTreeNode> (item, type, seq_);
assert (newNode->isValid () && newNode->isLeaf ());
if (!node->setChild (b1, newNode->getNodeHash (), newNode))
{
assert (false);
}
newNode = std::make_shared<SHAMapTreeNode> (otherItem, type, mSeq);
newNode = std::make_shared<SHAMapTreeNode> (otherItem, type, seq_);
assert (newNode->isValid () && newNode->isLeaf ());
if (!node->setChild (b2, newNode->getNodeHash (), newNode))
{
@@ -837,19 +842,21 @@ bool SHAMap::addItem (const SHAMapItem& i, bool isTransaction, bool hasMetaData)
return addGiveItem (std::make_shared<SHAMapItem> (i), isTransaction, hasMetaData);
}
bool SHAMap::updateGiveItem (SHAMapItem::ref item, bool isTransaction, bool hasMeta)
bool
SHAMap::updateGiveItem (std::shared_ptr<SHAMapItem> const& item,
bool isTransaction, bool hasMeta)
{
// can't change the tag but can change the hash
uint256 tag = item->getTag ();
assert (mState != smsImmutable);
assert (state_ != SHAMapState::Immutable);
auto stack = getStack (tag, true);
if (stack.empty ())
throw (std::runtime_error ("missing node"));
SHAMapTreeNode::pointer node = stack.top ().first;
std::shared_ptr<SHAMapTreeNode> node = stack.top ().first;
SHAMapNodeID nodeID = stack.top ().second;
stack.pop ();
@@ -875,17 +882,17 @@ bool SHAMap::updateGiveItem (SHAMapItem::ref item, bool isTransaction, bool hasM
bool SHAMap::fetchRoot (uint256 const& hash, SHAMapSyncFilter* filter)
{
if (hash == root->getNodeHash ())
if (hash == root_->getNodeHash ())
return true;
if (journal_.trace)
{
if (mType == smtTRANSACTION)
if (type_ == SHAMapType::TRANSACTION)
{
journal_.trace
<< "Fetch root TXN node " << hash;
}
else if (mType == smtSTATE)
else if (type_ == SHAMapType::STATE)
{
journal_.trace <<
"Fetch root STATE node " << hash;
@@ -897,12 +904,12 @@ bool SHAMap::fetchRoot (uint256 const& hash, SHAMapSyncFilter* filter)
}
}
SHAMapTreeNode::pointer newRoot = fetchNodeNT (SHAMapNodeID(), hash, filter);
std::shared_ptr<SHAMapTreeNode> newRoot = fetchNodeNT (SHAMapNodeID(), hash, filter);
if (newRoot)
{
root = newRoot;
assert (root->getNodeHash () == hash);
root_ = newRoot;
assert (root_->getNodeHash () == hash);
return true;
}
@@ -919,11 +926,11 @@ bool SHAMap::fetchRoot (uint256 const& hash, SHAMapSyncFilter* filter)
// 2) An unshareable node is shared. This happens when you make
// a mutable snapshot of a mutable SHAMap.
void SHAMap::writeNode (
NodeObjectType t, std::uint32_t seq, SHAMapTreeNode::pointer& node)
NodeObjectType t, std::uint32_t seq, std::shared_ptr<SHAMapTreeNode>& node) const
{
// Node is ours, so we can just make it shareable
assert (node->getSeq() == mSeq);
assert (mBacked);
assert (node->getSeq() == seq_);
assert (backed_);
node->setSeq (0);
canonicalize (node->getNodeHash(), node);
@@ -937,17 +944,17 @@ void SHAMap::writeNode (
// We can't modify an inner node someone else might have a
// pointer to because flushing modifies inner nodes -- it
// makes them point to canonical/shared nodes.
void SHAMap::preFlushNode (SHAMapTreeNode::pointer& node)
void SHAMap::preFlushNode (std::shared_ptr<SHAMapTreeNode>& node) const
{
// A shared node should never need to be flushed
// because that would imply someone modified it
assert (node->getSeq() != 0);
if (node->getSeq() != mSeq)
if (node->getSeq() != seq_)
{
// Node is not uniquely ours, so unshare it before
// possibly modifying it
node = std::make_shared <SHAMapTreeNode> (*node, mSeq);
node = std::make_shared <SHAMapTreeNode> (*node, seq_);
}
}
@@ -963,28 +970,29 @@ int SHAMap::flushDirty (NodeObjectType t, std::uint32_t seq)
return walkSubTree (true, t, seq);
}
int SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
int
SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
{
int flushed = 0;
Serializer s;
if (!root || (root->getSeq() == 0) || root->isEmpty ())
if (!root_ || (root_->getSeq() == 0) || root_->isEmpty ())
return flushed;
if (root->isLeaf())
{ // special case -- root is leaf
preFlushNode (root);
if (doWrite && mBacked)
writeNode (t, seq, root);
if (root_->isLeaf())
{ // special case -- root_ is leaf
preFlushNode (root_);
if (doWrite && backed_)
writeNode (t, seq, root_);
return 1;
}
// Stack of {parent,index,child} pointers representing
// inner nodes we are in the process of flushing
using StackEntry = std::pair <SHAMapTreeNode::pointer, int>;
using StackEntry = std::pair <std::shared_ptr<SHAMapTreeNode>, int>;
std::stack <StackEntry, std::vector<StackEntry>> stack;
SHAMapTreeNode::pointer node = root;
std::shared_ptr<SHAMapTreeNode> node = root_;
preFlushNode (node);
int pos = 0;
@@ -1003,7 +1011,7 @@ int SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
// No need to do I/O. If the node isn't linked,
// it can't need to be flushed
int branch = pos;
SHAMapTreeNode::pointer child = node->getChild (pos++);
std::shared_ptr<SHAMapTreeNode> child = node->getChild (pos++);
if (child && (child->getSeq() != 0))
{
@@ -1026,9 +1034,9 @@ int SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
preFlushNode (child);
assert (node->getSeq() == mSeq);
assert (node->getSeq() == seq_);
if (doWrite && mBacked)
if (doWrite && backed_)
writeNode (t, seq, child);
node->shareChild (branch, child);
@@ -1038,7 +1046,7 @@ int SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
}
// This inner node can now be shared
if (doWrite && mBacked)
if (doWrite && backed_)
writeNode (t, seq, node);
++flushed;
@@ -1046,12 +1054,12 @@ int SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
if (stack.empty ())
break;
SHAMapTreeNode::pointer parent = std::move (stack.top().first);
std::shared_ptr<SHAMapTreeNode> parent = std::move (stack.top().first);
pos = stack.top().second;
stack.pop();
// Hook this inner node to its parent
assert (parent->getSeq() == mSeq);
assert (parent->getSeq() == seq_);
parent->shareChild (pos, node);
// Continue with parent's next child, if any
@@ -1059,52 +1067,20 @@ int SHAMap::walkSubTree (bool doWrite, NodeObjectType t, std::uint32_t seq)
++pos;
}
// Last inner node is the new root
root = std::move (node);
// Last inner node is the new root_
root_ = std::move (node);
return flushed;
}
bool SHAMap::getPath (uint256 const& index, std::vector< Blob >& nodes, SHANodeFormat format)
{
// Return the path of nodes to the specified index in the specified format
// Return value: true = node present, false = node not present
SHAMapTreeNode* inNode = root.get ();
SHAMapNodeID nodeID;
while (inNode->isInner ())
{
Serializer s;
inNode->addRaw (s, format);
nodes.push_back (s.peekData ());
int branch = nodeID.selectBranch (index);
if (inNode->isEmptyBranch (branch))
return false;
inNode = descendThrow (inNode, branch);
nodeID = nodeID.getChildNodeID (branch);
}
if (inNode->peekItem()->getTag () != index) // path leads to different leaf
return false;
// path leads to the requested leaf
Serializer s;
inNode->addRaw (s, format);
nodes.push_back (std::move(s.peekData ()));
return true;
}
void SHAMap::dump (bool hash)
void SHAMap::dump (bool hash) const
{
int leafCount = 0;
if (journal_.info) journal_.info <<
" MAP Contains";
std::stack <std::pair <SHAMapTreeNode*, SHAMapNodeID> > stack;
stack.push ({root.get (), SHAMapNodeID ()});
stack.push ({root_.get (), SHAMapNodeID ()});
do
{
@@ -1142,21 +1118,20 @@ void SHAMap::dump (bool hash)
leafCount << " resident leaves";
}
SHAMapTreeNode::pointer SHAMap::getCache (uint256 const& hash)
std::shared_ptr<SHAMapTreeNode> SHAMap::getCache (uint256 const& hash) const
{
SHAMapTreeNode::pointer ret = f_.treecache().fetch (hash);
std::shared_ptr<SHAMapTreeNode> ret = f_.treecache().fetch (hash);
assert (!ret || !ret->getSeq());
return ret;
}
void SHAMap::canonicalize (uint256 const& hash, SHAMapTreeNode::pointer& node)
void SHAMap::canonicalize (uint256 const& hash, std::shared_ptr<SHAMapTreeNode>& node) const
{
assert (mBacked);
assert (backed_);
assert (node->getSeq() == 0);
assert (node->getNodeHash() == hash);
f_.treecache().canonicalize (hash, node);
}
} // ripple

View File

@@ -31,7 +31,7 @@ namespace ripple {
// synchronizing matching branches too.)
bool SHAMap::walkBranch (SHAMapTreeNode* node,
SHAMapItem::ref otherMapItem, bool isFirstMap,
std::shared_ptr<SHAMapItem> const& otherMapItem, bool isFirstMap,
Delta& differences, int& maxCount)
{
// Walk a branch of a SHAMap that's matched by an empty branch or single item in the other map
@@ -55,17 +55,17 @@ bool SHAMap::walkBranch (SHAMapTreeNode* node,
else
{
// This is a leaf node, process its item
SHAMapItem::pointer item = node->peekItem ();
std::shared_ptr<SHAMapItem> item = node->peekItem ();
if (emptyBranch || (item->getTag () != otherMapItem->getTag ()))
{
// unmatched
if (isFirstMap)
differences.insert (std::make_pair (item->getTag (),
DeltaRef (item, SHAMapItem::pointer ())));
DeltaRef (item, std::shared_ptr<SHAMapItem> ())));
else
differences.insert (std::make_pair (item->getTag (),
DeltaRef (SHAMapItem::pointer (), item)));
DeltaRef (std::shared_ptr<SHAMapItem> (), item)));
if (--maxCount <= 0)
return false;
@@ -98,12 +98,12 @@ bool SHAMap::walkBranch (SHAMapTreeNode* node,
// otherMapItem was unmatched, must add
if (isFirstMap) // this is first map, so other item is from second
differences.insert (std::make_pair (otherMapItem->getTag (),
DeltaRef (SHAMapItem::pointer(),
DeltaRef (std::shared_ptr<SHAMapItem>(),
otherMapItem)));
else
differences.insert (std::make_pair (otherMapItem->getTag (),
DeltaRef (otherMapItem,
SHAMapItem::pointer ())));
std::shared_ptr<SHAMapItem> ())));
if (--maxCount <= 0)
return false;
@@ -112,7 +112,9 @@ bool SHAMap::walkBranch (SHAMapTreeNode* node,
return true;
}
bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
bool
SHAMap::compare (std::shared_ptr<SHAMap> const& otherMap,
Delta& differences, int maxCount)
{
// compare two hash trees, add up to maxCount differences to the difference table
// return value: true=complete table of differences given, false=too many differences
@@ -127,7 +129,7 @@ bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
if (getHash () == otherMap->getHash ())
return true;
nodeStack.push ({root.get(), otherMap->root.get()});
nodeStack.push ({root_.get(), otherMap->root_.get()});
while (!nodeStack.empty ())
{
SHAMapTreeNode* ourNode = nodeStack.top().first;
@@ -137,7 +139,7 @@ bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
if (!ourNode || !otherNode)
{
assert (false);
throw SHAMapMissingNode (mType, uint256 ());
throw SHAMapMissingNode (type_, uint256 ());
}
if (ourNode->isLeaf () && otherNode->isLeaf ())
@@ -158,12 +160,12 @@ bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
{
differences.insert (std::make_pair(ourNode->peekItem()->getTag (),
DeltaRef(ourNode->peekItem(),
SHAMapItem::pointer ())));
std::shared_ptr<SHAMapItem> ())));
if (--maxCount <= 0)
return false;
differences.insert(std::make_pair(otherNode->peekItem()->getTag (),
DeltaRef(SHAMapItem::pointer(),
DeltaRef(std::shared_ptr<SHAMapItem>(),
otherNode->peekItem ())));
if (--maxCount <= 0)
return false;
@@ -191,7 +193,7 @@ bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
// We have a branch, the other tree does not
SHAMapTreeNode* iNode = descendThrow (ourNode, i);
if (!walkBranch (iNode,
SHAMapItem::pointer (), true,
std::shared_ptr<SHAMapItem> (), true,
differences, maxCount))
return false;
}
@@ -201,7 +203,7 @@ bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
SHAMapTreeNode* iNode =
otherMap->descendThrow(otherNode, i);
if (!otherMap->walkBranch (iNode,
SHAMapItem::pointer(),
std::shared_ptr<SHAMapItem>(),
false, differences, maxCount))
return false;
}
@@ -219,24 +221,24 @@ bool SHAMap::compare (SHAMap::ref otherMap, Delta& differences, int maxCount)
void SHAMap::walkMap (std::vector<SHAMapMissingNode>& missingNodes, int maxMissing)
{
std::stack <SHAMapTreeNode::pointer,
std::vector <SHAMapTreeNode::pointer>> nodeStack;
std::stack <std::shared_ptr<SHAMapTreeNode>,
std::vector <std::shared_ptr<SHAMapTreeNode>>> nodeStack;
if (!root->isInner ()) // root is only node, and we have it
if (!root_->isInner ()) // root_ is only node, and we have it
return;
nodeStack.push (root);
nodeStack.push (root_);
while (!nodeStack.empty ())
{
SHAMapTreeNode::pointer node = std::move (nodeStack.top());
std::shared_ptr<SHAMapTreeNode> node = std::move (nodeStack.top());
nodeStack.pop ();
for (int i = 0; i < 16; ++i)
{
if (!node->isEmptyBranch (i))
{
SHAMapTreeNode::pointer nextNode = descendNoStore (node, i);
std::shared_ptr<SHAMapTreeNode> nextNode = descendNoStore (node, i);
if (nextNode)
{
@@ -245,7 +247,7 @@ void SHAMap::walkMap (std::vector<SHAMapMissingNode>& missingNodes, int maxMissi
}
else
{
missingNodes.emplace_back (mType, node->getChildHash (i));
missingNodes.emplace_back (type_, node->getChildHash (i));
if (--maxMissing <= 0)
return;
}

View File

@@ -28,15 +28,15 @@ operator<< (std::ostream& out, const SHAMapMissingNode& mn)
{
switch (mn.getMapType ())
{
case smtTRANSACTION:
case SHAMapType::TRANSACTION:
out << "Missing/TXN(" << mn.getNodeHash () << ")";
break;
case smtSTATE:
case SHAMapType::STATE:
out << "Missing/STA(" << mn.getNodeHash () << ")";
break;
case smtFREE:
case SHAMapType::FREE:
default:
out << "Missing/" << mn.getNodeHash ();
break;

View File

@@ -57,43 +57,15 @@ SHAMapNodeID::Masks (int depth)
return masks->entry[depth];
}
std::size_t
SHAMapNodeID::calculate_hash (uint256 const& node, int depth)
{
struct HashParams
{
HashParams ()
: golden_ratio (0x9e3779b9)
{
random_fill (&cookie_value);
}
// The cookie value protects us against algorithmic complexity attacks.
std::size_t cookie_value;
std::size_t golden_ratio;
};
static beast::static_initializer <HashParams> params;
std::size_t h = params->cookie_value + (depth * params->golden_ratio);
auto ptr = reinterpret_cast <const unsigned int*> (node.cbegin ());
for (int i = (depth + 7) / 8; i != 0; --i)
h = (h * params->golden_ratio) ^ *ptr++;
return h;
}
// canonicalize the hash to a node ID for this depth
SHAMapNodeID::SHAMapNodeID (int depth, uint256 const& hash)
: mNodeID (hash), mDepth (depth), mHash (0)
: mNodeID (hash), mDepth (depth)
{
assert ((depth >= 0) && (depth < 65));
mNodeID &= Masks(depth);
}
SHAMapNodeID::SHAMapNodeID (void const* ptr, int len) : mHash (0)
SHAMapNodeID::SHAMapNodeID (void const* ptr, int len)
{
if (len < 33)
mDepth = -1;
@@ -113,12 +85,6 @@ std::string SHAMapNodeID::getString () const
"," + to_string (mNodeID) + ")";
}
uint256 SHAMapNodeID::getNodeID (int depth, uint256 const& hash)
{
assert ((depth >= 0) && (depth <= 64));
return hash & Masks(depth);
}
void SHAMapNodeID::addIDRaw (Serializer& s) const
{
s.add256 (mNodeID);
@@ -141,7 +107,7 @@ SHAMapNodeID SHAMapNodeID::getChildNodeID (int m) const
uint256 child (mNodeID);
child.begin ()[mDepth / 2] |= (mDepth & 1) ? m : (m << 4);
return SHAMapNodeID (mDepth + 1, child, true);
return SHAMapNodeID (mDepth + 1, child);
}
// Which branch would contain the specified hash

View File

@@ -29,7 +29,7 @@ namespace ripple {
static const uint256 uZero;
static bool visitLeavesHelper (
std::function <void (SHAMapItem::ref)> const& function,
std::function <void (std::shared_ptr<SHAMapItem> const&)> const& function,
SHAMapTreeNode& node)
{
// Adapt visitNodes to visitLeaves
@@ -39,7 +39,7 @@ static bool visitLeavesHelper (
return false;
}
void SHAMap::visitLeaves (std::function<void (SHAMapItem::ref item)> const& leafFunction)
void SHAMap::visitLeaves (std::function<void (std::shared_ptr<SHAMapItem> const& item)> const& leafFunction)
{
visitNodes (std::bind (visitLeavesHelper,
std::cref (leafFunction), std::placeholders::_1));
@@ -48,20 +48,20 @@ void SHAMap::visitLeaves (std::function<void (SHAMapItem::ref item)> const& leaf
void SHAMap::visitNodes(std::function<bool (SHAMapTreeNode&)> const& function)
{
// Visit every node in a SHAMap
assert (root->isValid ());
assert (root_->isValid ());
if (!root || root->isEmpty ())
if (!root_ || root_->isEmpty ())
return;
function (*root);
function (*root_);
if (!root->isInner ())
if (!root_->isInner ())
return;
using StackEntry = std::pair <int, SHAMapTreeNode::pointer>;
using StackEntry = std::pair <int, std::shared_ptr<SHAMapTreeNode>>;
std::stack <StackEntry, std::vector <StackEntry>> stack;
SHAMapTreeNode::pointer node = root;
std::shared_ptr<SHAMapTreeNode> node = root_;
int pos = 0;
while (1)
@@ -71,7 +71,7 @@ void SHAMap::visitNodes(std::function<bool (SHAMapTreeNode&)> const& function)
uint256 childHash;
if (!node->isEmptyBranch (pos))
{
SHAMapTreeNode::pointer child = descendNoStore (node, pos);
std::shared_ptr<SHAMapTreeNode> child = descendNoStore (node, pos);
if (function (*child))
return;
@@ -115,17 +115,17 @@ void SHAMap::visitNodes(std::function<bool (SHAMapTreeNode&)> const& function)
void SHAMap::getMissingNodes (std::vector<SHAMapNodeID>& nodeIDs, std::vector<uint256>& hashes, int max,
SHAMapSyncFilter* filter)
{
assert (root->isValid ());
assert (root->getNodeHash().isNonZero ());
assert (root_->isValid ());
assert (root_->getNodeHash().isNonZero ());
std::uint32_t generation = f_.fullbelow().getGeneration();
if (root->isFullBelow (generation))
if (root_->isFullBelow (generation))
{
clearSynching ();
return;
}
if (!root->isInner ())
if (!root_->isInner ())
{
if (journal_.warning) journal_.warning <<
"synching empty tree";
@@ -148,7 +148,7 @@ void SHAMap::getMissingNodes (std::vector<SHAMapNodeID>& nodeIDs, std::vector<ui
// Traverse the map without blocking
SHAMapTreeNode *node = root.get ();
SHAMapTreeNode *node = root_.get ();
SHAMapNodeID nodeID;
// The firstChild value is selected randomly so if multiple threads
@@ -169,7 +169,7 @@ void SHAMap::getMissingNodes (std::vector<SHAMapNodeID>& nodeIDs, std::vector<ui
{
uint256 const& childHash = node->getChildHash (branch);
if (! mBacked || ! f_.fullbelow().touch_if_exists (childHash))
if (! backed_ || ! f_.fullbelow().touch_if_exists (childHash))
{
SHAMapNodeID childID = nodeID.getChildNodeID (branch);
bool pending = false;
@@ -217,7 +217,7 @@ void SHAMap::getMissingNodes (std::vector<SHAMapNodeID>& nodeIDs, std::vector<ui
if (fullBelow)
{ // No partial node encountered below this node
node->setFullBelowGen (generation);
if (mBacked)
if (backed_)
f_.fullbelow().insert (node->getNodeHash ());
}
@@ -248,10 +248,10 @@ void SHAMap::getMissingNodes (std::vector<SHAMapNodeID>& nodeIDs, std::vector<ui
auto const& nodeID = std::get<2>(node);
auto const& nodeHash = parent->getChildHash (branch);
SHAMapTreeNode::pointer nodePtr = fetchNodeNT (nodeID, nodeHash, filter);
std::shared_ptr<SHAMapTreeNode> nodePtr = fetchNodeNT (nodeID, nodeHash, filter);
if (nodePtr)
{
if (mBacked)
if (backed_)
canonicalize (nodeHash, nodePtr);
parent->canonicalizeChild (branch, nodePtr);
}
@@ -288,7 +288,7 @@ bool SHAMap::getNodeFat (SHAMapNodeID wanted, std::vector<SHAMapNodeID>& nodeIDs
{
// Gets a node and some of its children
SHAMapTreeNode* node = root.get ();
SHAMapTreeNode* node = root_.get ();
SHAMapNodeID nodeID;
@@ -328,7 +328,7 @@ bool SHAMap::getNodeFat (SHAMapNodeID wanted, std::vector<SHAMapNodeID>& nodeIDs
rawNodes.push_back (std::move (s.peekData ()));
}
if ((!fatRoot && wanted.isRoot ()) || node->isLeaf ()) // don't get a fat root, can't get a fat leaf
if ((!fatRoot && wanted.isRoot ()) || node->isLeaf ()) // don't get a fat root_, can't get a fat leaf
return true;
SHAMapTreeNode* nextNode = nullptr;
@@ -362,26 +362,25 @@ bool SHAMap::getNodeFat (SHAMapNodeID wanted, std::vector<SHAMapNodeID>& nodeIDs
return true;
}
bool SHAMap::getRootNode (Serializer& s, SHANodeFormat format)
bool SHAMap::getRootNode (Serializer& s, SHANodeFormat format) const
{
root->addRaw (s, format);
root_->addRaw (s, format);
return true;
}
SHAMapAddNode SHAMap::addRootNode (Blob const& rootNode,
SHANodeFormat format, SHAMapSyncFilter* filter)
{
// we already have a root node
if (root->getNodeHash ().isNonZero ())
// we already have a root_ node
if (root_->getNodeHash ().isNonZero ())
{
if (journal_.trace) journal_.trace <<
"got root node, already have one";
return SHAMapAddNode::duplicate ();
}
assert (mSeq >= 1);
SHAMapTreeNode::pointer node =
std::make_shared<SHAMapTreeNode> (rootNode, 0,
assert (seq_ >= 1);
auto node = std::make_shared<SHAMapTreeNode> (rootNode, 0,
format, uZero, false);
if (!node)
@@ -391,20 +390,20 @@ SHAMapAddNode SHAMap::addRootNode (Blob const& rootNode,
node->dump (SHAMapNodeID (), journal_);
#endif
if (mBacked)
if (backed_)
canonicalize (node->getNodeHash (), node);
root = node;
root_ = node;
if (root->isLeaf())
if (root_->isLeaf())
clearSynching ();
if (filter)
{
Serializer s;
root->addRaw (s, snfPREFIX);
filter->gotNode (false, SHAMapNodeID{}, root->getNodeHash (),
s.modData (), root->getType ());
root_->addRaw (s, snfPREFIX);
filter->gotNode (false, SHAMapNodeID{}, root_->getNodeHash (),
s.modData (), root_->getType ());
}
return SHAMapAddNode::useful ();
@@ -413,37 +412,37 @@ SHAMapAddNode SHAMap::addRootNode (Blob const& rootNode,
SHAMapAddNode SHAMap::addRootNode (uint256 const& hash, Blob const& rootNode, SHANodeFormat format,
SHAMapSyncFilter* filter)
{
// we already have a root node
if (root->getNodeHash ().isNonZero ())
// we already have a root_ node
if (root_->getNodeHash ().isNonZero ())
{
if (journal_.trace) journal_.trace <<
"got root node, already have one";
assert (root->getNodeHash () == hash);
assert (root_->getNodeHash () == hash);
return SHAMapAddNode::duplicate ();
}
assert (mSeq >= 1);
SHAMapTreeNode::pointer node =
assert (seq_ >= 1);
std::shared_ptr<SHAMapTreeNode> node =
std::make_shared<SHAMapTreeNode> (rootNode, 0,
format, uZero, false);
if (!node || node->getNodeHash () != hash)
return SHAMapAddNode::invalid ();
if (mBacked)
if (backed_)
canonicalize (hash, node);
root = node;
root_ = node;
if (root->isLeaf())
if (root_->isLeaf())
clearSynching ();
if (filter)
{
Serializer s;
root->addRaw (s, snfPREFIX);
filter->gotNode (false, SHAMapNodeID{}, root->getNodeHash (), s.modData (),
root->getType ());
root_->addRaw (s, snfPREFIX);
filter->gotNode (false, SHAMapNodeID{}, root_->getNodeHash (), s.modData (),
root_->getType ());
}
return SHAMapAddNode::useful ();
@@ -465,7 +464,7 @@ SHAMap::addKnownNode (const SHAMapNodeID& node, Blob const& rawNode,
std::uint32_t generation = f_.fullbelow().getGeneration();
SHAMapNodeID iNodeID;
SHAMapTreeNode* iNode = root.get ();
SHAMapTreeNode* iNode = root_.get ();
while (iNode->isInner () && !iNode->isFullBelow (generation) &&
(iNodeID.getDepth () < node.getDepth ()))
@@ -502,14 +501,13 @@ SHAMap::addKnownNode (const SHAMapNodeID& node, Blob const& rawNode,
return SHAMapAddNode::invalid ();
}
SHAMapTreeNode::pointer newNode =
std::make_shared<SHAMapTreeNode> (rawNode, 0, snfWIRE,
auto newNode = std::make_shared<SHAMapTreeNode>(rawNode, 0, snfWIRE,
uZero, false);
if (!newNode->isInBounds (iNodeID))
{
// Map is provably invalid
mState = smsInvalid;
state_ = SHAMapState::Invalid;
return SHAMapAddNode::useful ();
}
@@ -520,7 +518,7 @@ SHAMap::addKnownNode (const SHAMapNodeID& node, Blob const& rawNode,
return SHAMapAddNode::invalid ();
}
if (mBacked)
if (backed_)
canonicalize (childHash, newNode);
prevNode->canonicalizeChild (branch, newNode);
@@ -547,7 +545,7 @@ bool SHAMap::deepCompare (SHAMap& other)
// Intended for debug/test only
std::stack <std::pair <SHAMapTreeNode*, SHAMapTreeNode*> > stack;
stack.push ({root.get(), other.root.get()});
stack.push ({root_.get(), other.root_.get()});
while (!stack.empty ())
{
@@ -619,7 +617,7 @@ bool
SHAMap::hasInnerNode (SHAMapNodeID const& targetNodeID,
uint256 const& targetNodeHash)
{
SHAMapTreeNode* node = root.get ();
SHAMapTreeNode* node = root_.get ();
SHAMapNodeID nodeID;
while (node->isInner () && (nodeID.getDepth () < targetNodeID.getDepth ()))
@@ -638,9 +636,10 @@ SHAMap::hasInnerNode (SHAMapNodeID const& targetNodeID,
/** Does this map have this leaf node?
*/
bool SHAMap::hasLeafNode (uint256 const& tag, uint256 const& targetNodeHash)
bool
SHAMap::hasLeafNode (uint256 const& tag, uint256 const& targetNodeHash)
{
SHAMapTreeNode* node = root.get ();
SHAMapTreeNode* node = root_.get ();
SHAMapNodeID nodeID;
if (!node->isInner()) // only one leaf node in the tree
@@ -697,16 +696,16 @@ void SHAMap::visitDifferences (SHAMap* have, std::function <bool (SHAMapTreeNode
// Visit every node in this SHAMap that is not present
// in the specified SHAMap
if (root->getNodeHash ().isZero ())
if (root_->getNodeHash ().isZero ())
return;
if (have && (root->getNodeHash () == have->root->getNodeHash ()))
if (have && (root_->getNodeHash () == have->root_->getNodeHash ()))
return;
if (root->isLeaf ())
if (root_->isLeaf ())
{
if (! have || ! have->hasLeafNode (root->peekItem()->getTag (), root->getNodeHash ()))
func (*root);
if (! have || ! have->hasLeafNode (root_->peekItem()->getTag (), root_->getNodeHash ()))
func (*root_);
return;
}
@@ -714,7 +713,7 @@ void SHAMap::visitDifferences (SHAMap* have, std::function <bool (SHAMapTreeNode
using StackEntry = std::pair <SHAMapTreeNode*, SHAMapNodeID>;
std::stack <StackEntry, std::vector<StackEntry>> stack;
stack.push ({root.get(), SHAMapNodeID{}});
stack.push ({root_.get(), SHAMapNodeID{}});
while (!stack.empty())
{
@@ -751,24 +750,4 @@ void SHAMap::visitDifferences (SHAMap* have, std::function <bool (SHAMapTreeNode
}
}
std::list <Blob> SHAMap::getTrustedPath (uint256 const& index)
{
auto stack = getStack (index, false);
if (stack.empty () || !stack.top ().first->isLeaf ())
throw std::runtime_error ("requested leaf not present");
std::list< Blob > path;
Serializer s;
while (!stack.empty ())
{
stack.top ().first->addRaw (s, snfWIRE);
path.push_back (s.getData ());
s.erase ();
stack.pop ();
}
return path;
}
} // ripple

View File

@@ -57,7 +57,7 @@ SHAMapTreeNode::SHAMapTreeNode (const SHAMapTreeNode& node, std::uint32_t seq)
}
}
SHAMapTreeNode::SHAMapTreeNode (SHAMapItem::ref item,
SHAMapTreeNode::SHAMapTreeNode (std::shared_ptr<SHAMapItem> const& item,
TNType type, std::uint32_t seq)
: mItem (item)
, mSeq (seq)
@@ -402,7 +402,7 @@ void SHAMapTreeNode::addRaw (Serializer& s, SHANodeFormat format)
assert (false);
}
bool SHAMapTreeNode::setItem (SHAMapItem::ref i, TNType type)
bool SHAMapTreeNode::setItem (std::shared_ptr<SHAMapItem> const& i, TNType type)
{
mType = type;
mItem = i;
@@ -437,12 +437,16 @@ void SHAMapTreeNode::makeInner ()
mHash.zero ();
}
#ifdef BEAST_DEBUG
void SHAMapTreeNode::dump (const SHAMapNodeID & id, beast::Journal journal)
{
if (journal.debug) journal.debug <<
"SHAMapTreeNode(" << id.getNodeID () << ")";
}
#endif // BEAST_DEBUG
std::string SHAMapTreeNode::getString (const SHAMapNodeID & id) const
{
std::string ret = "NodeID(";
@@ -486,7 +490,7 @@ std::string SHAMapTreeNode::getString (const SHAMapNodeID & id) const
}
// We are modifying an inner node
bool SHAMapTreeNode::setChild (int m, uint256 const& hash, SHAMapTreeNode::ref child)
bool SHAMapTreeNode::setChild (int m, uint256 const& hash, std::shared_ptr<SHAMapTreeNode> const& child)
{
assert ((m >= 0) && (m < 16));
assert (mType == tnINNER);
@@ -515,7 +519,7 @@ bool SHAMapTreeNode::setChild (int m, uint256 const& hash, SHAMapTreeNode::ref c
}
// finished modifying, now make shareable
void SHAMapTreeNode::shareChild (int m, SHAMapTreeNode::ref child)
void SHAMapTreeNode::shareChild (int m, std::shared_ptr<SHAMapTreeNode> const& child)
{
assert ((m >= 0) && (m < 16));
assert (mType == tnINNER);
@@ -536,7 +540,7 @@ SHAMapTreeNode* SHAMapTreeNode::getChildPointer (int branch)
return mChildren[branch].get ();
}
SHAMapTreeNode::pointer SHAMapTreeNode::getChild (int branch)
std::shared_ptr<SHAMapTreeNode> SHAMapTreeNode::getChild (int branch)
{
assert (branch >= 0 && branch < 16);
assert (isInnerNode ());
@@ -546,7 +550,7 @@ SHAMapTreeNode::pointer SHAMapTreeNode::getChild (int branch)
return mChildren[branch];
}
void SHAMapTreeNode::canonicalizeChild (int branch, SHAMapTreeNode::pointer& node)
void SHAMapTreeNode::canonicalizeChild (int branch, std::shared_ptr<SHAMapTreeNode>& node)
{
assert (branch >= 0 && branch < 16);
assert (isInnerNode ());

View File

@@ -117,7 +117,7 @@ public:
beast::Journal const j; // debug journal
TestFamily f(j);
std::shared_ptr <Table> t1 (std::make_shared <Table> (
smtFREE, f, beast::Journal()));
SHAMapType::FREE, f, beast::Journal()));
pass ();
@@ -141,7 +141,7 @@ public:
// {
// TestFilter filter (map, beast::Journal());
//
// t3 = std::make_shared <Table> (smtFREE, t2->getHash (),
// t3 = std::make_shared <Table> (SHAMapType::FREE, t2->getHash (),
// fullBelowCache);
//
// expect (t3->fetchRoot (t2->getHash (), &filter), "unable to get root");

View File

@@ -63,12 +63,12 @@ public:
h4.SetHex ("b92891fe4ef6cee585fdc6fda2e09eb4d386363158ec3321b8123e5a772c6ca8");
h5.SetHex ("a92891fe4ef6cee585fdc6fda0e09eb4d386363158ec3321b8123e5a772c6ca7");
SHAMap sMap (smtFREE, f, beast::Journal());
SHAMap sMap (SHAMapType::FREE, f, beast::Journal());
SHAMapItem i1 (h1, IntToVUC (1)), i2 (h2, IntToVUC (2)), i3 (h3, IntToVUC (3)), i4 (h4, IntToVUC (4)), i5 (h5, IntToVUC (5));
unexpected (!sMap.addItem (i2, true, false), "no add");
unexpected (!sMap.addItem (i1, true, false), "no add");
SHAMapItem::pointer i;
std::shared_ptr<SHAMapItem> i;
i = sMap.peekFirstItem ();
unexpected (!i || (*i != i1), "bad traverse");
i = sMap.peekNextItem (i->getTag ());
@@ -89,7 +89,7 @@ public:
testcase ("snapshot");
uint256 mapHash = sMap.getHash ();
SHAMap::pointer map2 = sMap.snapShot (false);
std::shared_ptr<SHAMap> map2 = sMap.snapShot (false);
unexpected (sMap.getHash () != mapHash, "bad snapshot");
unexpected (map2->getHash () != mapHash, "bad snapshot");
unexpected (!sMap.delItem (sMap.peekFirstItem ()->getTag ()), "bad mod");

View File

@@ -37,7 +37,7 @@ namespace tests {
class sync_test : public beast::unit_test::suite
{
public:
static SHAMapItem::pointer makeRandomAS ()
static std::shared_ptr<SHAMapItem> makeRandomAS ()
{
Serializer s;
@@ -56,7 +56,7 @@ public:
for (int i = 0; i < count; ++i)
{
SHAMapItem::pointer item = makeRandomAS ();
std::shared_ptr<SHAMapItem> item = makeRandomAS ();
items.push_back (item->getTag ());
if (!map.addItem (*item, false, false))
@@ -101,8 +101,8 @@ public:
beast::Journal const j; // debug journal
TestFamily f(j);
SHAMap source (smtFREE, f, j);
SHAMap destination (smtFREE, f, j);
SHAMap source (SHAMapType::FREE, f, j);
SHAMap destination (SHAMapType::FREE, f, j);
int items = 10000;
for (int i = 0; i < items; ++i)