mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
exitWith
This commit is contained in:
@@ -91,7 +91,6 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
.nextSequence = nextSequence,
|
||||
.otxnAccount = otxn.id(),
|
||||
.otxnId = txId,
|
||||
.exitType = ripple::ExitType::ROLLBACK,
|
||||
.exitCode = -1,
|
||||
.dataMap = dataMap,
|
||||
.eventMap = eventMap,
|
||||
|
||||
@@ -264,7 +264,7 @@ ContractCall::doApply()
|
||||
.nextSequence = caSle->getFieldU32(sfSequence),
|
||||
.otxnAccount = account_,
|
||||
.otxnId = ctx_.tx.getTransactionID(),
|
||||
.exitType = ripple::ExitType::ROLLBACK,
|
||||
.exitReason = "",
|
||||
.exitCode = -1,
|
||||
.dataMap = dataMap,
|
||||
.eventMap = eventMap,
|
||||
@@ -306,8 +306,9 @@ ContractCall::doApply()
|
||||
auto ret = re.value().result;
|
||||
if (ret < 0)
|
||||
{
|
||||
JLOG(j_.error()) << "Contract Failure: " << ret;
|
||||
JLOG(j_.error()) << "WASM Execution Failed: " << contractCtx.result.exitReason;
|
||||
ctx_.setWasmReturnCode(ret);
|
||||
// ctx_.setWasmReturnStr(contractCtx.result.exitReason);
|
||||
return tecWASM_REJECTED;
|
||||
}
|
||||
|
||||
@@ -325,6 +326,7 @@ ContractCall::doApply()
|
||||
}
|
||||
|
||||
ctx_.setWasmReturnCode(ret);
|
||||
// ctx_.setWasmReturnStr(contractCtx.result.exitReason);
|
||||
ctx_.setEmittedTxns(contractCtx.result.emittedTxns);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
@@ -333,6 +335,7 @@ ContractCall::doApply()
|
||||
JLOG(j_.error()) << "WASM Failure: " + transHuman(re.error());
|
||||
auto const errorCode = TERtoInt(re.error());
|
||||
ctx_.setWasmReturnCode(errorCode);
|
||||
// ctx_.setWasmReturnStr(contractCtx.result.exitReason);
|
||||
return re.error();
|
||||
}
|
||||
return tesSUCCESS;
|
||||
|
||||
@@ -86,7 +86,7 @@ struct ContractResult
|
||||
ripple::AccountID const
|
||||
otxnAccount; // AccountID for the originating transaction
|
||||
ripple::uint256 const otxnId; // ID for the originating transaction
|
||||
ripple::ExitType exitType = ripple::ExitType::ROLLBACK;
|
||||
std::string exitReason{""};
|
||||
int64_t exitCode{-1};
|
||||
ContractDataMap dataMap;
|
||||
ContractEventMap eventMap;
|
||||
|
||||
@@ -118,6 +118,9 @@ public:
|
||||
Expected<int32_t, HostFunctionError>
|
||||
emitEvent(std::string_view const& eventName, STJson const& eventData)
|
||||
override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
exitWith(int32_t code, std::string_view const& msg) override;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -643,6 +643,12 @@ struct HostFunctions
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
exitWith(int32_t code, std::string_view const& msg)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual ~HostFunctions() = default;
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
|
||||
@@ -714,4 +714,12 @@ emitEvent_wrap(
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
|
||||
using exitWith_proto =
|
||||
int32_t(int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
exitWith_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -1102,4 +1102,14 @@ ContractHostFunctionsImpl::emitEvent(
|
||||
}
|
||||
}
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
ContractHostFunctionsImpl::exitWith(
|
||||
int32_t code,
|
||||
std::string_view const& msg)
|
||||
{
|
||||
contractCtx.result.exitReason = std::string(msg);
|
||||
contractCtx.result.exitCode = code;
|
||||
return code;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -2562,6 +2562,38 @@ emitEvent_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
rt, params, results, hf->emitEvent(*name, *parsed), index);
|
||||
}
|
||||
|
||||
wasm_trap_t*
|
||||
exitWith_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
auto* hf = reinterpret_cast<HostFunctions*>(env);
|
||||
auto const* rt = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
int index = 0;
|
||||
|
||||
auto const code = getDataInt32(rt, params, index);
|
||||
if (!code)
|
||||
{
|
||||
return hfResult(results, code.error());
|
||||
}
|
||||
|
||||
if (params->data[2].of.i32 > maxWasmDataLength)
|
||||
{
|
||||
return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE);
|
||||
}
|
||||
|
||||
auto const msg = getDataString(rt, params, index);
|
||||
if (!msg)
|
||||
{
|
||||
return hfResult(results, msg.error());
|
||||
}
|
||||
|
||||
// Call exitWith to store the exit code and reason
|
||||
[[maybe_unused]] auto result = hf->exitWith(*code, *msg);
|
||||
|
||||
// ALWAYS return a trap to halt execution
|
||||
// This ensures WASM stops here
|
||||
return static_cast<wasm_trap_t*>(WasmEngine::instance().newTrap(*msg));
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
namespace test {
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ setCommonHostFunctions(HostFunctions* hfs, std::vector<WasmImportFunc>& i)
|
||||
WASM_IMPORT_FUNC2(i, emitBuiltTxn, "emit_built_txn", hfs, 2'000);
|
||||
WASM_IMPORT_FUNC2(i, emitTxn, "emit_txn", hfs, 2'000);
|
||||
WASM_IMPORT_FUNC2(i, emitEvent, "emit_event", hfs, 70);
|
||||
WASM_IMPORT_FUNC2(i, exitWith, "exit_with", hfs, 70);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user