Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions src/ripple/app/tx/impl/Change.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <ripple/app/misc/AmendmentTable.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/tx/impl/Change.h>
#include <ripple/app/tx/impl/SetHook.h>
#include <ripple/app/tx/impl/SetSignerList.h>
#include <ripple/app/tx/impl/XahauGenesis.h>
#include <ripple/basics/Log.h>
Expand Down Expand Up @@ -584,10 +585,6 @@ Change::activateXahauGenesis()
SetSignerList::removeFromLedger(ctx_.app, sb, accid, j_);

// Step 4: install genesis hooks
sle->setFieldU32(
sfOwnerCount, sle->getFieldU32(sfOwnerCount) + genesis_hooks.size());
sb.update(sle);

if (sb.exists(keylet::hook(accid)))
{
JLOG(j_.warn()) << "featureXahauGenesis genesis account already has "
Expand All @@ -598,6 +595,7 @@ Change::activateXahauGenesis()
{
ripple::STArray hooks{sfHooks, static_cast<int>(genesis_hooks.size())};
int hookCount = 0;
uint32_t hookReserve = 0;

for (auto const& [hookOn, wasmBytes, params] : genesis_hooks)
{
Expand Down Expand Up @@ -703,8 +701,14 @@ Change::activateXahauGenesis()
}

hooks.push_back(hookObj);

hookReserve += SetHook::computeHookReserve(hookObj);
}

sle->setFieldU32(
sfOwnerCount, sle->getFieldU32(sfOwnerCount) + hookReserve);
sb.update(sle);

auto sle = std::make_shared<SLE>(keylet::hook(accid));
sle->setFieldArray(sfHooks, hooks);
sle->setAccountID(sfAccount, accid);
Expand Down Expand Up @@ -745,6 +749,8 @@ Change::activateXahauGenesis()
ripple::STArray hooks{sfHooks, 1};
STObject hookObj{sfHook};
hookObj.setFieldH256(sfHookHash, governHash);

uint32_t hookReserve = 0;
// parameters
{
std::vector<STObject> vec;
Expand All @@ -760,6 +766,7 @@ Change::activateXahauGenesis()
sfHookParameters, STArray(vec, sfHookParameters));
}

hookReserve += SetHook::computeHookReserve(hookObj);
hooks.push_back(hookObj);

auto sle = std::make_shared<SLE>(hookKL);
Expand All @@ -786,7 +793,8 @@ Change::activateXahauGenesis()

sle->setAccountID(sfRegularKey, noAccount());
sle->setFieldU32(sfFlags, lsfDisableMaster);
sle->setFieldU32(sfOwnerCount, sle->getFieldU32(sfOwnerCount) + 1);
sle->setFieldU32(
sfOwnerCount, sle->getFieldU32(sfOwnerCount) + hookReserve);
sb.update(sle);
}
}
Expand Down
43 changes: 26 additions & 17 deletions src/ripple/app/tx/impl/SetHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,29 @@ updateHookParameters(
return tesSUCCESS;
}

/**
* Compute the reserve required for a hook object.
* @param hookObj The hook object to compute the reserve for.(not Transaction
* field, use the Hook object inside the ltHook object.)
* @return The reserve required for the hook object.
*/
uint32_t
SetHook::computeHookReserve(STObject const& hookObj)
{
if (!hookObj.isFieldPresent(sfHookHash))
return 0;

int reserve{1};

if (hookObj.isFieldPresent(sfHookParameters))
reserve += hookObj.getFieldArray(sfHookParameters).size();

if (hookObj.isFieldPresent(sfHookGrants))
reserve += hookObj.getFieldArray(sfHookGrants).size();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to have a way to ensure hookSetObj is never accidentally passed into here, even just via a comment at the top


return reserve;
};

struct KeyletComparator
{
bool
Expand Down Expand Up @@ -1972,28 +1995,14 @@ SetHook::setHook()
int oldHookReserve = 0;
int newHookReserve = 0;

auto const computeHookReserve = [](STObject const& hookObj) -> int {
if (!hookObj.isFieldPresent(sfHookHash))
return 0;

int reserve{1};

if (hookObj.isFieldPresent(sfHookParameters))
reserve += hookObj.getFieldArray(sfHookParameters).size();

if (hookObj.isFieldPresent(sfHookGrants))
reserve += hookObj.getFieldArray(sfHookGrants).size();

return reserve;
};

for (int i = 0; i < hook::maxHookChainLength(); ++i)
{
if (oldHooks && i < oldHookCount)
oldHookReserve += computeHookReserve(((*oldHooks).get())[i]);
oldHookReserve +=
SetHook::computeHookReserve(((*oldHooks).get())[i]);

if (i < newHooks.size())
newHookReserve += computeHookReserve(newHooks[i]);
newHookReserve += SetHook::computeHookReserve(newHooks[i]);
}

reserveDelta = newHookReserve - oldHookReserve;
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/app/tx/impl/SetHook.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class SetHook : public Transactor
static HookSetValidation
validateHookSetEntry(SetHookCtx& ctx, STObject const& hookSetObj);

static uint32_t
computeHookReserve(STObject const& hookObj);

private:
TER
setHook();
Expand Down
27 changes: 23 additions & 4 deletions src/test/app/XahauGenesis_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ struct XahauGenesis_test : public beast::unit_test::suite
false, // means the calling test already burned some of the genesis
bool skipTests = false,
bool const testFlag = false,
bool const badNetID = false)
bool const badNetID = false,
uint32_t const expectedOwnerCount =
10 /** testFlag ? 10 : 14 (default) */)
{
using namespace jtx;

Expand Down Expand Up @@ -247,7 +249,10 @@ struct XahauGenesis_test : public beast::unit_test::suite
BEAST_EXPECT(
genesisAccRoot->getFieldAmount(sfBalance) ==
XahauGenesis::GenesisAmount);
BEAST_EXPECT(genesisAccRoot->getFieldU32(sfOwnerCount) == 2);
BEAST_EXPECT(
genesisAccRoot->getFieldU32(sfOwnerCount) == !testFlag
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion currently has a precedence bug and is not checking what it appears to check. As written, \ownerCount == !testFlag ? expectedOwnerCount : 14is parsed as(ownerCount == !testFlag) ?
expectedOwnerCount : 14, so BEAST_EXPECT(...)receives eitherexpectedOwnerCountor14(both non-zero), which can pass even whenownerCountis wrong. The intended check is that owner count equalsexpectedOwnerCountwhentestFlag == false, otherwise equals 14. Please parenthesize the ternary on the right-hand side: ownerCount == (!testFlag ? expectedOwnerCount : 14).

? expectedOwnerCount
: 14);

// ensure the definitions are correctly set
{
Expand Down Expand Up @@ -583,7 +588,14 @@ struct XahauGenesis_test : public beast::unit_test::suite
toBase58(t), membersStr);
}

activate(__LINE__, env, true, false, true);
activate(
__LINE__,
env,
true,
false,
true,
{},
3 /* IRR,IRD,IMC */ + members.size() + tables.size());

env.close();
env.close();
Expand Down Expand Up @@ -2235,13 +2247,18 @@ struct XahauGenesis_test : public beast::unit_test::suite
BEAST_EXPECT(!!hookLE);
uint256 const ns = beast::zero;
uint8_t mc = 0;
uint8_t paramsCount = 0;

if (hookLE)
{
auto const hooksArray = hookLE->getFieldArray(sfHooks);
BEAST_EXPECT(
hooksArray.size() == 1 &&
hooksArray[0].getFieldH256(sfHookHash) == governHookHash);

paramsCount =
hooksArray[0].getFieldArray(sfHookParameters).size();

for (Account const* m : members)
{
auto const mVec = vecFromAcc(*m);
Expand Down Expand Up @@ -2308,7 +2325,9 @@ struct XahauGenesis_test : public beast::unit_test::suite
BEAST_EXPECT(!!root);
if (root)
{
BEAST_EXPECT(root->getFieldU32(sfOwnerCount) == mc * 2 + 2);
BEAST_EXPECT(
root->getFieldU32(sfOwnerCount) ==
mc * 2 + 2 + paramsCount);
BEAST_EXPECT(root->getFieldU32(sfFlags) & lsfDisableMaster);
BEAST_EXPECT(root->getAccountID(sfRegularKey) == noAccount());
}
Expand Down
Loading