mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-20 03:32:23 +00:00
Compare commits
5 Commits
develop
...
mvadari/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64b53d6890 | ||
|
|
d8f11a9c17 | ||
|
|
ceeff478f4 | ||
|
|
a149cc944a | ||
|
|
c4c76e2aaf |
@@ -17,6 +17,9 @@
|
||||
#include <xrpl/tx/transactors/delegate/DelegateUtils.h>
|
||||
#include <xrpl/tx/transactors/nft/NFTokenUtils.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/** Performs early sanity checks on the txid */
|
||||
@@ -1133,25 +1136,25 @@ Transactor::operator()()
|
||||
// awkward and very limiting. A more general purpose approach
|
||||
// should be used, making it possible to do more useful work
|
||||
// when transactions fail with a `tec` code.
|
||||
std::vector<uint256> removedOffers;
|
||||
std::vector<uint256> removedTrustLines;
|
||||
std::vector<uint256> expiredNFTokenOffers;
|
||||
std::vector<uint256> expiredCredentials;
|
||||
|
||||
bool const doOffers = ((result == tecOVERSIZE) || (result == tecKILLED));
|
||||
bool const doLines = (result == tecINCOMPLETE);
|
||||
bool const doNFTokenOffers = (result == tecEXPIRED);
|
||||
bool const doCredentials = (result == tecEXPIRED);
|
||||
if (doOffers || doLines || doNFTokenOffers || doCredentials)
|
||||
// Build a list of ledger entry types to collect, based on the
|
||||
// result code. Only deleted objects of these types will be
|
||||
// re-applied after the context is reset.
|
||||
std::vector<LedgerEntryType> typesToCollect;
|
||||
if ((result == tecOVERSIZE) || (result == tecKILLED))
|
||||
typesToCollect.push_back(ltOFFER);
|
||||
if (result == tecINCOMPLETE)
|
||||
typesToCollect.push_back(ltRIPPLE_STATE);
|
||||
if (result == tecEXPIRED)
|
||||
{
|
||||
ctx_.visit([doOffers,
|
||||
&removedOffers,
|
||||
doLines,
|
||||
&removedTrustLines,
|
||||
doNFTokenOffers,
|
||||
&expiredNFTokenOffers,
|
||||
doCredentials,
|
||||
&expiredCredentials](
|
||||
typesToCollect.push_back(ltNFTOKEN_OFFER);
|
||||
typesToCollect.push_back(ltCREDENTIAL);
|
||||
}
|
||||
|
||||
std::map<LedgerEntryType, std::vector<uint256>> deletedObjects;
|
||||
if (!typesToCollect.empty())
|
||||
{
|
||||
ctx_.visit([&typesToCollect, &deletedObjects](
|
||||
uint256 const& index,
|
||||
bool isDelete,
|
||||
std::shared_ptr<SLE const> const& before,
|
||||
@@ -1162,25 +1165,21 @@ Transactor::operator()()
|
||||
before && after,
|
||||
"xrpl::Transactor::operator()::visit : non-null SLE "
|
||||
"inputs");
|
||||
if (doOffers && before && after && (before->getType() == ltOFFER) &&
|
||||
(before->getFieldAmount(sfTakerPays) == after->getFieldAmount(sfTakerPays)))
|
||||
if (before && after)
|
||||
{
|
||||
// Removal of offer found or made unfunded
|
||||
removedOffers.push_back(index);
|
||||
auto const type = before->getType();
|
||||
if (std::ranges::find(typesToCollect, type) != typesToCollect.end())
|
||||
{
|
||||
// For offers, only collect unfunded removals
|
||||
// (where TakerPays is unchanged)
|
||||
if (type == ltOFFER &&
|
||||
before->getFieldAmount(sfTakerPays) !=
|
||||
after->getFieldAmount(sfTakerPays))
|
||||
return;
|
||||
|
||||
deletedObjects[type].push_back(index);
|
||||
}
|
||||
}
|
||||
|
||||
if (doLines && before && after && (before->getType() == ltRIPPLE_STATE))
|
||||
{
|
||||
// Removal of obsolete AMM trust line
|
||||
removedTrustLines.push_back(index);
|
||||
}
|
||||
|
||||
if (doNFTokenOffers && before && after &&
|
||||
(before->getType() == ltNFTOKEN_OFFER))
|
||||
expiredNFTokenOffers.push_back(index);
|
||||
|
||||
if (doCredentials && before && after && (before->getType() == ltCREDENTIAL))
|
||||
expiredCredentials.push_back(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1194,18 +1193,34 @@ Transactor::operator()()
|
||||
fee = resetResult.second;
|
||||
}
|
||||
|
||||
// If necessary, remove any offers found unfunded during processing
|
||||
if ((result == tecOVERSIZE) || (result == tecKILLED))
|
||||
removeUnfundedOffers(view(), removedOffers, ctx_.registry.journal("View"));
|
||||
// Re-apply the collected deletions
|
||||
auto const viewJ = ctx_.registry.journal("View");
|
||||
for (auto const& [type, ids] : deletedObjects)
|
||||
{
|
||||
if (ids.empty())
|
||||
continue;
|
||||
|
||||
if (result == tecEXPIRED)
|
||||
removeExpiredNFTokenOffers(view(), expiredNFTokenOffers, ctx_.registry.journal("View"));
|
||||
|
||||
if (result == tecINCOMPLETE)
|
||||
removeDeletedTrustLines(view(), removedTrustLines, ctx_.registry.journal("View"));
|
||||
|
||||
if (result == tecEXPIRED)
|
||||
removeExpiredCredentials(view(), expiredCredentials, ctx_.registry.journal("View"));
|
||||
switch (type)
|
||||
{
|
||||
case ltOFFER:
|
||||
removeUnfundedOffers(view(), ids, viewJ);
|
||||
break;
|
||||
case ltNFTOKEN_OFFER:
|
||||
removeExpiredNFTokenOffers(view(), ids, viewJ);
|
||||
break;
|
||||
case ltRIPPLE_STATE:
|
||||
removeDeletedTrustLines(view(), ids, viewJ);
|
||||
break;
|
||||
case ltCREDENTIAL:
|
||||
removeExpiredCredentials(view(), ids, viewJ);
|
||||
break;
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
UNREACHABLE("xrpl::Transactor::operator() : unexpected type");
|
||||
break;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
applied = isTecClaim(result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user