add sfHookEmissions to metadata, compiling untested

This commit is contained in:
Richard Holland
2023-07-11 19:58:45 +00:00
parent 4f86551fb3
commit 96af8735ba
12 changed files with 106 additions and 24 deletions

View File

@@ -1745,8 +1745,9 @@ finalizeHookResult(
ApplyViewImpl& avi = dynamic_cast<ApplyViewImpl&>(applyCtx.view());
uint16_t exec_index = avi.nextHookExecutionIndex();
uint16_t emission_count = 0;
// apply emitted transactions to the ledger (by adding them to the emitted directory) if we are allowed to
std::vector<uint256> emission_txnid;
if (doEmit)
{
DBG_PRINTF("emitted txn count: %d\n", hookResult.emittedTxn.size());
@@ -1766,7 +1767,7 @@ finalizeHookResult(
if (!sleEmitted)
{
++emission_count;
emission_txnid.push_back(id);
sleEmitted = std::make_shared<SLE>(emittedId);
// RH TODO: add a new constructor to STObject to avoid this serder thing
@@ -1801,24 +1802,39 @@ finalizeHookResult(
}
// add a metadata entry for this hook execution result
STObject meta { sfHookExecution };
meta.setFieldU8(sfHookResult, hookResult.exitType );
meta.setAccountID(sfHookAccount, hookResult.account);
{
STObject meta { sfHookExecution };
meta.setFieldU8(sfHookResult, hookResult.exitType );
meta.setAccountID(sfHookAccount, hookResult.account);
// RH NOTE: this is probably not necessary, a direct cast should always put the (negative) 1 bit at the MSB
// however to ensure this is consistent across different arch/compilers it's done explicitly here.
uint64_t unsigned_exit_code =
( hookResult.exitCode >= 0 ? hookResult.exitCode :
0x8000000000000000ULL + (-1 * hookResult.exitCode ));
// RH NOTE: this is probably not necessary, a direct cast should always put the (negative) 1 bit at the MSB
// however to ensure this is consistent across different arch/compilers it's done explicitly here.
uint64_t unsigned_exit_code =
( hookResult.exitCode >= 0 ? hookResult.exitCode :
0x8000000000000000ULL + (-1 * hookResult.exitCode ));
meta.setFieldU64(sfHookReturnCode, unsigned_exit_code);
meta.setFieldVL(sfHookReturnString, ripple::Slice{hookResult.exitReason.data(), hookResult.exitReason.size()});
meta.setFieldU64(sfHookInstructionCount, hookResult.instructionCount);
meta.setFieldU16(sfHookEmitCount, emission_count); // this will never wrap, hard limit
meta.setFieldU16(sfHookExecutionIndex, exec_index );
meta.setFieldU16(sfHookStateChangeCount, hookResult.changedStateCount );
meta.setFieldH256(sfHookHash, hookResult.hookHash);
avi.addHookMetaData(std::move(meta));
meta.setFieldU64(sfHookReturnCode, unsigned_exit_code);
meta.setFieldVL(sfHookReturnString, ripple::Slice{hookResult.exitReason.data(), hookResult.exitReason.size()});
meta.setFieldU64(sfHookInstructionCount, hookResult.instructionCount);
meta.setFieldU16(sfHookEmitCount, emission_txnid.size()); // this will never wrap, hard limit
meta.setFieldU16(sfHookExecutionIndex, exec_index );
meta.setFieldU16(sfHookStateChangeCount, hookResult.changedStateCount );
meta.setFieldH256(sfHookHash, hookResult.hookHash);
avi.addHookExecutionMetaData(std::move(meta));
}
// if any txns were emitted then add them to the HookEmissions
if (!emission_txnid.empty())
{
for (auto const& etxnid : emission_txnid)
{
STObject meta { sfHookEmission };
meta.setFieldH256(sfHookHash, hookResult.hookHash);
meta.setAccountID(sfHookAccount, hookResult.account);
meta.setFieldH256(sfEmittedTxnID, etxnid);
avi.addHookEmissionMetaData(std::move(meta));
}
}
return tesSUCCESS;
}

View File

@@ -213,6 +213,12 @@ URIToken::preclaim(PreclaimContext const& ctx)
if (ctx.view.exists(
keylet::uritoken(acc, ctx.tx.getFieldVL(sfURI))))
return tecDUPLICATE;
// check if destination is specified, and if it is then check if it exists
if (ctx.tx.isFieldPresent(sfDestination) &&
!ctx.view.exists(keylet::account(ctx.tx.getAccountID(sfDestination))))
return tecNO_DST;
return tesSUCCESS;
}
@@ -370,7 +376,16 @@ URIToken::doApply()
return tecDUPLICATE;
sleU = std::make_shared<SLE>(*kl);
sleU->setAccountID(sfOwner, account_);
AccountID dest =
ctx_.tx.isFieldPresent(sfDestination)
? ctx_.tx.getAccountID(sfDestination)
: account_;
if (!view().exists(keylet::account(dest)))
return tecNO_DST;
sleU->setAccountID(sfOwner, dest);
sleU->setAccountID(sfIssuer, account_);
sleU->setFieldVL(sfURI, ctx_.tx.getFieldVL(sfURI));
@@ -381,7 +396,7 @@ URIToken::doApply()
sleU->setFlag(tfBurnable);
auto const page = view().dirInsert(
keylet::ownerDir(account_), *kl, describeOwnerDir(account_));
keylet::ownerDir(dest), *kl, describeOwnerDir(dest));
JLOG(j_.trace())
<< "Adding URIToken to owner directory " << to_string(kl->key)

View File

@@ -79,11 +79,17 @@ public:
* Takes ownership / use std::move
*/
void
addHookMetaData(STObject&& hookExecution)
addHookExecutionMetaData(STObject&& hookExecution)
{
hookExecution_.push_back(std::move(hookExecution));
}
void
addHookEmissionMetaData(STObject&& hookEmission)
{
hookEmission_.push_back(std::move(hookEmission));
}
void
setHookMetaData(std::vector<STObject>&& vec)
{
@@ -122,6 +128,7 @@ public:
private:
std::optional<STAmount> deliver_;
std::vector<STObject> hookExecution_;
std::vector<STObject> hookEmission_;
};
} // namespace ripple

View File

@@ -74,6 +74,7 @@ public:
STTx const& tx,
std::optional<STAmount> const& deliver,
std::vector<STObject> const& hookExecution,
std::vector<STObject> const& hookEmission,
beast::Journal j);
void
@@ -83,6 +84,7 @@ public:
TER ter,
std::optional<STAmount> const& deliver,
std::vector<STObject> const& hookExecution,
std::vector<STObject> const& hookEmission,
beast::Journal j);
bool

View File

@@ -117,6 +117,7 @@ ApplyStateTable::generateTxMeta(
STTx const& tx,
std::optional<STAmount> const& deliver,
std::vector<STObject> const& hookExecution,
std::vector<STObject> const& hookEmission,
beast::Journal j)
{
TxMeta meta(tx.getTransactionID(), to.seq());
@@ -126,6 +127,9 @@ ApplyStateTable::generateTxMeta(
if (!hookExecution.empty())
meta.setHookExecutions(STArray{hookExecution, sfHookExecutions});
if (!hookEmission.empty())
meta.setHookEmissions(STArray{hookEmission, sfHookEmissions});
Mods newMod;
for (auto& item : items_)
{
@@ -257,6 +261,7 @@ ApplyStateTable::apply(
TER ter,
std::optional<STAmount> const& deliver,
std::vector<STObject> const& hookExecution,
std::vector<STObject> const& hookEmission,
beast::Journal j)
{
// Build metadata and insert
@@ -268,7 +273,7 @@ ApplyStateTable::apply(
// generate meta
auto [meta, newMod] =
generateTxMeta(to, tx, deliver, hookExecution, j);
generateTxMeta(to, tx, deliver, hookExecution, hookEmission, j);
// add any new modified nodes to the modification set
for (auto& mod : newMod)

View File

@@ -31,7 +31,7 @@ ApplyViewImpl::ApplyViewImpl(ReadView const* base, ApplyFlags flags)
void
ApplyViewImpl::apply(OpenView& to, STTx const& tx, TER ter, beast::Journal j)
{
items_.apply(to, tx, ter, deliver_, hookExecution_, j);
items_.apply(to, tx, ter, deliver_, hookExecution_, hookEmission_, j);
}
TxMeta
@@ -39,7 +39,7 @@ ApplyViewImpl::
generateProvisionalMeta(OpenView const& to, STTx const& tx, beast::Journal j)
{
auto [meta, _] =
items_.generateTxMeta(to, tx, deliver_, hookExecution_, j);
items_.generateTxMeta(to, tx, deliver_, hookExecution_, hookEmission_, j);
return meta;
}

View File

@@ -479,6 +479,7 @@ extern SF_UINT256 const sfEscrowID;
extern SF_UINT256 const sfURITokenID;
extern SF_UINT256 const sfGovernanceFlags;
extern SF_UINT256 const sfGovernanceMarks;
extern SF_UINT256 const sfEmittedTxnID;
// currency amount (common)
extern SF_AMOUNT const sfAmount;
@@ -585,6 +586,7 @@ extern SField const sfHookParameter;
extern SField const sfHookGrant;
extern SField const sfActiveValidator;
extern SField const sfImportVLKey;
extern SField const sfHookEmission;
// array of objects (common)
// ARRAY/1 is reserved for end of array
@@ -611,6 +613,7 @@ extern SField const sfHookGrants;
extern SField const sfGenesisMints;
extern SField const sfActiveValidators;
extern SField const sfImportVLKeys;
extern SField const sfHookEmissions;
//------------------------------------------------------------------------------

View File

@@ -122,18 +122,36 @@ public:
return *mHookExecutions;
}
STArray const&
getHookEmissions() const
{
return *mHookEmissions;
}
void
setHookExecutions(STArray const& hookExecutions)
{
mHookExecutions = hookExecutions;
}
void
setHookEmissions(STArray const& hookEmissions)
{
mHookEmissions = hookEmissions;
}
bool
hasHookExecutions() const
{
return static_cast<bool>(mHookExecutions);
}
bool
hasHookEmissions() const
{
return static_cast<bool>(mHookEmissions);
}
STAmount
getDeliveredAmount() const
{
@@ -155,6 +173,7 @@ private:
std::optional<STAmount> mDelivered;
std::optional<STArray> mHookExecutions;
std::optional<STArray> mHookEmissions;
STArray mNodes;
};

View File

@@ -78,6 +78,14 @@ InnerObjectFormats::InnerObjectFormats()
{sfHookEmitCount, soeREQUIRED}
});
add(sfHookEmission.jsonName.c_str(),
sfHookEmission.getCode(),
{
{sfHookHash, soeREQUIRED},
{sfHookAccount, soeREQUIRED},
{sfEmittedTxnID, soeREQUIRED}
});
add(sfHookDefinition.jsonName.c_str(),
sfHookDefinition.getCode(),
{

View File

@@ -232,6 +232,7 @@ CONSTRUCT_TYPED_SFIELD(sfEscrowID, "EscrowID", UINT256,
CONSTRUCT_TYPED_SFIELD(sfURITokenID, "URITokenID", UINT256, 36);
CONSTRUCT_TYPED_SFIELD(sfGovernanceFlags, "GovernanceFlags", UINT256, 99);
CONSTRUCT_TYPED_SFIELD(sfGovernanceMarks, "GovernanceMarks", UINT256, 98);
CONSTRUCT_TYPED_SFIELD(sfEmittedTxnID, "EmittedTxnID", UINT256, 97);
// currency amount (common)
CONSTRUCT_TYPED_SFIELD(sfAmount, "Amount", AMOUNT, 1);
@@ -341,6 +342,7 @@ CONSTRUCT_UNTYPED_SFIELD(sfHookGrant, "HookGrant", OBJECT,
CONSTRUCT_UNTYPED_SFIELD(sfGenesisMint, "GenesisMint", OBJECT, 96);
CONSTRUCT_UNTYPED_SFIELD(sfActiveValidator, "ActiveValidator", OBJECT, 95);
CONSTRUCT_UNTYPED_SFIELD(sfImportVLKey, "ImportVLKey", OBJECT, 94);
CONSTRUCT_UNTYPED_SFIELD(sfHookEmission, "HookEmission", OBJECT, 93);
// array of objects
// ARRAY/1 is reserved for end of array
@@ -361,6 +363,7 @@ CONSTRUCT_UNTYPED_SFIELD(sfDisabledValidators, "DisabledValidators", ARRAY,
CONSTRUCT_UNTYPED_SFIELD(sfHookExecutions, "HookExecutions", ARRAY, 18);
CONSTRUCT_UNTYPED_SFIELD(sfHookParameters, "HookParameters", ARRAY, 19);
CONSTRUCT_UNTYPED_SFIELD(sfHookGrants, "HookGrants", ARRAY, 20);
CONSTRUCT_UNTYPED_SFIELD(sfHookEmissions, "HookEmissions", ARRAY, 95);
CONSTRUCT_UNTYPED_SFIELD(sfGenesisMints, "GenesisMints", ARRAY, 96);
CONSTRUCT_UNTYPED_SFIELD(sfActiveValidators, "ActiveValidators", ARRAY, 95);
CONSTRUCT_UNTYPED_SFIELD(sfImportVLKeys, "ImportVLKeys", ARRAY, 94);

View File

@@ -398,6 +398,7 @@ TxFormats::TxFormats()
{
{sfURI, soeREQUIRED},
{sfDigest, soeOPTIONAL},
{sfDestination, soeOPTIONAL},
{sfTicketSequence, soeOPTIONAL},
},
commonFields);

View File

@@ -225,6 +225,9 @@ TxMeta::getAsObject() const
if (hasHookExecutions())
metaData.setFieldArray(sfHookExecutions, getHookExecutions());
if (hasHookEmissions())
metaData.setFieldArray(sfHookEmissions, getHookEmissions());
return metaData;
}