preliminary support for "second execution as weak" feature

This commit is contained in:
Richard Holland
2022-05-10 11:38:42 +00:00
parent 7dbfa071b1
commit 0bb38809be
5 changed files with 71 additions and 5 deletions

View File

@@ -282,7 +282,9 @@ namespace hook_api
"hook_pos",
"hook_param",
"hook_param_set",
"hook_skip"
"hook_skip",
"hook_after",
"hook_weak"
};
};
#endif

View File

@@ -152,6 +152,9 @@ namespace hook_api
DECLARE_HOOK_FUNCTION(int64_t, hook_param, uint32_t write_ptr, uint32_t write_len,
uint32_t read_ptr, uint32_t read_len);
DECLARE_HOOK_FUNCNARG(int64_t, hook_after);
DECLARE_HOOK_FUNCNARG(int64_t, hook_weak);
DECLARE_HOOK_FUNCTION(int64_t, hook_skip, uint32_t read_ptr, uint32_t read_len, uint32_t flags);
DECLARE_HOOK_FUNCNARG(int64_t, hook_pos);
@@ -223,6 +226,7 @@ namespace hook
ripple::AccountID const& account, /* the account the hook is INSTALLED ON not always the otxn account */
bool hasCallback,
bool isCallback = false,
bool isStrongTSH = false,
uint32_t wasmParam = 0,
int32_t hookChainPosition = -1
);
@@ -271,10 +275,13 @@ namespace hook
uint64_t instructionCount {0};
bool hasCallback = false; // true iff this hook wasm has a cbak function
bool isCallback = false; // true iff this hook execution is a callback in action
bool isStrong = false;
uint32_t wasmParam = 0;
uint32_t overrideCount = 0;
int32_t hookChainPosition = -1;
bool foreignStateSetDisabled = false;
bool executeAgainAsWeak = false; // hook_after allows strong pre-apply to nominate
// additional weak post-apply execution
};
class HookExecutor;
@@ -547,6 +554,8 @@ namespace hook
ADD_HOOK_FUNCTION(otxn_slot, ctx);
ADD_HOOK_FUNCTION(hook_account, ctx);
ADD_HOOK_FUNCTION(hook_hash, ctx);
ADD_HOOK_FUNCTION(hook_after, ctx);
ADD_HOOK_FUNCTION(hook_weak, ctx);
ADD_HOOK_FUNCTION(fee_base, ctx);
ADD_HOOK_FUNCTION(ledger_seq, ctx);
ADD_HOOK_FUNCTION(ledger_last_hash, ctx);

View File

@@ -681,6 +681,7 @@ hook::apply(
ripple::AccountID const& account, /* the account the hook is INSTALLED ON not always the otxn account */
bool hasCallback,
bool isCallback,
bool isStrong,
uint32_t wasmParam,
int32_t hookChainPosition)
{
@@ -708,6 +709,7 @@ hook::apply(
.exitCode = -1,
.hasCallback = hasCallback,
.isCallback = isCallback,
.isStrong = isStrong,
.wasmParam = wasmParam,
.hookChainPosition = hookChainPosition,
.foreignStateSetDisabled = false
@@ -4489,3 +4491,28 @@ DEFINE_HOOK_FUNCNARG(
return hookCtx.result.hookChainPosition;
}
DEFINE_HOOK_FUNCNARG(
int64_t,
hook_weak)
{
HOOK_SETUP();
return (hookCtx.result.isStrong ? 0 : 1);
}
DEFINE_HOOK_FUNCNARG(
int64_t,
hook_after)
{
HOOK_SETUP();
if (hookCtx.result.executeAgainAsWeak)
return ALREADY_SET;
if (hookCtx.result.isStrong)
{
hookCtx.result.executeAgainAsWeak = true;
return 1;
}
return PREREQUISITE_NOT_MET;
}

View File

@@ -900,7 +900,8 @@ executeHookChain(
std::shared_ptr<ripple::STLedgerEntry const> const& hookSLE,
hook::HookStateMap& stateMap,
std::vector<hook::HookResult>& results,
ripple::AccountID const& account)
ripple::AccountID const& account,
bool strong)
{
std::set<uint256> hookSkips;
std::map<
@@ -976,6 +977,7 @@ executeHookChain(
account,
hasCallback,
false,
strong,
0,
hook_no));
@@ -1112,6 +1114,7 @@ Transactor::doHookCallback()
callbackAccountID,
true,
true,
false,
safe_cast<TxType>(ctx_.tx.getFieldU16(sfTransactionType)) == ttEMIT_FAILURE
? 1UL : 0UL,
hook_no - 1);
@@ -1294,7 +1297,8 @@ doTSH(
tshHook,
stateMap,
results,
tshAccountID);
tshAccountID,
strong);
if (canRollback && (tshResult != tesSUCCESS))
return tshResult;
@@ -1333,6 +1337,13 @@ Transactor::operator()()
bool const hooksEnabled = view().rules().enabled(featureHooks);
// This vector stores any "strong" hooks that requested a weak "after application" re-execution.
std::vector<
std::pair<
AccountID, // account of hook
uint256 // hash of hook
>> executeAgainAsWeak;
// Pre-application (Strong TSH) Hooks are executed here
// These TSH have the right to rollback.
// Weak TSH and callback are executed post-application.
@@ -1356,7 +1367,8 @@ Transactor::operator()()
hooksOriginator,
stateMap,
orgResults,
accountID);
accountID,
true);
if (isTesSuccess(result))
{
@@ -1376,10 +1388,18 @@ Transactor::operator()()
// because it contains error codes that any failed hooks would have
// returned for meta
for (auto& orgResult: orgResults)
{
hook::finalizeHookResult(orgResult, ctx_, isTesSuccess(result));
if (isTesSuccess(result) && orgResult.executeAgainAsWeak)
executeAgainAsWeak.emplace_back(orgResult.account, orgResult.hookHash);
}
for (auto& tshResult: tshResults)
{
hook::finalizeHookResult(tshResult, ctx_, isTesSuccess(result));
if (isTesSuccess(result) && tshResult.executeAgainAsWeak)
executeAgainAsWeak.emplace_back(tshResult.account, tshResult.hookHash);
}
}
@@ -1414,6 +1434,13 @@ Transactor::operator()()
doTSH(false, stateMap, tshResults);
// execute any hooks that nominated for 'again as weak'
for (auto const& [accID, hash] : executeAgainAsWeak)
{
// RH UPTO: execute individual hooks again here
}
// write hook results
hook::finalizeHookState(stateMap, ctx_, ctx_.tx.getTransactionID());
for (auto& tshResult: tshResults)

View File

@@ -204,7 +204,8 @@ protected:
std::shared_ptr<ripple::STLedgerEntry const> const& hookSLE,
hook::HookStateMap& stateMap,
std::vector<hook::HookResult>& results,
ripple::AccountID const& account);
ripple::AccountID const& account,
bool strong);
void
addWeakTSHFromSandbox(detail::ApplyViewBase const& pv);