Compare commits

..

2 Commits

Author SHA1 Message Date
tequ
9f97d4643d Merge fixAMMClawbackRounding amendment into featureAMMClawback amendment 2026-02-25 15:27:37 +09:00
yinyiqian1
d9666cee77 fixAMMClawbackRounding: adjust last holder's LPToken balance (#5513)
Due to rounding, the LPTokenBalance of the last LP might not match the LP's trustline balance. This was fixed for `AMMWithdraw` in `fixAMMv1_1` by adjusting the LPTokenBalance to be the same as the trustline balance. Since `AMMClawback` is also performing a withdrawal, we need to adjust LPTokenBalance as well in `AMMClawback.`

This change includes:
1. Refactored `verifyAndAdjustLPTokenBalance` function in `AMMUtils`, which both`AMMWithdraw` and `AMMClawback` call to adjust LPTokenBalance.
2. Added the unit test `testLastHolderLPTokenBalance` to test the scenario.
3. Modify the existing unit tests for `fixAMMClawbackRounding`.
2026-02-25 15:27:33 +09:00
2 changed files with 9 additions and 52 deletions

View File

@@ -310,28 +310,12 @@ LedgerMaster::setValidLedger(std::shared_ptr<Ledger const> const& l)
if (auto const first =
app_.getAmendmentTable().firstUnsupportedExpected())
{
using namespace std::chrono_literals;
auto const now = app_.timeKeeper().closeTime();
if (*first > now && (*first - now) <= 1min)
{
// Shut down just before the amendment activates to
// avoid processing ledgers with unknown fields.
JLOG(m_journal.error())
<< "Unsupported amendment activating imminently "
"at "
<< to_string(*first) << ". Shutting down.";
app_.getOPs().setAmendmentBlocked();
}
else
{
JLOG(m_journal.error())
<< "One or more unsupported amendments "
"reached majority. Upgrade before "
<< to_string(*first)
<< " to prevent your server from "
"becoming amendment blocked.";
app_.getOPs().setAmendmentWarned();
}
JLOG(m_journal.error()) << "One or more unsupported amendments "
"reached majority. Upgrade before "
<< to_string(*first)
<< " to prevent your server from "
"becoming amendment blocked.";
app_.getOPs().setAmendmentWarned();
}
else
app_.getOPs().clearAmendmentWarned();

View File

@@ -1634,16 +1634,6 @@ NetworkOPsImp::setAmendmentBlocked()
{
amendmentBlocked_ = true;
setMode(OperatingMode::CONNECTED);
if (!app_.config().standalone())
{
JLOG(m_journal.fatal())
<< "One or more unsupported amendments activated. "
"Shutting down. Upgrade the server to remain "
"compatible with the network.";
app_.signalStop(
"One or more unsupported amendments activated. "
"Server must be upgraded to remain compatible with the network.");
}
}
inline bool
@@ -1799,23 +1789,8 @@ NetworkOPsImp::switchLastClosedLedger(
clearNeedNetworkLedger();
// Update fee computations. May throw if the ledger contains
// transactions with fields unknown to this binary (e.g. after an
// unsupported amendment activates). Catch to allow graceful shutdown.
//@@start process-closed-ledger-catch
try
{
app_.getTxQ().processClosedLedger(app_, *newLCL, true);
}
catch (std::runtime_error const& e)
{
if (!amendmentBlocked_)
throw;
JLOG(m_journal.error())
<< "Failed to process closed ledger: " << e.what();
return;
}
//@@end process-closed-ledger-catch
// Update fee computations.
app_.getTxQ().processClosedLedger(app_, *newLCL, true);
// Caller must own master lock
{
@@ -2474,7 +2449,7 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
"may be incorrectly configured or some [validator_list_sites] "
"may be unreachable.";
}
if (isAmendmentWarned())
if (admin && isAmendmentWarned())
{
Json::Value& w = warnings.append(Json::objectValue);
w[jss::id] = warnRPC_UNSUPPORTED_MAJORITY;
@@ -2918,7 +2893,6 @@ NetworkOPsImp::pubLedger(std::shared_ptr<ReadView const> const& lpAccepted)
// Ledgers are published only when they acquire sufficient validations
// Holes are filled across connection loss or other catastrophe
//@@start pubLedger-accepted-ledger-construction
std::shared_ptr<AcceptedLedger> alpAccepted =
app_.getAcceptedLedgerCache().fetch(lpAccepted->info().hash);
if (!alpAccepted)
@@ -2927,7 +2901,6 @@ NetworkOPsImp::pubLedger(std::shared_ptr<ReadView const> const& lpAccepted)
app_.getAcceptedLedgerCache().canonicalize_replace_client(
lpAccepted->info().hash, alpAccepted);
}
//@@end pubLedger-accepted-ledger-construction
XRPL_ASSERT(
alpAccepted->getLedger().get() == lpAccepted.get(),