From 98d8efdb6a13799cbfe07e3b568901e62d6bdd6a Mon Sep 17 00:00:00 2001 From: Richard Holland Date: Tue, 10 Jan 2023 16:04:10 +0000 Subject: [PATCH] trace test cases --- src/ripple/app/hook/Macro.h | 25 ------ src/ripple/app/hook/impl/applyHook.cpp | 64 ++++++++++++--- src/test/app/SetHook_test.cpp | 106 +++++++++++++++++++------ 3 files changed, 133 insertions(+), 62 deletions(-) diff --git a/src/ripple/app/hook/Macro.h b/src/ripple/app/hook/Macro.h index 2ab85bf94..3d7fde28c 100644 --- a/src/ripple/app/hook/Macro.h +++ b/src/ripple/app/hook/Macro.h @@ -177,31 +177,6 @@ return bytes_written;\ } -#define RETURN_HOOK_TRACE(read_ptr, read_len, t)\ -{\ - if (j.trace())\ - {\ - int rl = read_len;\ - if (rl > 1024)\ - rl = 1024;\ - if (NOT_IN_BOUNDS(read_ptr, read_len, memory_length))\ - return OUT_OF_BOUNDS;\ - std::string out;\ - out.reserve(rl);\ - if (!(read_ptr == 0 && read_len == 0))\ - {\ - out = std::string((const char*)(memory + read_ptr), (size_t)rl);\ - /* replace all nul chars with spaces */\ - for (char* ptr = out.data(); ptr < out.data() + out.size(); ++ptr)\ - if (*ptr == '\0') *ptr = ' ';\ - }\ - j.trace()\ - << "HookTrace[" << HC_ACC() << "]: "\ - << out << (out.empty() ? "" : " ")\ - << t;\ - }\ - return 0;\ -} // ptr = pointer inside the wasm memory space #define NOT_IN_BOUNDS(ptr, len, memory_length)\ ((static_cast(ptr) > static_cast(memory_length)) || \ diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index a86672892..e0f7a33a8 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -1052,8 +1052,26 @@ DEFINE_HOOK_FUNCTION( HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx on current stack if (NOT_IN_BOUNDS(read_ptr, read_len, memory_length)) return OUT_OF_BOUNDS; + + if (!j.trace()) + return 0; - RETURN_HOOK_TRACE(read_ptr, read_len, number); + if (read_len > 128) + read_len = 128; + + if (read_len > 0) + { + j.trace() + << "HookTrace[" << HC_ACC() << "]: " + << std::string_view((const char*)memory + read_ptr, read_len) + << " " << number; + return 0; + } + + j.trace() + << "HookTrace[" << HC_ACC() << "]: " + << number; + return 0; } @@ -1120,8 +1138,14 @@ DEFINE_HOOK_FUNCTION( } } - RETURN_HOOK_TRACE(mread_ptr, mread_len, - std::string((const char*)output_storage, out_len)); + if (out_len > 0) + { + j.trace() + << "HookTrace[" << HC_ACC() << "]: " + << std::string_view((const char*)output_storage, out_len); + } + + return 0; } @@ -1311,7 +1335,6 @@ DEFINE_HOOK_FUNCTION( // update or create a hook state object // read_ptr = data to set, kread_ptr = key // RH NOTE passing 0 size causes a delete operation which is as-intended -// RH TODO: check reserve /* uint32_t write_ptr, uint32_t write_len, uint32_t kread_ptr, uint32_t kread_len, // key @@ -4133,22 +4156,41 @@ DEFINE_HOOK_FUNCTION( int64_t float1) { HOOK_SETUP(); // populates memory_ctx, memory, memory_length, applyCtx on current stack - if (!j.trace()) - return 0; - if (NOT_IN_BOUNDS(read_ptr, read_len, memory_length)) return OUT_OF_BOUNDS; - if (float1 == 0) - RETURN_HOOK_TRACE(read_ptr, read_len, "Float 0*10^(0) "); + if (!j.trace()) + return 0; + if (read_len > 128) + read_len = 128; + + if (float1 == 0) + { + j.trace() + << "HookTrace[" << HC_ACC() << "]:" + << (read_len == 0 ? "" : std::string_view((const char*)memory + read_ptr, read_len)) + << " Float 0*10^(0) "; + return 0; + } + uint64_t man = get_mantissa(float1); int32_t exp = get_exponent(float1); bool neg = is_negative(float1); if (man < minMantissa || man > maxMantissa || exp < minExponent || exp > maxExponent) - RETURN_HOOK_TRACE(read_ptr, read_len, "Float "); + { + j.trace() + << "HookTrace[" << HC_ACC() << "]:" + << (read_len == 0 ? "" : std::string_view((const char*)memory + read_ptr, read_len)) + << " Float "; + return 0; + } - RETURN_HOOK_TRACE(read_ptr, read_len, "Float " << (neg ? "-" : "") << man << "*10^(" << exp << ")"); + j.trace() + << "HookTrace[" << HC_ACC() << "]:" + << (read_len == 0 ? "" : std::string_view((const char*)memory + read_ptr, read_len)) + << " Float " << (neg ? "-" : "") << man << "*10^(" << exp << ")"; + return 0; } DEFINE_HOOK_FUNCTION( diff --git a/src/test/app/SetHook_test.cpp b/src/test/app/SetHook_test.cpp index f67484d2b..289adb5b8 100644 --- a/src/test/app/SetHook_test.cpp +++ b/src/test/app/SetHook_test.cpp @@ -9053,28 +9053,6 @@ public: env(pay(bob, alice, XRP(1)), M("test sto_validate"), fee(XRP(1))); } - /* - void - test_str_compare() - { - } - - void - test_str_concat() - { - } - - void - test_str_find() - { - } - - void - test_str_replace() - { - } - */ - void test_trace() { @@ -9129,13 +9107,89 @@ public: void test_trace_float() { - // TODO + testcase("Test trace_float"); + using namespace jtx; + + Env env{*this, supported_amendments()}; + + auto const alice = Account{"alice"}; + auto const bob = Account{"bob"}; + env.fund(XRP(10000), alice); + env.fund(XRP(10000), bob); + + TestHook hook = wasm[R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + #define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1) + extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t rollback (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t trace_float (uint32_t, uint32_t, int64_t); + #define OUT_OF_BOUNDS -1 + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + int64_t hook(uint32_t reservmaed ) + { + _g(1,1); + // Test out of bounds check + ASSERT(trace_float(1000000, 10, 0) == OUT_OF_BOUNDS); + ASSERT(trace_float(0, 1000000, 0) == OUT_OF_BOUNDS); + return accept(0,0,0); + } + )[test.hook]"]; + + // install the hook on alice + env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), + M("set trace_float"), + HSFEE); + env.close(); + + // invoke the hook + env(pay(bob, alice, XRP(1)), M("test trace_float"), fee(XRP(1))); } void test_trace_num() { - // TODO + testcase("Test trace_num"); + using namespace jtx; + + Env env{*this, supported_amendments()}; + + auto const alice = Account{"alice"}; + auto const bob = Account{"bob"}; + env.fund(XRP(10000), alice); + env.fund(XRP(10000), bob); + + TestHook hook = wasm[R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + #define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1) + extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t rollback (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t trace_num (uint32_t, uint32_t, int64_t); + #define OUT_OF_BOUNDS -1 + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + int64_t hook(uint32_t r ) + { + _g(1,1); + // Test out of bounds check + ASSERT(trace_num(1000000, 10, 0) == OUT_OF_BOUNDS); + ASSERT(trace_num(0, 1000000, 0) == OUT_OF_BOUNDS); + return accept(0,0,0); + } + )[test.hook]"]; + + // install the hook on alice + env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), + M("set trace_num"), + HSFEE); + env.close(); + + // invoke the hook + env(pay(bob, alice, XRP(1)), M("test trace_num"), fee(XRP(1))); } void @@ -11020,8 +11074,8 @@ public: test_sto_validate(); // test_trace(); // - test_trace_float(); - test_trace_num(); + test_trace_float(); // + test_trace_num(); // test_util_accid(); // test_util_keylet(); //