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()); ApplyViewImpl& avi = dynamic_cast<ApplyViewImpl&>(applyCtx.view());
uint16_t exec_index = avi.nextHookExecutionIndex(); 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 // 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) if (doEmit)
{ {
DBG_PRINTF("emitted txn count: %d\n", hookResult.emittedTxn.size()); DBG_PRINTF("emitted txn count: %d\n", hookResult.emittedTxn.size());
@@ -1766,7 +1767,7 @@ finalizeHookResult(
if (!sleEmitted) if (!sleEmitted)
{ {
++emission_count; emission_txnid.push_back(id);
sleEmitted = std::make_shared<SLE>(emittedId); sleEmitted = std::make_shared<SLE>(emittedId);
// RH TODO: add a new constructor to STObject to avoid this serder thing // 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 // add a metadata entry for this hook execution result
STObject meta { sfHookExecution }; {
meta.setFieldU8(sfHookResult, hookResult.exitType ); STObject meta { sfHookExecution };
meta.setAccountID(sfHookAccount, hookResult.account); 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 // 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. // however to ensure this is consistent across different arch/compilers it's done explicitly here.
uint64_t unsigned_exit_code = uint64_t unsigned_exit_code =
( hookResult.exitCode >= 0 ? hookResult.exitCode : ( hookResult.exitCode >= 0 ? hookResult.exitCode :
0x8000000000000000ULL + (-1 * hookResult.exitCode )); 0x8000000000000000ULL + (-1 * hookResult.exitCode ));
meta.setFieldU64(sfHookReturnCode, unsigned_exit_code); meta.setFieldU64(sfHookReturnCode, unsigned_exit_code);
meta.setFieldVL(sfHookReturnString, ripple::Slice{hookResult.exitReason.data(), hookResult.exitReason.size()}); meta.setFieldVL(sfHookReturnString, ripple::Slice{hookResult.exitReason.data(), hookResult.exitReason.size()});
meta.setFieldU64(sfHookInstructionCount, hookResult.instructionCount); meta.setFieldU64(sfHookInstructionCount, hookResult.instructionCount);
meta.setFieldU16(sfHookEmitCount, emission_count); // this will never wrap, hard limit meta.setFieldU16(sfHookEmitCount, emission_txnid.size()); // this will never wrap, hard limit
meta.setFieldU16(sfHookExecutionIndex, exec_index ); meta.setFieldU16(sfHookExecutionIndex, exec_index );
meta.setFieldU16(sfHookStateChangeCount, hookResult.changedStateCount ); meta.setFieldU16(sfHookStateChangeCount, hookResult.changedStateCount );
meta.setFieldH256(sfHookHash, hookResult.hookHash); meta.setFieldH256(sfHookHash, hookResult.hookHash);
avi.addHookMetaData(std::move(meta)); 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; return tesSUCCESS;
} }

View File

@@ -213,6 +213,12 @@ URIToken::preclaim(PreclaimContext const& ctx)
if (ctx.view.exists( if (ctx.view.exists(
keylet::uritoken(acc, ctx.tx.getFieldVL(sfURI)))) keylet::uritoken(acc, ctx.tx.getFieldVL(sfURI))))
return tecDUPLICATE; 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; return tesSUCCESS;
} }
@@ -370,7 +376,16 @@ URIToken::doApply()
return tecDUPLICATE; return tecDUPLICATE;
sleU = std::make_shared<SLE>(*kl); 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->setAccountID(sfIssuer, account_);
sleU->setFieldVL(sfURI, ctx_.tx.getFieldVL(sfURI)); sleU->setFieldVL(sfURI, ctx_.tx.getFieldVL(sfURI));
@@ -381,7 +396,7 @@ URIToken::doApply()
sleU->setFlag(tfBurnable); sleU->setFlag(tfBurnable);
auto const page = view().dirInsert( auto const page = view().dirInsert(
keylet::ownerDir(account_), *kl, describeOwnerDir(account_)); keylet::ownerDir(dest), *kl, describeOwnerDir(dest));
JLOG(j_.trace()) JLOG(j_.trace())
<< "Adding URIToken to owner directory " << to_string(kl->key) << "Adding URIToken to owner directory " << to_string(kl->key)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -232,6 +232,7 @@ CONSTRUCT_TYPED_SFIELD(sfEscrowID, "EscrowID", UINT256,
CONSTRUCT_TYPED_SFIELD(sfURITokenID, "URITokenID", UINT256, 36); CONSTRUCT_TYPED_SFIELD(sfURITokenID, "URITokenID", UINT256, 36);
CONSTRUCT_TYPED_SFIELD(sfGovernanceFlags, "GovernanceFlags", UINT256, 99); CONSTRUCT_TYPED_SFIELD(sfGovernanceFlags, "GovernanceFlags", UINT256, 99);
CONSTRUCT_TYPED_SFIELD(sfGovernanceMarks, "GovernanceMarks", UINT256, 98); CONSTRUCT_TYPED_SFIELD(sfGovernanceMarks, "GovernanceMarks", UINT256, 98);
CONSTRUCT_TYPED_SFIELD(sfEmittedTxnID, "EmittedTxnID", UINT256, 97);
// currency amount (common) // currency amount (common)
CONSTRUCT_TYPED_SFIELD(sfAmount, "Amount", AMOUNT, 1); 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(sfGenesisMint, "GenesisMint", OBJECT, 96);
CONSTRUCT_UNTYPED_SFIELD(sfActiveValidator, "ActiveValidator", OBJECT, 95); CONSTRUCT_UNTYPED_SFIELD(sfActiveValidator, "ActiveValidator", OBJECT, 95);
CONSTRUCT_UNTYPED_SFIELD(sfImportVLKey, "ImportVLKey", OBJECT, 94); CONSTRUCT_UNTYPED_SFIELD(sfImportVLKey, "ImportVLKey", OBJECT, 94);
CONSTRUCT_UNTYPED_SFIELD(sfHookEmission, "HookEmission", OBJECT, 93);
// array of objects // array of objects
// ARRAY/1 is reserved for end of array // 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(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(sfHookEmissions, "HookEmissions", ARRAY, 95);
CONSTRUCT_UNTYPED_SFIELD(sfGenesisMints, "GenesisMints", ARRAY, 96); CONSTRUCT_UNTYPED_SFIELD(sfGenesisMints, "GenesisMints", ARRAY, 96);
CONSTRUCT_UNTYPED_SFIELD(sfActiveValidators, "ActiveValidators", ARRAY, 95); CONSTRUCT_UNTYPED_SFIELD(sfActiveValidators, "ActiveValidators", ARRAY, 95);
CONSTRUCT_UNTYPED_SFIELD(sfImportVLKeys, "ImportVLKeys", ARRAY, 94); CONSTRUCT_UNTYPED_SFIELD(sfImportVLKeys, "ImportVLKeys", ARRAY, 94);

View File

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

View File

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