mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
update invariant check for ttGENESIS_MINT, update tx structure too
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -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&
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -361,8 +361,7 @@ TxFormats::TxFormats()
|
|||||||
add(jss::GenesisMint,
|
add(jss::GenesisMint,
|
||||||
ttGENESIS_MINT,
|
ttGENESIS_MINT,
|
||||||
{
|
{
|
||||||
{sfDestinations, soeREQUIRED},
|
{sfGenesisMints, soeREQUIRED},
|
||||||
{sfAmount, soeREQUIRED}
|
|
||||||
},
|
},
|
||||||
commonFields);
|
commonFields);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user