update invariant check for ttGENESIS_MINT, update tx structure too

This commit is contained in:
Richard Holland
2023-06-05 09:53:03 +00:00
parent 4c6fd4785d
commit 58d71b8c96
6 changed files with 39 additions and 12 deletions

View File

@@ -107,7 +107,7 @@ int64_t hook(uint32_t r)
int64_t tt = otxn_type(); int64_t tt = otxn_type();
if (tt != 99 && tt != ) // ttINVOKE or ttGENESIS_MINT accepted if (tt != 99) // ttINVOKE or ttGENESIS_MINT accepted
DONE("Governance: Passing non-Invoke txn. HookOn should be changed to avoid this."); DONE("Governance: Passing non-Invoke txn. HookOn should be changed to avoid this.");
// get the account id // get the account id
@@ -124,7 +124,6 @@ int64_t hook(uint32_t r)
TRACEVAR(member_count); TRACEVAR(member_count);
// outgoing txns to other hooks allowed // outgoing txns to other hooks allowed
// but a self ttINVOKE means rewards hook is trying to get the governance hook to distribute governance rewards
int64_t is_distribution = 0; int64_t is_distribution = 0;
int64_t is_setup = member_count == DOESNT_EXIST; int64_t is_setup = member_count == DOESNT_EXIST;

View File

@@ -143,13 +143,15 @@ XRPNotCreated::visitEntry(
bool bool
XRPNotCreated::finalize( XRPNotCreated::finalize(
STTx const& tx, STTx const& tx,
TER const, TER const res,
XRPAmount const fee, XRPAmount const fee,
ReadView const& view, ReadView const& view,
beast::Journal const& j) beast::Journal const& j)
{ {
if (view.rules().enabled(featureImport) && tx.getTxnType() == ttIMPORT) auto const tt = tx.getTxnType();
if (view.rules().enabled(featureImport) && tt == ttIMPORT && res == tesSUCCESS)
{ {
// different rules for ttIMPORT // different rules for ttIMPORT
auto const [inner, meta] = Import::getInnerTxn(tx, j); auto const [inner, meta] = Import::getInnerTxn(tx, j);
@@ -176,6 +178,24 @@ XRPNotCreated::finalize(
return (drops_ == dropsAdded.drops() - fee.drops()); return (drops_ == dropsAdded.drops() - fee.drops());
} }
if (view.rules().enabled(featureXahauGenesis) && tt == ttGENESIS_MINT && res == tesSUCCESS)
{
// different rules for ttGENESIS_MINT
auto const& dests = tx.getFieldArray(sfGenesisMints);
XRPAmount dropsAdded { beast::zero };
for (auto const& dest: dests)
dropsAdded += dest.getFieldAmount(sfAmount).xrp();
JLOG(j.trace())
<< "Invariant XRPNotCreated GenesisMint: "
<< "dropsAdded: " << dropsAdded
<< " fee.drops(): " << fee.drops()
<< " drops_: " << drops_
<< " dropsAdded - fee.drops(): " << dropsAdded - fee.drops();
return (drops_ == dropsAdded.drops() - fee.drops());
}
// The net change should never be positive, as this would mean that the // The net change should never be positive, as this would mean that the
// transaction created XRP out of thin air. That's not possible. // transaction created XRP out of thin air. That's not possible.
if (drops_ > 0) if (drops_ > 0)
@@ -518,16 +538,16 @@ ValidNewAccountRoot::finalize(
if (accountsCreated_ == 0) if (accountsCreated_ == 0)
return true; return true;
if (accountsCreated_ > 1) auto tt = tx.getTxnType();
if (accountsCreated_ > 1 && tt != ttGENESIS_MINT)
{ {
JLOG(j.fatal()) << "Invariant failed: multiple accounts " JLOG(j.fatal()) << "Invariant failed: multiple accounts "
"created in a single transaction"; "created in a single transaction";
return false; return false;
} }
// From this point on we know exactly one account was created. if ((tt == ttPAYMENT || tt == ttIMPORT || tt == ttGENESIS_MINT) && result == tesSUCCESS)
auto tt = tx.getTxnType();
if ((tt == ttPAYMENT || tt == ttIMPORT) && result == tesSUCCESS)
{ {
std::uint32_t const startingSeq{ std::uint32_t const startingSeq{
view.rules().enabled(featureDeletableAccounts) ? view.seq() : 1}; view.rules().enabled(featureDeletableAccounts) ? view.seq() : 1};

View File

@@ -594,6 +594,7 @@ extern SField const sfAffectedNodes;
extern SField const sfMemos; extern SField const sfMemos;
extern SField const sfNFTokens; extern SField const sfNFTokens;
extern SField const sfHooks; extern SField const sfHooks;
extern SField const sfGenesisMint;
// array of objects (uncommon) // array of objects (uncommon)
extern SField const sfMajorities; extern SField const sfMajorities;
@@ -603,7 +604,7 @@ extern SField const sfHookExecution;
extern SField const sfHookParameters; extern SField const sfHookParameters;
extern SField const sfHooks; extern SField const sfHooks;
extern SField const sfHookGrants; extern SField const sfHookGrants;
extern SField const sfDestinations; extern SField const sfGenesisMints;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -125,6 +125,13 @@ InnerObjectFormats::InnerObjectFormats()
{sfNFTokenID, soeREQUIRED}, {sfNFTokenID, soeREQUIRED},
{sfURI, soeOPTIONAL}, {sfURI, soeOPTIONAL},
}); });
add(sfGenesisMint.jsonName.c_str(),
sfGenesisMint.getCode(),
{
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED},
});
} }
InnerObjectFormats const& InnerObjectFormats const&

View File

@@ -336,6 +336,7 @@ CONSTRUCT_UNTYPED_SFIELD(sfHookExecution, "HookExecution", OBJECT,
CONSTRUCT_UNTYPED_SFIELD(sfHookDefinition, "HookDefinition", OBJECT, 22); CONSTRUCT_UNTYPED_SFIELD(sfHookDefinition, "HookDefinition", OBJECT, 22);
CONSTRUCT_UNTYPED_SFIELD(sfHookParameter, "HookParameter", OBJECT, 23); CONSTRUCT_UNTYPED_SFIELD(sfHookParameter, "HookParameter", OBJECT, 23);
CONSTRUCT_UNTYPED_SFIELD(sfHookGrant, "HookGrant", OBJECT, 24); CONSTRUCT_UNTYPED_SFIELD(sfHookGrant, "HookGrant", OBJECT, 24);
CONSTRUCT_UNTYPED_SFIELD(sfGenesisMint, "GenesisMint", OBJECT, 25);
// array of objects // array of objects
// ARRAY/1 is reserved for end of array // ARRAY/1 is reserved for end of array
@@ -356,7 +357,7 @@ CONSTRUCT_UNTYPED_SFIELD(sfDisabledValidators, "DisabledValidators", ARRAY,
CONSTRUCT_UNTYPED_SFIELD(sfHookExecutions, "HookExecutions", ARRAY, 18); CONSTRUCT_UNTYPED_SFIELD(sfHookExecutions, "HookExecutions", ARRAY, 18);
CONSTRUCT_UNTYPED_SFIELD(sfHookParameters, "HookParameters", ARRAY, 19); CONSTRUCT_UNTYPED_SFIELD(sfHookParameters, "HookParameters", ARRAY, 19);
CONSTRUCT_UNTYPED_SFIELD(sfHookGrants, "HookGrants", ARRAY, 20); CONSTRUCT_UNTYPED_SFIELD(sfHookGrants, "HookGrants", ARRAY, 20);
CONSTRUCT_UNTYPED_SFIELD(sfDestinations, "Destinations", ARRAY, 21); CONSTRUCT_UNTYPED_SFIELD(sfGenesisMints, "GenesisMints", ARRAY, 21);
// clang-format on // clang-format on

View File

@@ -361,8 +361,7 @@ TxFormats::TxFormats()
add(jss::GenesisMint, add(jss::GenesisMint,
ttGENESIS_MINT, ttGENESIS_MINT,
{ {
{sfDestinations, soeREQUIRED}, {sfGenesisMints, soeREQUIRED},
{sfAmount, soeREQUIRED}
}, },
commonFields); commonFields);