This commit is contained in:
Denis Angell
2025-11-07 14:16:06 +01:00
parent 56c848e62a
commit 650dc3d479
9 changed files with 66 additions and 4 deletions

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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
};

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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
}