From a3902e2c4a0b8aec3e641dd63259c1d482a36edd Mon Sep 17 00:00:00 2001 From: tequ Date: Fri, 14 Feb 2025 11:35:22 +0900 Subject: [PATCH] Fix not to effect to HookStateCount. --- src/ripple/app/hook/applyHook.h | 7 ++- src/ripple/app/hook/impl/applyHook.cpp | 66 ++++++++++++++------------ src/ripple/app/tx/impl/SetHook.cpp | 2 +- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/ripple/app/hook/applyHook.h b/src/ripple/app/hook/applyHook.h index e30a577ca..eb81d1868 100644 --- a/src/ripple/app/hook/applyHook.h +++ b/src/ripple/app/hook/applyHook.h @@ -461,9 +461,12 @@ apply( struct HookContext; uint32_t -computeHookStateOwnerCount(Blob hookStateData); +computeHookStateCount(uint32_t hookStateCount); + uint32_t -computeHookStateOwnerCount(Slice hookStateData); +computeHookStateReserves(Blob hookStateData); +uint32_t +computeHookStateReserves(Slice hookStateData); int64_t computeExecutionFee(uint64_t instructionCount); diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index c9a3ab560..0b4cbcd7f 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -853,13 +853,19 @@ parseCurrency(uint8_t* cu_ptr, uint32_t cu_len) } uint32_t -hook::computeHookStateOwnerCount(Blob hookStateData) +hook::computeHookStateCount(uint32_t hookStateCount) +{ + return hookStateCount; +} + +uint32_t +hook::computeHookStateReserves(Blob hookStateData) { return std::floor((hookStateData.size() - 1) / 256) + 1; } uint32_t -hook::computeHookStateOwnerCount(Slice hookStateData) +hook::computeHookStateReserves(Slice hookStateData) { return std::floor((hookStateData.size() - 1) / 256) + 1; } @@ -1059,13 +1065,18 @@ hook::setHookState( auto hookStateKeylet = ripple::keylet::hookState(acc, key, ns); auto hookStateDirKeylet = ripple::keylet::hookStateDir(acc, ns); - uint32_t newHookStateCount = sleAccount->getFieldU32(sfHookStateCount); - uint32_t oldHookStateCount = newHookStateCount; + uint32_t stateCount = sleAccount->getFieldU32(sfHookStateCount); + uint32_t oldStateCount = stateCount; auto hookState = view.peek(hookStateKeylet); bool createNew = !hookState; + int32_t newHookStateReserves = computeHookStateReserves(data); + int32_t oldHookStateReserves = createNew + ? 0 + : computeHookStateReserves(hookState->getFieldVL(sfHookStateData)); + // if the blob is nil then delete the entry if it exists if (data.empty()) { @@ -1088,22 +1099,18 @@ hook::setHookState( view.erase(hookState); // adjust state object count - Blob deletedStateData = hookState->getFieldVL(sfHookStateData); - uint32_t deleteOwnerCount = - computeHookStateOwnerCount(deletedStateData); - if (newHookStateCount >= deleteOwnerCount) - { - newHookStateCount -= - deleteOwnerCount; // guard this because in the "impossible" - // event it is already 0 we'll wrap back to - // int_max - } + if (stateCount > 0) + --stateCount; // guard this because in the "impossible" event it is + // already 0 we'll wrap back to int_max // if removing this state entry would destroy the allotment then reduce // the owner count - if (newHookStateCount < oldHookStateCount) - adjustOwnerCount(view, sleAccount, -deleteOwnerCount, j); + if (stateCount < oldStateCount) + adjustOwnerCount(view, sleAccount, -oldHookStateReserves, j); - sleAccount->setFieldU32(sfHookStateCount, newHookStateCount); + if (stateCount == 0) + sleAccount->makeFieldAbsent(sfHookStateCount); + else + sleAccount->setFieldU32(sfHookStateCount, stateCount); if (nsDestroyed) hook::removeHookNamespaceEntry(*sleAccount, ns); @@ -1128,26 +1135,25 @@ hook::setHookState( if (createNew) { - uint32_t createdOwnerCount = computeHookStateOwnerCount(data); - newHookStateCount += createdOwnerCount; + ++stateCount; - if (newHookStateCount > oldHookStateCount) + if (stateCount > oldStateCount) { // the hook used its allocated allotment of state entries for its // previous ownercount increment ownercount and give it another // allotment - ownerCount += createdOwnerCount; + ownerCount += newHookStateReserves; XRPAmount const newReserve{view.fees().accountReserve(ownerCount)}; if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserve) return tecINSUFFICIENT_RESERVE; - adjustOwnerCount(view, sleAccount, createdOwnerCount, j); + adjustOwnerCount(view, sleAccount, newHookStateReserves, j); } // update state count - sleAccount->setFieldU32(sfHookStateCount, newHookStateCount); + sleAccount->setFieldU32(sfHookStateCount, stateCount); view.update(sleAccount); // create an entry @@ -1156,23 +1162,21 @@ hook::setHookState( else { // on Update - uint32_t oldOwnerCount = - computeHookStateOwnerCount((*hookState)[sfHookStateData]); - uint32_t newOwnerCount = computeHookStateOwnerCount(data); - - uint32_t changedOwnerCount = newOwnerCount - oldOwnerCount; - newHookStateCount += changedOwnerCount; + uint32_t changedOwnerCount = + newHookStateReserves - oldHookStateReserves; if (changedOwnerCount != 0) { ownerCount += changedOwnerCount; XRPAmount const newReserve{view.fees().accountReserve(ownerCount)}; - if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserve) + if (changedOwnerCount > 0 && + STAmount((*sleAccount)[sfBalance]).xrp() < newReserve) + // only check if increasing reserve return tecINSUFFICIENT_RESERVE; adjustOwnerCount(view, sleAccount, changedOwnerCount, j); - sleAccount->setFieldU32(sfHookStateCount, newHookStateCount); + sleAccount->setFieldU32(sfHookStateCount, stateCount); view.update(sleAccount); } } diff --git a/src/ripple/app/tx/impl/SetHook.cpp b/src/ripple/app/tx/impl/SetHook.cpp index 64668bfaa..019c022ca 100644 --- a/src/ripple/app/tx/impl/SetHook.cpp +++ b/src/ripple/app/tx/impl/SetHook.cpp @@ -895,7 +895,7 @@ SetHook::destroyNamespace( } toDeleteOwnerCount += - hook::computeHookStateOwnerCount((*sleItem)[sfHookStateData]); + hook::computeHookStateReserves((*sleItem)[sfHookStateData]); auto const hint = (*sleItem)[sfOwnerNode]; if (!view.dirRemove(dirKeylet, hint, itemKey, false))