Remove unfunded offers on tecOVERSIZE

This commit is contained in:
JoelKatz
2015-09-08 12:26:29 -07:00
committed by Nik Bougalis
parent 332114c02a
commit 3759c553b0
10 changed files with 139 additions and 17 deletions

View File

@@ -52,4 +52,19 @@ ApplyContext::apply(TER ter)
view_->apply(base_, tx, ter, journal);
}
std::size_t
ApplyContext::size()
{
return view_->size();
}
void
ApplyContext::visit (std::function <void (
uint256 const&, bool,
std::shared_ptr<SLE const> const&,
std::shared_ptr<SLE const> const&)> const& func)
{
view_->visit(base_, func);
}
} // ripple

View File

@@ -79,6 +79,18 @@ public:
void
apply (TER);
/** Get the number of unapplied changes. */
std::size_t
size ();
/** Visit unapplied changes. */
void
visit (std::function <void (
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func);
void
destroyXRP (std::uint64_t feeDrops)
{

View File

@@ -25,6 +25,7 @@
#include <ripple/core/Config.h>
#include <ripple/core/LoadFeeTrack.h>
#include <ripple/json/to_string.h>
#include <ripple/ledger/View.h>
#include <ripple/protocol/Feature.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/types.h>
@@ -454,6 +455,25 @@ TER Transactor::checkMultiSign ()
//------------------------------------------------------------------------------
void removeUnfundedOffers (ApplyView& view, std::vector<uint256> const& offers)
{
int removed = 0;
for (auto const& index : offers)
{
auto const sleOffer = view.peek (keylet::offer (index));
if (sleOffer)
{
// offer is unfunded
offerDelete (view, sleOffer);
if (++removed == 1000)
return;
}
}
}
//------------------------------------------------------------------------------
static
inline
void
@@ -532,7 +552,7 @@ Transactor::operator()()
bool didApply = isTesSuccess (terResult);
auto fee = tx().getTransactionFee ();
if (view().size() > 5200)
if (ctx_.size() > 5200)
terResult = tecOVERSIZE;
if ((terResult == tecOVERSIZE) ||
@@ -542,6 +562,30 @@ Transactor::operator()()
JLOG(j_.debug) <<
"Reprocessing tx " << txID << " to only claim fee";
std::vector<uint256> removedOffers;
if (terResult == tecOVERSIZE)
{
ctx_.visit (
[&removedOffers](
uint256 const& index,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)
{
if (isDelete)
{
assert (before && after);
if (before && after &&
(before->getType() == ltOFFER) &&
(before->getFieldAmount(sfTakerPays) == after->getFieldAmount(sfTakerPays)))
{
// Removal of offer found or made unfunded
removedOffers.push_back (index);
}
}
});
}
ctx_.discard();
auto const txnAcct = view().peek(
@@ -575,6 +619,10 @@ Transactor::operator()()
fee = balance;
txnAcct->setFieldAmount (sfBalance, balance - fee);
txnAcct->setFieldU32 (sfSequence, t_seq + 1);
if (terResult == tecOVERSIZE)
removeUnfundedOffers (view(), removedOffers);
view().update (txnAcct);
didApply = true;
}

View File

@@ -196,12 +196,6 @@ public:
void
update (std::shared_ptr<SLE> const& sle) = 0;
/** Get the number of modified entries
*/
virtual
std::size_t
size () = 0;
//--------------------------------------------------------------------------
// Called when a credit is made to an account

View File

@@ -85,6 +85,16 @@ public:
std::size_t
size ();
/** Visit modified entries
*/
void
visit (
OpenView& target,
std::function <void (
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func);
private:
boost::optional<STAmount> deliver_;
};

View File

@@ -97,6 +97,14 @@ public:
std::size_t
size ();
void
visit (ReadView const& base,
std::function <void (
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func);
void
erase (ReadView const& base,
std::shared_ptr<SLE> const& sle);

View File

@@ -132,9 +132,6 @@ public:
rawDestroyXRP (
std::uint64_t feeDrops) override;
std::size_t
size () override;
protected:
ApplyFlags flags_;
ReadView const* base_;

View File

@@ -72,6 +72,39 @@ ApplyStateTable::size ()
return ret;
}
void
ApplyStateTable::visit (ReadView const& to,
std::function <void (
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func)
{
for (auto& item : items_)
{
switch (item.second.first)
{
case Action::erase:
func (item.first, true,
to.read (keylet::unchecked (item.first)), item.second.second);
break;
case Action::insert:
func (item.first, false,
nullptr, item.second.second);
break;
case Action::modify:
func (item.first, false,
to.read (keylet::unchecked (item.first)), item.second.second);
break;
default:
break;
}
}
}
void
ApplyStateTable::apply (OpenView& to,
STTx const& tx, TER ter,

View File

@@ -148,13 +148,6 @@ ApplyViewBase::update(
items_.update(*base_, sle);
}
std::size_t
ApplyViewBase::size ()
{
return items_.size ();
}
//---
void

View File

@@ -44,4 +44,16 @@ ApplyViewImpl::size ()
return items_.size ();
}
void
ApplyViewImpl::visit (
OpenView& to,
std::function <void (
uint256 const& key,
bool isDelete,
std::shared_ptr <SLE const> const& before,
std::shared_ptr <SLE const> const& after)> const& func)
{
items_.visit (to, func);
}
} // ripple