diff --git a/src/ripple/app/tx/impl/ApplyContext.cpp b/src/ripple/app/tx/impl/ApplyContext.cpp index 1763a639e..f3131950f 100644 --- a/src/ripple/app/tx/impl/ApplyContext.cpp +++ b/src/ripple/app/tx/impl/ApplyContext.cpp @@ -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 const&, + std::shared_ptr const&)> const& func) +{ + view_->visit(base_, func); +} + } // ripple diff --git a/src/ripple/app/tx/impl/ApplyContext.h b/src/ripple/app/tx/impl/ApplyContext.h index 4094316e2..8d9498548 100644 --- a/src/ripple/app/tx/impl/ApplyContext.h +++ b/src/ripple/app/tx/impl/ApplyContext.h @@ -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 const& before, + std::shared_ptr const& after)> const& func); + void destroyXRP (std::uint64_t feeDrops) { diff --git a/src/ripple/app/tx/impl/Transactor.cpp b/src/ripple/app/tx/impl/Transactor.cpp index 8479a9736..ef5905f68 100644 --- a/src/ripple/app/tx/impl/Transactor.cpp +++ b/src/ripple/app/tx/impl/Transactor.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -454,6 +455,25 @@ TER Transactor::checkMultiSign () //------------------------------------------------------------------------------ +void removeUnfundedOffers (ApplyView& view, std::vector 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 removedOffers; + if (terResult == tecOVERSIZE) + { + ctx_.visit ( + [&removedOffers]( + uint256 const& index, + bool isDelete, + std::shared_ptr const& before, + std::shared_ptr 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; } diff --git a/src/ripple/ledger/ApplyView.h b/src/ripple/ledger/ApplyView.h index 9b85de26a..0d96b1e9d 100644 --- a/src/ripple/ledger/ApplyView.h +++ b/src/ripple/ledger/ApplyView.h @@ -196,12 +196,6 @@ public: void update (std::shared_ptr const& sle) = 0; - /** Get the number of modified entries - */ - virtual - std::size_t - size () = 0; - //-------------------------------------------------------------------------- // Called when a credit is made to an account diff --git a/src/ripple/ledger/ApplyViewImpl.h b/src/ripple/ledger/ApplyViewImpl.h index c9883e521..668ccc649 100644 --- a/src/ripple/ledger/ApplyViewImpl.h +++ b/src/ripple/ledger/ApplyViewImpl.h @@ -85,6 +85,16 @@ public: std::size_t size (); + /** Visit modified entries + */ + void + visit ( + OpenView& target, + std::function const& before, + std::shared_ptr const& after)> const& func); private: boost::optional deliver_; }; diff --git a/src/ripple/ledger/detail/ApplyStateTable.h b/src/ripple/ledger/detail/ApplyStateTable.h index e621d812c..dbbd2c6b3 100644 --- a/src/ripple/ledger/detail/ApplyStateTable.h +++ b/src/ripple/ledger/detail/ApplyStateTable.h @@ -97,6 +97,14 @@ public: std::size_t size (); + void + visit (ReadView const& base, + std::function const& before, + std::shared_ptr const& after)> const& func); + void erase (ReadView const& base, std::shared_ptr const& sle); diff --git a/src/ripple/ledger/detail/ApplyViewBase.h b/src/ripple/ledger/detail/ApplyViewBase.h index 2fa6d54dc..afd565d1e 100644 --- a/src/ripple/ledger/detail/ApplyViewBase.h +++ b/src/ripple/ledger/detail/ApplyViewBase.h @@ -132,9 +132,6 @@ public: rawDestroyXRP ( std::uint64_t feeDrops) override; - std::size_t - size () override; - protected: ApplyFlags flags_; ReadView const* base_; diff --git a/src/ripple/ledger/impl/ApplyStateTable.cpp b/src/ripple/ledger/impl/ApplyStateTable.cpp index 3f3e934fd..93e8d52b6 100644 --- a/src/ripple/ledger/impl/ApplyStateTable.cpp +++ b/src/ripple/ledger/impl/ApplyStateTable.cpp @@ -72,6 +72,39 @@ ApplyStateTable::size () return ret; } +void +ApplyStateTable::visit (ReadView const& to, + std::function const& before, + std::shared_ptr 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, diff --git a/src/ripple/ledger/impl/ApplyViewBase.cpp b/src/ripple/ledger/impl/ApplyViewBase.cpp index da5818086..22491d4ca 100644 --- a/src/ripple/ledger/impl/ApplyViewBase.cpp +++ b/src/ripple/ledger/impl/ApplyViewBase.cpp @@ -148,13 +148,6 @@ ApplyViewBase::update( items_.update(*base_, sle); } -std::size_t -ApplyViewBase::size () -{ - return items_.size (); -} - - //--- void diff --git a/src/ripple/ledger/impl/ApplyViewImpl.cpp b/src/ripple/ledger/impl/ApplyViewImpl.cpp index 3a1603cdb..58e112441 100644 --- a/src/ripple/ledger/impl/ApplyViewImpl.cpp +++ b/src/ripple/ledger/impl/ApplyViewImpl.cpp @@ -44,4 +44,16 @@ ApplyViewImpl::size () return items_.size (); } +void +ApplyViewImpl::visit ( + OpenView& to, + std::function const& before, + std::shared_ptr const& after)> const& func) +{ + items_.visit (to, func); +} + } // ripple