Add balanceChanges to PaymentSandbox

fold
This commit is contained in:
seelabs
2016-05-25 21:39:23 -04:00
parent a87f56448a
commit 34d590d93a
4 changed files with 146 additions and 3 deletions

View File

@@ -188,6 +188,15 @@ public:
apply (PaymentSandbox& to);
/** @} */
// Return a map of balance changes on trust lines. The low account is the
// first account in the key. If the two accounts are equal, the map contains
// the total changes in currency regardless of issuer. This is useful to get
// the total change in XRP balances.
std::map<std::tuple<AccountID, AccountID, Currency>, STAmount>
balanceChanges (ReadView const& view) const;
XRPAmount xrpDestroyed () const;
private:
detail::DeferredCredits tab_;
PaymentSandbox const* ps_ = nullptr;

View File

@@ -96,7 +96,7 @@ public:
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func);
std::shared_ptr <SLE const> const& after)> const& func) const;
void
erase (ReadView const& base,
@@ -121,6 +121,12 @@ public:
void
destroyXRP (XRPAmount const& fee);
// For debugging
XRPAmount const& dropsDestroyed () const
{
return dropsDestroyed_;
}
private:
using Mods = hash_map<key_type,
std::shared_ptr<SLE>>;

View File

@@ -78,7 +78,7 @@ ApplyStateTable::visit (ReadView const& to,
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func)
std::shared_ptr <SLE const> const& after)> const& func) const
{
for (auto& item : items_)
{

View File

@@ -18,9 +18,11 @@
//==============================================================================
#include <BeastConfig.h>
#include <ripple/app/paths/impl/AmountSpec.h>
#include <ripple/ledger/PaymentSandbox.h>
#include <ripple/ledger/View.h>
#include <ripple/protocol/SField.h>
#include <ripple/protocol/STAccount.h>
#include <boost/optional.hpp>
#include <cassert>
@@ -260,4 +262,130 @@ PaymentSandbox::apply (PaymentSandbox& to)
tab_.apply(to.tab_);
}
std::map<std::tuple<AccountID, AccountID, Currency>, STAmount>
PaymentSandbox::balanceChanges (ReadView const& view) const
{
using key = std::tuple<AccountID, AccountID, Currency>;
// Map of delta trust lines. As a special case, when both ends of the trust
// line are the same currency, then it's delta currency for that issuer. To
// get the change in XRP balance, Account == root, issuer == root, currency == XRP
std::map<key, STAmount> result;
// populate a dictionary with low/high/currency/delta. This can be
// compared with the other versions payment code.
auto each = [&result](uint256 const& key, bool isDelete,
std::shared_ptr<SLE const> const& before,
std::shared_ptr<SLE const> const& after) {
STAmount oldBalance;
STAmount newBalance;
AccountID lowID;
AccountID highID;
// before is read from prev view
if (isDelete)
{
if (!before)
return;
auto const bt = before->getType ();
switch(bt)
{
case ltACCOUNT_ROOT:
lowID = xrpAccount();
highID = (*before)[sfAccount];
oldBalance = (*before)[sfBalance];
newBalance = oldBalance.zeroed();
break;
case ltRIPPLE_STATE:
lowID = (*before)[sfLowLimit].getIssuer();
highID = (*before)[sfHighLimit].getIssuer();
oldBalance = (*before)[sfBalance];
newBalance = oldBalance.zeroed();
break;
case ltOFFER:
// TBD
break;
default:
break;
}
}
if (!before)
{
// insert
auto const at = after->getType ();
switch(at)
{
case ltACCOUNT_ROOT:
lowID = xrpAccount();
highID = (*after)[sfAccount];
newBalance = (*after)[sfBalance];
oldBalance = newBalance.zeroed();
break;
case ltRIPPLE_STATE:
lowID = (*after)[sfLowLimit].getIssuer();
highID = (*after)[sfHighLimit].getIssuer();
newBalance = (*after)[sfBalance];
oldBalance = newBalance.zeroed();
break;
case ltOFFER:
// TBD
break;
default:
break;
}
}
else
{
// modify
auto const at = after->getType ();
assert (at == before->getType ());
switch(at)
{
case ltACCOUNT_ROOT:
lowID = xrpAccount();
highID = (*after)[sfAccount];
oldBalance = (*before)[sfBalance];
newBalance = (*after)[sfBalance];
break;
case ltRIPPLE_STATE:
lowID = (*after)[sfLowLimit].getIssuer();
highID = (*after)[sfHighLimit].getIssuer();
oldBalance = (*before)[sfBalance];
newBalance = (*after)[sfBalance];
break;
case ltOFFER:
// TBD
break;
default:
break;
}
}
// The following are now set, put them in the map
auto delta = newBalance - oldBalance;
auto const cur = newBalance.getCurrency();
result[std::make_tuple(lowID, highID, cur)] = delta;
auto r = result.emplace(std::make_tuple(lowID, lowID, cur), delta);
if (r.second)
{
r.first->second += delta;
}
delta.negate();
r = result.emplace(std::make_tuple(highID, highID, cur), delta);
if (r.second)
{
r.first->second += delta;
}
};
items_.visit (view, each);
return result;
}
XRPAmount PaymentSandbox::xrpDestroyed () const
{
return items_.dropsDestroyed ();
}
} // ripple