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_pos",
"hook_param", "hook_param",
"hook_param_set", "hook_param_set",
"hook_skip" "hook_skip",
"hook_after",
"hook_weak"
}; };
}; };
#endif #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, DECLARE_HOOK_FUNCTION(int64_t, hook_param, uint32_t write_ptr, uint32_t write_len,
uint32_t read_ptr, uint32_t read_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_FUNCTION(int64_t, hook_skip, uint32_t read_ptr, uint32_t read_len, uint32_t flags);
DECLARE_HOOK_FUNCNARG(int64_t, hook_pos); 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 */ ripple::AccountID const& account, /* the account the hook is INSTALLED ON not always the otxn account */
bool hasCallback, bool hasCallback,
bool isCallback = false, bool isCallback = false,
bool isStrongTSH = false,
uint32_t wasmParam = 0, uint32_t wasmParam = 0,
int32_t hookChainPosition = -1 int32_t hookChainPosition = -1
); );
@@ -271,10 +275,13 @@ namespace hook
uint64_t instructionCount {0}; uint64_t instructionCount {0};
bool hasCallback = false; // true iff this hook wasm has a cbak function 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 isCallback = false; // true iff this hook execution is a callback in action
bool isStrong = false;
uint32_t wasmParam = 0; uint32_t wasmParam = 0;
uint32_t overrideCount = 0; uint32_t overrideCount = 0;
int32_t hookChainPosition = -1; int32_t hookChainPosition = -1;
bool foreignStateSetDisabled = false; bool foreignStateSetDisabled = false;
bool executeAgainAsWeak = false; // hook_after allows strong pre-apply to nominate
// additional weak post-apply execution
}; };
class HookExecutor; class HookExecutor;
@@ -547,6 +554,8 @@ namespace hook
ADD_HOOK_FUNCTION(otxn_slot, ctx); ADD_HOOK_FUNCTION(otxn_slot, ctx);
ADD_HOOK_FUNCTION(hook_account, ctx); ADD_HOOK_FUNCTION(hook_account, ctx);
ADD_HOOK_FUNCTION(hook_hash, 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(fee_base, ctx);
ADD_HOOK_FUNCTION(ledger_seq, ctx); ADD_HOOK_FUNCTION(ledger_seq, ctx);
ADD_HOOK_FUNCTION(ledger_last_hash, 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 */ ripple::AccountID const& account, /* the account the hook is INSTALLED ON not always the otxn account */
bool hasCallback, bool hasCallback,
bool isCallback, bool isCallback,
bool isStrong,
uint32_t wasmParam, uint32_t wasmParam,
int32_t hookChainPosition) int32_t hookChainPosition)
{ {
@@ -708,6 +709,7 @@ hook::apply(
.exitCode = -1, .exitCode = -1,
.hasCallback = hasCallback, .hasCallback = hasCallback,
.isCallback = isCallback, .isCallback = isCallback,
.isStrong = isStrong,
.wasmParam = wasmParam, .wasmParam = wasmParam,
.hookChainPosition = hookChainPosition, .hookChainPosition = hookChainPosition,
.foreignStateSetDisabled = false .foreignStateSetDisabled = false
@@ -4489,3 +4491,28 @@ DEFINE_HOOK_FUNCNARG(
return hookCtx.result.hookChainPosition; 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, std::shared_ptr<ripple::STLedgerEntry const> const& hookSLE,
hook::HookStateMap& stateMap, hook::HookStateMap& stateMap,
std::vector<hook::HookResult>& results, std::vector<hook::HookResult>& results,
ripple::AccountID const& account) ripple::AccountID const& account,
bool strong)
{ {
std::set<uint256> hookSkips; std::set<uint256> hookSkips;
std::map< std::map<
@@ -976,6 +977,7 @@ executeHookChain(
account, account,
hasCallback, hasCallback,
false, false,
strong,
0, 0,
hook_no)); hook_no));
@@ -1112,6 +1114,7 @@ Transactor::doHookCallback()
callbackAccountID, callbackAccountID,
true, true,
true, true,
false,
safe_cast<TxType>(ctx_.tx.getFieldU16(sfTransactionType)) == ttEMIT_FAILURE safe_cast<TxType>(ctx_.tx.getFieldU16(sfTransactionType)) == ttEMIT_FAILURE
? 1UL : 0UL, ? 1UL : 0UL,
hook_no - 1); hook_no - 1);
@@ -1294,7 +1297,8 @@ doTSH(
tshHook, tshHook,
stateMap, stateMap,
results, results,
tshAccountID); tshAccountID,
strong);
if (canRollback && (tshResult != tesSUCCESS)) if (canRollback && (tshResult != tesSUCCESS))
return tshResult; return tshResult;
@@ -1333,6 +1337,13 @@ Transactor::operator()()
bool const hooksEnabled = view().rules().enabled(featureHooks); 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 // Pre-application (Strong TSH) Hooks are executed here
// These TSH have the right to rollback. // These TSH have the right to rollback.
// Weak TSH and callback are executed post-application. // Weak TSH and callback are executed post-application.
@@ -1356,7 +1367,8 @@ Transactor::operator()()
hooksOriginator, hooksOriginator,
stateMap, stateMap,
orgResults, orgResults,
accountID); accountID,
true);
if (isTesSuccess(result)) if (isTesSuccess(result))
{ {
@@ -1376,10 +1388,18 @@ Transactor::operator()()
// because it contains error codes that any failed hooks would have // because it contains error codes that any failed hooks would have
// returned for meta // returned for meta
for (auto& orgResult: orgResults) for (auto& orgResult: orgResults)
{
hook::finalizeHookResult(orgResult, ctx_, isTesSuccess(result)); hook::finalizeHookResult(orgResult, ctx_, isTesSuccess(result));
if (isTesSuccess(result) && orgResult.executeAgainAsWeak)
executeAgainAsWeak.emplace_back(orgResult.account, orgResult.hookHash);
}
for (auto& tshResult: tshResults) for (auto& tshResult: tshResults)
{
hook::finalizeHookResult(tshResult, ctx_, isTesSuccess(result)); 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); 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 // write hook results
hook::finalizeHookState(stateMap, ctx_, ctx_.tx.getTransactionID()); hook::finalizeHookState(stateMap, ctx_, ctx_.tx.getTransactionID());
for (auto& tshResult: tshResults) for (auto& tshResult: tshResults)

View File

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