mirror of
https://github.com/Xahau/xahaud.git
synced 2026-07-07 07:10:09 +00:00
Compare commits
21 Commits
fixHookMem
...
subscripti
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93910f6295 | ||
|
|
15181211df | ||
|
|
c1488a7f0b | ||
|
|
12e8e79b1f | ||
|
|
d214344616 | ||
|
|
db7ecfb86a | ||
|
|
280659c32b | ||
|
|
827177d009 | ||
|
|
67eebc686a | ||
|
|
60401fcb40 | ||
|
|
2d7b17ae1f | ||
|
|
159e00570d | ||
|
|
202353ac8c | ||
|
|
12cdcbcecf | ||
|
|
1855350b65 | ||
|
|
41db993a20 | ||
|
|
7241fed6d0 | ||
|
|
a6dfb40413 | ||
|
|
3e0d6b9cd2 | ||
|
|
a8388e48a4 | ||
|
|
49908096d5 |
@@ -77,6 +77,11 @@ test.ledger > xrpld.app
|
||||
test.ledger > xrpld.core
|
||||
test.ledger > xrpld.ledger
|
||||
test.ledger > xrpl.protocol
|
||||
test.net > test.toplevel
|
||||
test.net > xrpl.basics
|
||||
test.net > xrpld.core
|
||||
test.net > xrpld.net
|
||||
test.net > xrpl.json
|
||||
test.nodestore > test.jtx
|
||||
test.nodestore > test.toplevel
|
||||
test.nodestore > test.unit_test
|
||||
|
||||
@@ -95,16 +95,8 @@ if [[ "$4" == "" ]]; then
|
||||
echo "Non GH, local building, no Action runner magic"
|
||||
else
|
||||
# GH Action, runner
|
||||
if [[ "$(git rev-parse --abbrev-ref HEAD)" == "release" ]]; then
|
||||
echo "building on the release branch... placing it in builds/candidate"
|
||||
mkdir /data/builds/candidate
|
||||
cp /io/release-build/xahaud /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
else
|
||||
echo "building non-release branch, placing it in builds root"
|
||||
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
fi
|
||||
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
echo "Published build to: http://build.xahau.tech/"
|
||||
echo $(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
fi
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#define featureHooksUpdate2 "1"
|
||||
#define fix20250131 "1"
|
||||
#define fixGuardDepth32 "1"
|
||||
#define fixHookMemoryMissing "1"
|
||||
namespace hook_api {
|
||||
struct Rules
|
||||
{
|
||||
@@ -268,7 +267,6 @@ enum hook_log_code : uint16_t {
|
||||
CUSTOM_SECTION_DISALLOWED =
|
||||
86, // the wasm contained a custom section (id=0)
|
||||
INTERNAL_ERROR = 87, // an internal error described by the log text
|
||||
MEMORY_MISSING = 88, // hook wasm did not contain a memory section
|
||||
// RH NOTE: only HookSet msgs got log codes, possibly all Hook log lines
|
||||
// should get a code?
|
||||
};
|
||||
@@ -447,7 +445,6 @@ getImportWhitelist(Rules const& rules)
|
||||
enum GuardRulesVersion : uint64_t {
|
||||
GuardRuleFix20250131 = 0x00000001,
|
||||
GuardRuleDepth32 = 0x00000002,
|
||||
GuardRuleMemoryMissing = 0x00000004,
|
||||
};
|
||||
|
||||
inline uint64_t
|
||||
@@ -458,8 +455,6 @@ getGuardRulesVersion(Rules const& rules)
|
||||
version |= GuardRuleFix20250131;
|
||||
if (rules.enabled(fixGuardDepth32))
|
||||
version |= GuardRuleDepth32;
|
||||
if (rules.enabled(fixHookMemoryMissing))
|
||||
version |= GuardRuleMemoryMissing;
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
@@ -893,7 +893,6 @@ validateGuards(
|
||||
int last_import_number = -1;
|
||||
int import_count = 0;
|
||||
int last_section_type = 0;
|
||||
bool has_memory_section = false;
|
||||
for (int i = 8, j = 0; i < wasm.size();)
|
||||
{
|
||||
if (j == i)
|
||||
@@ -1182,24 +1181,11 @@ validateGuards(
|
||||
func_type_map[j] = type_idx;
|
||||
}
|
||||
}
|
||||
else if (section_type == 5) // memory section
|
||||
{
|
||||
has_memory_section = true;
|
||||
}
|
||||
|
||||
i = next_section;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((rulesVersion & hook_api::GuardRuleMemoryMissing) &&
|
||||
!has_memory_section)
|
||||
{
|
||||
GUARDLOG(hook::log::MEMORY_MISSING)
|
||||
<< "Malformed transaction. Hook did not contain a memory section."
|
||||
<< "\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
// we must subtract import_count from the hook and cbak function in order to
|
||||
// be able to look them up in the functions section. this is a rule of the
|
||||
// webassembly spec note that at this point in execution we are guarenteed
|
||||
|
||||
@@ -150,32 +150,23 @@
|
||||
WasmEdge_CallingFrameContext const& frameCtx __VA_OPT__( \
|
||||
COMMA __VA_ARGS__))
|
||||
|
||||
#define HOOK_SETUP() \
|
||||
using enum hook_api::hook_return_code; \
|
||||
try \
|
||||
{ \
|
||||
[[maybe_unused]] ApplyContext& applyCtx = hookCtx.applyCtx; \
|
||||
[[maybe_unused]] auto& view = applyCtx.view(); \
|
||||
[[maybe_unused]] auto j = applyCtx.app.journal("View"); \
|
||||
[[maybe_unused]] WasmEdge_MemoryInstanceContext* memoryCtx = \
|
||||
WasmEdge_CallingFrameGetMemoryInstance(&frameCtx, 0); \
|
||||
if (!memoryCtx) \
|
||||
{ \
|
||||
JLOG(j.warn()) << "HookError[" << HC_ACC() \
|
||||
<< "]: wasm memory is unavailable"; \
|
||||
if (view.rules().enabled(fixHookMemoryMissing)) \
|
||||
{ \
|
||||
hookCtx.result.exitType = hook_api::ExitType::WASM_ERROR; \
|
||||
hookCtx.result.exitReason = ""; \
|
||||
return INTERNAL_ERROR; \
|
||||
} \
|
||||
} \
|
||||
[[maybe_unused]] unsigned char* memory = \
|
||||
WasmEdge_MemoryInstanceGetPointer(memoryCtx, 0, 0); \
|
||||
[[maybe_unused]] const uint64_t memory_length = \
|
||||
WasmEdge_MemoryInstanceGetPageSize(memoryCtx) * \
|
||||
WasmEdge_kPageSize; \
|
||||
[[maybe_unused]] auto& api = hookCtx.api();
|
||||
#define HOOK_SETUP() \
|
||||
using enum hook_api::hook_return_code; \
|
||||
try \
|
||||
{ \
|
||||
[[maybe_unused]] ApplyContext& applyCtx = hookCtx.applyCtx; \
|
||||
[[maybe_unused]] auto& view = applyCtx.view(); \
|
||||
[[maybe_unused]] auto j = applyCtx.app.journal("View"); \
|
||||
[[maybe_unused]] WasmEdge_MemoryInstanceContext* memoryCtx = \
|
||||
WasmEdge_CallingFrameGetMemoryInstance(&frameCtx, 0); \
|
||||
[[maybe_unused]] unsigned char* memory = \
|
||||
WasmEdge_MemoryInstanceGetPointer(memoryCtx, 0, 0); \
|
||||
[[maybe_unused]] const uint64_t memory_length = \
|
||||
WasmEdge_MemoryInstanceGetPageSize(memoryCtx) * \
|
||||
WasmEdge_kPageSize; \
|
||||
[[maybe_unused]] auto& api = hookCtx.api(); \
|
||||
if (!memoryCtx || !memory || !memory_length) \
|
||||
return INTERNAL_ERROR;
|
||||
|
||||
#define HOOK_TEARDOWN() \
|
||||
} \
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
// If you add an amendment here, then do not forget to increment `numFeatures`
|
||||
// in include/xrpl/protocol/Feature.h.
|
||||
|
||||
XRPL_FIX (HookMemoryMissing, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (HookMap, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (GuardDepth32, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(NamedHooks, Supported::yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -3081,100 +3081,6 @@ public:
|
||||
ter(temMALFORMED));
|
||||
}
|
||||
|
||||
void
|
||||
testWasmMissingMemory(FeatureBitset features)
|
||||
{
|
||||
testcase("missing memory");
|
||||
using namespace jtx;
|
||||
|
||||
auto const alice = Account{"alice"};
|
||||
auto const bob = Account{"bob"};
|
||||
auto const carol = Account{"carol"};
|
||||
|
||||
TestHook missing_memory_wasm = wasm[R"[test.hook](
|
||||
(module
|
||||
(type $rollback_type
|
||||
(func (param i32 i32 i64) (result i64)))
|
||||
(type $guard_type (func (param i32 i32) (result i32)))
|
||||
(type $hook_type (func (param i32) (result i64)))
|
||||
(import "env" "rollback"
|
||||
(func $rollback (type $rollback_type)))
|
||||
(import "env" "_g" (func $_g (type $guard_type)))
|
||||
(func $hook (type $hook_type) (param i32) (result i64)
|
||||
i32.const 1
|
||||
i32.const 1
|
||||
i64.const 0
|
||||
call $rollback
|
||||
drop
|
||||
i32.const 1
|
||||
i32.const 1
|
||||
call $_g
|
||||
drop
|
||||
i64.const 0)
|
||||
(export "hook" (func $hook)))
|
||||
)[test.hook]"];
|
||||
|
||||
for (auto const& withFix : {false, true})
|
||||
{
|
||||
// test if the Hook is created before the Amendment is enabled
|
||||
Env env{*this, features - fixHookMemoryMissing};
|
||||
env.fund(XRP(10000), alice, bob, carol);
|
||||
|
||||
env(ripple::test::jtx::hook(alice, {{hso(missing_memory_wasm)}}, 0),
|
||||
M("Install missing memory hook"),
|
||||
HSFEE);
|
||||
env.close();
|
||||
|
||||
if (withFix)
|
||||
{
|
||||
env.enableFeature(fixHookMemoryMissing);
|
||||
env.close();
|
||||
}
|
||||
|
||||
env(pay(bob, alice, XRP(1)),
|
||||
M("Test missing memory hook"),
|
||||
fee(XRP(1)),
|
||||
ter(tecHOOK_REJECTED));
|
||||
|
||||
auto meta = env.meta();
|
||||
BEAST_REQUIRE(meta);
|
||||
BEAST_REQUIRE(meta->isFieldPresent(sfHookExecutions));
|
||||
|
||||
auto const& hookExecutions = meta->getFieldArray(sfHookExecutions);
|
||||
BEAST_REQUIRE(hookExecutions.size() == 1);
|
||||
auto const& e = hookExecutions[0];
|
||||
|
||||
auto const expectedExitType = withFix
|
||||
? hook_api::ExitType::WASM_ERROR
|
||||
: hook_api::ExitType::UNSET;
|
||||
BEAST_EXPECT(
|
||||
e.getFieldU8(sfHookResult) ==
|
||||
static_cast<uint8_t>(expectedExitType));
|
||||
BEAST_EXPECT(e.getFieldVL(sfHookReturnString).size() == 0);
|
||||
BEAST_EXPECT(
|
||||
e.getFieldU64(sfHookReturnCode) ==
|
||||
0x8000000000000001 /* INTERNAL_ERROR */);
|
||||
}
|
||||
|
||||
for (auto const& withFix : {false, true})
|
||||
{
|
||||
// test if the Hook is created after the Amendment is enabled
|
||||
auto f = features - fixHookMemoryMissing;
|
||||
if (withFix)
|
||||
f = f | fixHookMemoryMissing;
|
||||
Env env{*this, f};
|
||||
env.fund(XRP(10000), alice, bob, carol);
|
||||
|
||||
auto const expectedTer =
|
||||
withFix ? TER{temMALFORMED} : TER{tesSUCCESS};
|
||||
env(ripple::test::jtx::hook(alice, {{hso(missing_memory_wasm)}}, 0),
|
||||
M("Install missing memory hook"),
|
||||
HSFEE,
|
||||
ter(expectedTer));
|
||||
env.close();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_accept(FeatureBitset features)
|
||||
{
|
||||
@@ -15171,8 +15077,6 @@ public:
|
||||
void
|
||||
testWithFeatures(FeatureBitset features)
|
||||
{
|
||||
testWasmMissingMemory(features);
|
||||
return;
|
||||
testHooksOwnerDir(features);
|
||||
testHooksDisabled(features);
|
||||
testTxStructure(features);
|
||||
@@ -15199,7 +15103,6 @@ public:
|
||||
testFillCopy(features);
|
||||
|
||||
testWasm(features);
|
||||
testWasmMissingMemory(features);
|
||||
test_accept(features);
|
||||
test_rollback(features);
|
||||
|
||||
|
||||
@@ -191,42 +191,6 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
}},
|
||||
|
||||
/* ==== WASM: 1 ==== */
|
||||
{R"[test.hook](
|
||||
(module
|
||||
(type $rollback_type
|
||||
(func (param i32 i32 i64) (result i64)))
|
||||
(type $guard_type (func (param i32 i32) (result i32)))
|
||||
(type $hook_type (func (param i32) (result i64)))
|
||||
(import "env" "rollback"
|
||||
(func $rollback (type $rollback_type)))
|
||||
(import "env" "_g" (func $_g (type $guard_type)))
|
||||
(func $hook (type $hook_type) (param i32) (result i64)
|
||||
i32.const 1
|
||||
i32.const 1
|
||||
i64.const 0
|
||||
call $rollback
|
||||
drop
|
||||
i32.const 1
|
||||
i32.const 1
|
||||
call $_g
|
||||
drop
|
||||
i64.const 0)
|
||||
(export "hook" (func $hook)))
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x13U,
|
||||
0x03U, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x02U,
|
||||
0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U,
|
||||
0x19U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x08U, 0x72U, 0x6FU, 0x6CU,
|
||||
0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU,
|
||||
0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x01U, 0x03U, 0x02U, 0x01U, 0x02U,
|
||||
0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x02U,
|
||||
0x0AU, 0x16U, 0x01U, 0x14U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x42U,
|
||||
0x00U, 0x10U, 0x00U, 0x1AU, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x01U,
|
||||
0x1AU, 0x42U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 2 ==== */
|
||||
{R"[test.hook](
|
||||
(module
|
||||
(type (;0;) (func (param i32 i32) (result i64)))
|
||||
@@ -276,7 +240,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 3 ==== */
|
||||
/* ==== WASM: 2 ==== */
|
||||
{R"[test.hook](
|
||||
(module
|
||||
(type (;0;) (func (param i32 i32) (result i64)))
|
||||
@@ -330,7 +294,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x14U, 0x10U, 0x00U, 0x1AU, 0x0CU, 0x00U, 0x0BU, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 4 ==== */
|
||||
/* ==== WASM: 3 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -397,7 +361,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x80U, 0x80U, 0x00U, 0x20U, 0x02U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 5 ==== */
|
||||
/* ==== WASM: 4 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -503,7 +467,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x03U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 6 ==== */
|
||||
/* ==== WASM: 5 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -578,7 +542,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x05U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 7 ==== */
|
||||
/* ==== WASM: 6 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g(uint32_t, uint32_t);
|
||||
@@ -1195,7 +1159,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x78U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 8 ==== */
|
||||
/* ==== WASM: 7 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g(uint32_t, uint32_t);
|
||||
@@ -1624,7 +1588,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 9 ==== */
|
||||
/* ==== WASM: 8 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -1830,7 +1794,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x3DU, 0x20U, 0x30U, 0x78U, 0x45U, 0x31U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 10 ==== */
|
||||
/* ==== WASM: 9 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -1952,7 +1916,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x58U, 0x4EU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 11 ==== */
|
||||
/* ==== WASM: 10 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -2085,7 +2049,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x4FU, 0x4EU, 0x43U, 0x45U, 0x53U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 12 ==== */
|
||||
/* ==== WASM: 11 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -2165,7 +2129,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x54U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 13 ==== */
|
||||
/* ==== WASM: 12 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -2210,7 +2174,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 14 ==== */
|
||||
/* ==== WASM: 13 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -2529,7 +2493,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x80U, 0x80U, 0x80U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 15 ==== */
|
||||
/* ==== WASM: 14 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -3315,7 +3279,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x37U, 0x36U, 0x33U, 0x4CU, 0x4CU, 0x20U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 16 ==== */
|
||||
/* ==== WASM: 15 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -3705,7 +3669,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x80U, 0x80U, 0x80U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 17 ==== */
|
||||
/* ==== WASM: 16 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -3886,7 +3850,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x38U, 0x4CU, 0x4CU, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 18 ==== */
|
||||
/* ==== WASM: 17 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -4075,7 +4039,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 19 ==== */
|
||||
/* ==== WASM: 18 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -4314,7 +4278,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U, 0x42U, 0x00U, 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 20 ==== */
|
||||
/* ==== WASM: 19 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -5016,7 +4980,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x38U, 0x35U, 0x35U, 0x32U, 0x55U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 21 ==== */
|
||||
/* ==== WASM: 20 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -6361,7 +6325,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 22 ==== */
|
||||
/* ==== WASM: 21 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -6463,7 +6427,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 23 ==== */
|
||||
/* ==== WASM: 22 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -6506,7 +6470,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 24 ==== */
|
||||
/* ==== WASM: 23 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -6654,7 +6618,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x34U, 0x34U, 0x4CU, 0x4CU, 0x2CU, 0x20U, 0x33U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 25 ==== */
|
||||
/* ==== WASM: 24 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -6982,7 +6946,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x38U, 0x34U, 0x39U, 0x30U, 0x4CU, 0x4CU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 26 ==== */
|
||||
/* ==== WASM: 25 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -7187,7 +7151,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x10U, 0x85U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 27 ==== */
|
||||
/* ==== WASM: 26 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -7871,7 +7835,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 28 ==== */
|
||||
/* ==== WASM: 27 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -8166,7 +8130,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x32U, 0x34U, 0x31U, 0x36U, 0x55U, 0x4CU, 0x4CU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 29 ==== */
|
||||
/* ==== WASM: 28 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -8879,7 +8843,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x31U, 0x33U, 0x33U, 0x38U, 0x20U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 30 ==== */
|
||||
/* ==== WASM: 29 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -8964,7 +8928,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 31 ==== */
|
||||
/* ==== WASM: 30 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9026,7 +8990,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x80U, 0x80U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 32 ==== */
|
||||
/* ==== WASM: 31 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9103,7 +9067,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 33 ==== */
|
||||
/* ==== WASM: 32 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9180,7 +9144,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 34 ==== */
|
||||
/* ==== WASM: 33 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9437,7 +9401,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 35 ==== */
|
||||
/* ==== WASM: 34 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9595,7 +9559,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x04U, 0x00U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 36 ==== */
|
||||
/* ==== WASM: 35 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9948,7 +9912,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U, 0x2AU, 0x04U, 0x00U, 0x00U, 0x31U, 0x04U, 0x00U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 37 ==== */
|
||||
/* ==== WASM: 36 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -9981,7 +9945,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 38 ==== */
|
||||
/* ==== WASM: 37 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10208,7 +10172,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 39 ==== */
|
||||
/* ==== WASM: 38 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10239,7 +10203,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 40 ==== */
|
||||
/* ==== WASM: 39 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10550,7 +10514,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 41 ==== */
|
||||
/* ==== WASM: 40 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10627,7 +10591,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 42 ==== */
|
||||
/* ==== WASM: 41 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10661,7 +10625,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 43 ==== */
|
||||
/* ==== WASM: 42 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10748,7 +10712,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 44 ==== */
|
||||
/* ==== WASM: 43 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10782,7 +10746,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 45 ==== */
|
||||
/* ==== WASM: 44 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -10922,7 +10886,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x54U, 0x5FU, 0x4DU, 0x45U, 0x54U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 46 ==== */
|
||||
/* ==== WASM: 45 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -11112,7 +11076,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x31U, 0x34U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 47 ==== */
|
||||
/* ==== WASM: 46 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -11266,7 +11230,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 48 ==== */
|
||||
/* ==== WASM: 47 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -11427,7 +11391,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 49 ==== */
|
||||
/* ==== WASM: 48 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -11584,7 +11548,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 50 ==== */
|
||||
/* ==== WASM: 49 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -11669,7 +11633,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x74U, 0x79U, 0x70U, 0x65U, 0x28U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 51 ==== */
|
||||
/* ==== WASM: 50 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -11926,7 +11890,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 52 ==== */
|
||||
/* ==== WASM: 51 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -12164,7 +12128,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x3EU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 53 ==== */
|
||||
/* ==== WASM: 52 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -12260,7 +12224,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x53U, 0x54U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 54 ==== */
|
||||
/* ==== WASM: 53 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -12370,7 +12334,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x31U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 55 ==== */
|
||||
/* ==== WASM: 54 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -12500,7 +12464,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x30U, 0x30U, 0x30U, 0x4CU, 0x4CU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 56 ==== */
|
||||
/* ==== WASM: 55 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -12774,7 +12738,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 57 ==== */
|
||||
/* ==== WASM: 56 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -12911,7 +12875,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x2CU, 0x20U, 0x73U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x31U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 58 ==== */
|
||||
/* ==== WASM: 57 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -13205,7 +13169,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x5FU, 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 59 ==== */
|
||||
/* ==== WASM: 58 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -13439,7 +13403,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x5FU, 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 60 ==== */
|
||||
/* ==== WASM: 59 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -13735,7 +13699,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x2CU, 0x20U, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 61 ==== */
|
||||
/* ==== WASM: 60 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -13939,7 +13903,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x6EU, 0x74U, 0x32U, 0x22U, 0x20U, 0x2BU, 0x20U, 0x69U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 62 ==== */
|
||||
/* ==== WASM: 61 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -14056,7 +14020,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x69U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 63 ==== */
|
||||
/* ==== WASM: 62 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -14165,7 +14129,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x6EU, 0x74U, 0x65U, 0x6EU, 0x74U, 0x32U, 0x22U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 64 ==== */
|
||||
/* ==== WASM: 63 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -14438,7 +14402,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 65 ==== */
|
||||
/* ==== WASM: 64 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
#define sfInvoiceID ((5U << 16U) + 17U)
|
||||
@@ -14657,7 +14621,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 66 ==== */
|
||||
/* ==== WASM: 65 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -14769,7 +14733,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x58U, 0x49U, 0x53U, 0x54U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 67 ==== */
|
||||
/* ==== WASM: 66 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
#define sfInvoiceID ((5U << 16U) + 17U)
|
||||
@@ -14905,7 +14869,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x3DU, 0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 68 ==== */
|
||||
/* ==== WASM: 67 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15041,7 +15005,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x49U, 0x47U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 69 ==== */
|
||||
/* ==== WASM: 68 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15180,7 +15144,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x66U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x32U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 70 ==== */
|
||||
/* ==== WASM: 69 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15292,7 +15256,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 71 ==== */
|
||||
/* ==== WASM: 70 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15386,7 +15350,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x61U, 0x64U, 0x5BU, 0x69U, 0x5DU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 72 ==== */
|
||||
/* ==== WASM: 71 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15519,7 +15483,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x64U, 0x5BU, 0x69U, 0x5DU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 73 ==== */
|
||||
/* ==== WASM: 72 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15607,7 +15571,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x61U, 0x74U, 0x61U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 74 ==== */
|
||||
/* ==== WASM: 73 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
#define sfInvoiceID ((5U << 16U) + 17U)
|
||||
@@ -15718,7 +15682,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x33U, 0x32U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 75 ==== */
|
||||
/* ==== WASM: 74 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -15929,7 +15893,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 76 ==== */
|
||||
/* ==== WASM: 75 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -16037,7 +16001,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x22U, 0x32U, 0x22U, 0x2CU, 0x20U, 0x31U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 77 ==== */
|
||||
/* ==== WASM: 76 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -16649,7 +16613,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 78 ==== */
|
||||
/* ==== WASM: 77 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -16836,7 +16800,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x63U, 0x65U, 0x29U, 0x20U, 0x3EU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 79 ==== */
|
||||
/* ==== WASM: 78 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17186,7 +17150,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 80 ==== */
|
||||
/* ==== WASM: 79 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17322,7 +17286,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 81 ==== */
|
||||
/* ==== WASM: 80 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17381,7 +17345,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x64U, 0xE1U, 0xF1U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 82 ==== */
|
||||
/* ==== WASM: 81 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17554,7 +17518,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x54U, 0x5FU, 0x45U, 0x58U, 0x49U, 0x53U, 0x54U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 83 ==== */
|
||||
/* ==== WASM: 82 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17702,7 +17666,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x30U, 0x00U, 0x22U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 84 ==== */
|
||||
/* ==== WASM: 83 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17856,7 +17820,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x0FU, 0x0BU, 0x02U, 0x56U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 85 ==== */
|
||||
/* ==== WASM: 84 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -17953,7 +17917,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x3DU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 86 ==== */
|
||||
/* ==== WASM: 85 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -18012,7 +17976,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 87 ==== */
|
||||
/* ==== WASM: 86 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -18071,7 +18035,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x4EU, 0x44U, 0x53U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 88 ==== */
|
||||
/* ==== WASM: 87 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -19900,7 +19864,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 89 ==== */
|
||||
/* ==== WASM: 88 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -21519,7 +21483,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x29U, 0x29U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 90 ==== */
|
||||
/* ==== WASM: 89 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -24452,7 +24416,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 91 ==== */
|
||||
/* ==== WASM: 90 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -26417,7 +26381,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x54U, 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 92 ==== */
|
||||
/* ==== WASM: 91 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -26702,7 +26666,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 93 ==== */
|
||||
/* ==== WASM: 92 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g(uint32_t, uint32_t);
|
||||
@@ -27289,7 +27253,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x4EU, 0x5FU, 0x46U, 0x41U, 0x49U, 0x4CU, 0x55U, 0x52U, 0x45U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 94 ==== */
|
||||
/* ==== WASM: 93 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -27318,7 +27282,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 95 ==== */
|
||||
/* ==== WASM: 94 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -27350,7 +27314,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x20U, 0x52U, 0x65U, 0x6AU, 0x65U, 0x63U, 0x74U, 0x65U, 0x64U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 96 ==== */
|
||||
/* ==== WASM: 95 ==== */
|
||||
{R"[test.hook](
|
||||
(module
|
||||
(type (;0;) (func (param i32 i32 i64) (result i64)))
|
||||
@@ -27377,7 +27341,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, 0x00U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 97 ==== */
|
||||
/* ==== WASM: 96 ==== */
|
||||
{R"[test.hook](
|
||||
(module
|
||||
(type (;0;) (func (param i32 i32) (result i32)))
|
||||
@@ -27430,7 +27394,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x00U, 0x1AU, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 98 ==== */
|
||||
/* ==== WASM: 97 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -34073,7 +34037,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x39U, 0x30U, 0x31U, 0x32U, 0x33U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 99 ==== */
|
||||
/* ==== WASM: 98 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -34119,7 +34083,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x0BU, 0x06U, 0x76U, 0x61U, 0x6CU, 0x75U, 0x65U, 0x00U,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 100 ==== */
|
||||
/* ==== WASM: 99 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g (uint32_t id, uint32_t maxiter);
|
||||
@@ -34148,7 +34112,7 @@ std::map<std::string, std::vector<uint8_t>> wasm = {
|
||||
0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 101 ==== */
|
||||
/* ==== WASM: 100 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code);
|
||||
|
||||
1187
src/test/net/HTTPClient_test.cpp
Normal file
1187
src/test/net/HTTPClient_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
351
src/test/net/RPCSub_test.cpp
Normal file
351
src/test/net/RPCSub_test.cpp
Normal file
@@ -0,0 +1,351 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2024 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <test/jtx.h>
|
||||
#include <xrpld/core/Job.h>
|
||||
#include <xrpld/core/JobQueue.h>
|
||||
#include <xrpld/net/RPCSub.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
// Minimal HTTP endpoint that counts received webhook POSTs and replies
|
||||
// with a configurable status. Responses are EOF-delimited (no
|
||||
// Content-Length) and the socket is closed right after writing — the
|
||||
// exact shape that triggered the original handleData EOF-completion
|
||||
// leak. So these tests exercise RPCSub flow control AND the HTTPClient
|
||||
// EOF fix end to end: if either regressed, delivery would stall and the
|
||||
// expected count would never be reached within the timeout.
|
||||
class MockWebhookEndpoint
|
||||
{
|
||||
boost::asio::io_service ios_;
|
||||
std::unique_ptr<boost::asio::io_service::work> work_;
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
std::thread thread_;
|
||||
unsigned short port_;
|
||||
|
||||
std::atomic<int> received_{0};
|
||||
std::atomic<int> status_{200};
|
||||
std::atomic<int> delayMs_{0};
|
||||
|
||||
public:
|
||||
MockWebhookEndpoint()
|
||||
: work_(std::make_unique<boost::asio::io_service::work>(ios_))
|
||||
, acceptor_(
|
||||
ios_,
|
||||
boost::asio::ip::tcp::endpoint(
|
||||
boost::asio::ip::address::from_string("127.0.0.1"),
|
||||
0))
|
||||
{
|
||||
port_ = acceptor_.local_endpoint().port();
|
||||
accept();
|
||||
thread_ = std::thread([this] { ios_.run(); });
|
||||
}
|
||||
|
||||
~MockWebhookEndpoint()
|
||||
{
|
||||
work_.reset();
|
||||
boost::system::error_code ec;
|
||||
acceptor_.close(ec);
|
||||
ios_.stop();
|
||||
if (thread_.joinable())
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
unsigned short
|
||||
port() const
|
||||
{
|
||||
return port_;
|
||||
}
|
||||
|
||||
int
|
||||
received() const
|
||||
{
|
||||
return received_;
|
||||
}
|
||||
|
||||
void
|
||||
setStatus(int s)
|
||||
{
|
||||
status_ = s;
|
||||
}
|
||||
|
||||
// Delay each reply so delivery is deterministically slower than the
|
||||
// microsecond-fast enqueue loop — keeps the deque full for the
|
||||
// queue-cap drop test regardless of scheduling.
|
||||
void
|
||||
setResponseDelay(int ms)
|
||||
{
|
||||
delayMs_ = ms;
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
accept()
|
||||
{
|
||||
auto sock = std::make_shared<boost::asio::ip::tcp::socket>(ios_);
|
||||
acceptor_.async_accept(*sock, [this, sock](auto ec) {
|
||||
if (ec)
|
||||
return;
|
||||
handle(sock);
|
||||
accept();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
handle(std::shared_ptr<boost::asio::ip::tcp::socket> sock)
|
||||
{
|
||||
auto buf = std::make_shared<boost::asio::streambuf>();
|
||||
boost::asio::async_read_until(
|
||||
*sock, *buf, "\r\n\r\n", [this, sock, buf](auto ec, std::size_t) {
|
||||
if (ec)
|
||||
return;
|
||||
|
||||
++received_;
|
||||
|
||||
auto const delay = delayMs_.load();
|
||||
if (delay > 0)
|
||||
{
|
||||
auto timer =
|
||||
std::make_shared<boost::asio::steady_timer>(ios_);
|
||||
timer->expires_from_now(std::chrono::milliseconds(delay));
|
||||
timer->async_wait(
|
||||
[this, sock, timer](auto) { reply(sock); });
|
||||
}
|
||||
else
|
||||
{
|
||||
reply(sock);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
reply(std::shared_ptr<boost::asio::ip::tcp::socket> sock)
|
||||
{
|
||||
// EOF-delimited reply: no Content-Length, close after writing.
|
||||
// This is the realistic failing-webhook shape.
|
||||
auto resp = std::make_shared<std::string>(
|
||||
"HTTP/1.0 " + std::to_string(status_.load()) +
|
||||
" Reply\r\n\r\n{\"result\":{}}");
|
||||
boost::asio::async_write(
|
||||
*sock, boost::asio::buffer(*resp), [sock, resp](auto, std::size_t) {
|
||||
boost::system::error_code ig;
|
||||
sock->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ig);
|
||||
sock->close(ig);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class RPCSub_test : public beast::unit_test::suite
|
||||
{
|
||||
// Generous ceiling: the instrumented Debug (coverage) build is much
|
||||
// slower than Release, so timeouts are sized for that, not Release.
|
||||
template <class Cond>
|
||||
bool
|
||||
waitFor(Cond cond, std::chrono::seconds timeout = std::chrono::seconds{30})
|
||||
{
|
||||
auto const deadline = std::chrono::steady_clock::now() + timeout;
|
||||
while (!cond() && std::chrono::steady_clock::now() < deadline)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
return cond();
|
||||
}
|
||||
|
||||
std::shared_ptr<RPCSub>
|
||||
makeSub(
|
||||
jtx::Env& env,
|
||||
MockWebhookEndpoint& ep,
|
||||
std::size_t maxQueueSize = 16384)
|
||||
{
|
||||
return make_RPCSub(
|
||||
env.app().getOPs(),
|
||||
env.app().getJobQueue(),
|
||||
"http://127.0.0.1:" + std::to_string(ep.port()) + "/",
|
||||
"",
|
||||
"",
|
||||
env.app().logs(),
|
||||
maxQueueSize);
|
||||
}
|
||||
|
||||
// True once no RPCSub sending job is queued or running. sendThread
|
||||
// captures a raw `this`, so the RPCSub must not be destroyed while a
|
||||
// job is still in flight — wait on this before letting the sub die.
|
||||
bool
|
||||
sendingIdle(jtx::Env& env)
|
||||
{
|
||||
return env.app().getJobQueue().getJobCountTotal(jtCLIENT_SUBSCRIBE) ==
|
||||
0;
|
||||
}
|
||||
|
||||
// Wait for all events to reach the endpoint AND the sending job to
|
||||
// finish, so the sub can be torn down without racing sendThread.
|
||||
void
|
||||
drainAndSettle(jtx::Env& env, MockWebhookEndpoint& ep, int expected)
|
||||
{
|
||||
bool const delivered =
|
||||
waitFor([&] { return ep.received() >= expected; });
|
||||
bool const idle = waitFor([&] { return sendingIdle(env); });
|
||||
log << " drainAndSettle: received=" << ep.received() << "/" << expected
|
||||
<< " idle=" << idle << std::endl;
|
||||
BEAST_EXPECT(delivered);
|
||||
BEAST_EXPECT(idle);
|
||||
}
|
||||
|
||||
void
|
||||
send(std::shared_ptr<RPCSub> const& sub, int n)
|
||||
{
|
||||
Json::Value ev(Json::objectValue);
|
||||
ev["n"] = n;
|
||||
sub->send(ev, false);
|
||||
}
|
||||
|
||||
void
|
||||
testDelivery()
|
||||
{
|
||||
testcase("Webhook events are delivered");
|
||||
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
MockWebhookEndpoint ep;
|
||||
|
||||
static constexpr int N = 10;
|
||||
{
|
||||
auto sub = makeSub(env, ep);
|
||||
for (int i = 0; i < N; ++i)
|
||||
send(sub, i);
|
||||
drainAndSettle(env, ep, N);
|
||||
}
|
||||
|
||||
BEAST_EXPECT(ep.received() == N);
|
||||
}
|
||||
|
||||
void
|
||||
testErrorsDoNotStall()
|
||||
{
|
||||
testcase("Delivery continues when endpoint returns HTTP 500");
|
||||
|
||||
// The original bug (xrpld #6341): an endpoint returning errors
|
||||
// without Content-Length never completed, stalling delivery to
|
||||
// ALL subscribers. Here every response is a 500 with no
|
||||
// Content-Length (EOF-delimited) — all N must still arrive.
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
MockWebhookEndpoint ep;
|
||||
ep.setStatus(500);
|
||||
|
||||
static constexpr int N = 10;
|
||||
{
|
||||
auto sub = makeSub(env, ep);
|
||||
for (int i = 0; i < N; ++i)
|
||||
send(sub, i);
|
||||
drainAndSettle(env, ep, N);
|
||||
}
|
||||
|
||||
BEAST_EXPECT(ep.received() == N);
|
||||
}
|
||||
|
||||
void
|
||||
testRestartAfterDrain()
|
||||
{
|
||||
testcase("Sending restarts after the queue drains");
|
||||
|
||||
// After a batch drains, sendThread clears mSending and returns.
|
||||
// A later send() must start a fresh sending job; if mSending were
|
||||
// left set (the #6341 failure mode) the second burst would never
|
||||
// be delivered.
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
MockWebhookEndpoint ep;
|
||||
|
||||
{
|
||||
auto sub = makeSub(env, ep);
|
||||
|
||||
// First burst, then wait for the sending job to fully drain
|
||||
// and exit (mSending cleared) — deterministically, not via a
|
||||
// sleep.
|
||||
for (int i = 0; i < 5; ++i)
|
||||
send(sub, i);
|
||||
drainAndSettle(env, ep, 5);
|
||||
|
||||
// Second burst must start a fresh sending job.
|
||||
for (int i = 5; i < 10; ++i)
|
||||
send(sub, i);
|
||||
drainAndSettle(env, ep, 10);
|
||||
}
|
||||
|
||||
BEAST_EXPECT(ep.received() == 10);
|
||||
}
|
||||
|
||||
void
|
||||
testQueueCapDrops()
|
||||
{
|
||||
testcase("Events past the queue cap are dropped");
|
||||
|
||||
// With a tiny cap, pushing far more events than delivery can keep
|
||||
// up with forces send() down the drop path: enqueue is microsecond
|
||||
// -fast while each (delayed) HTTP delivery is a full round-trip, so
|
||||
// the deque sits at the cap and excess events are dropped. The
|
||||
// delay makes "delivery slower than enqueue" hold regardless of
|
||||
// scheduling, so this isn't timing-dependent. We just need some
|
||||
// delivered (cap works) and some dropped (drop path exercised).
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
MockWebhookEndpoint ep;
|
||||
ep.setResponseDelay(50);
|
||||
|
||||
static constexpr int pushed = 50;
|
||||
{
|
||||
auto sub = makeSub(env, ep, /*maxQueueSize*/ 2);
|
||||
for (int i = 0; i < pushed; ++i)
|
||||
send(sub, i);
|
||||
BEAST_EXPECT(waitFor([&] { return sendingIdle(env); }));
|
||||
}
|
||||
|
||||
log << " queue cap: received " << ep.received() << "/" << pushed
|
||||
<< std::endl;
|
||||
BEAST_EXPECT(ep.received() > 0);
|
||||
BEAST_EXPECT(ep.received() < pushed);
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testDelivery();
|
||||
testErrorsDoNotStall();
|
||||
testRestartAfterDrain();
|
||||
testQueueCapDrops();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(RPCSub, net, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <xrpld/core/JobQueue.h>
|
||||
#include <xrpld/net/InfoSub.h>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -39,16 +38,17 @@ protected:
|
||||
explicit RPCSub(InfoSub::Source& source);
|
||||
};
|
||||
|
||||
// VFALCO Why is the io_service needed?
|
||||
std::shared_ptr<RPCSub>
|
||||
make_RPCSub(
|
||||
InfoSub::Source& source,
|
||||
boost::asio::io_service& io_service,
|
||||
JobQueue& jobQueue,
|
||||
std::string const& strUrl,
|
||||
std::string const& strUsername,
|
||||
std::string const& strPassword,
|
||||
Logs& logs);
|
||||
Logs& logs,
|
||||
// Max events buffered before new ones are dropped. Configurable so
|
||||
// tests can exercise the drop path without queueing the full default.
|
||||
std::size_t maxQueueSize = 16384);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
|
||||
@@ -122,12 +122,20 @@ public:
|
||||
mComplete = complete;
|
||||
mTimeout = timeout;
|
||||
|
||||
// Bind a non-owning `this` (not shared_from_this()) into mBuild.
|
||||
// mBuild is a member, so capturing a shared_ptr to self here would
|
||||
// form a reference cycle (this -> mBuild -> shared_ptr<this>) that
|
||||
// never breaks, leaking the object and its socket FD after the
|
||||
// request completes. mBuild is only ever invoked from
|
||||
// handleRequest(), which always runs inside an async handler that
|
||||
// already holds a shared_from_this(), so the object is guaranteed
|
||||
// alive whenever mBuild fires — a raw `this` is safe.
|
||||
request(
|
||||
bSSL,
|
||||
deqSites,
|
||||
std::bind(
|
||||
&HTTPClientImp::makeGet,
|
||||
shared_from_this(),
|
||||
this,
|
||||
strPath,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2),
|
||||
@@ -393,8 +401,12 @@ public:
|
||||
if (boost::regex_match(strHeader, smMatch, reBody)) // we got some body
|
||||
mBody = smMatch[1];
|
||||
|
||||
bool const hasContentLength =
|
||||
boost::regex_match(strHeader, smMatch, reSize);
|
||||
mReceivedContentLength = hasContentLength;
|
||||
|
||||
std::size_t const responseSize = [&] {
|
||||
if (boost::regex_match(strHeader, smMatch, reSize))
|
||||
if (hasContentLength)
|
||||
return beast::lexicalCast<std::size_t>(
|
||||
std::string(smMatch[1]), maxResponseSize_);
|
||||
return maxResponseSize_;
|
||||
@@ -445,22 +457,24 @@ public:
|
||||
JLOG(j_.trace()) << "Read error: " << mShutdown.message();
|
||||
|
||||
invokeComplete(mShutdown);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mShutdown)
|
||||
{
|
||||
JLOG(j_.trace()) << "Complete.";
|
||||
}
|
||||
else
|
||||
{
|
||||
mResponse.commit(bytes_transferred);
|
||||
std::string strBody{
|
||||
{std::istreambuf_iterator<char>(&mResponse)},
|
||||
std::istreambuf_iterator<char>()};
|
||||
invokeComplete(ecResult, mStatus, mBody + strBody);
|
||||
}
|
||||
}
|
||||
|
||||
// Either the read completed normally or it ended at EOF. EOF is a
|
||||
// successful completion for EOF-delimited responses, but it is an
|
||||
// error when the server promised a Content-Length and closed early.
|
||||
JLOG(j_.trace()) << "Complete.";
|
||||
|
||||
mResponse.commit(bytes_transferred);
|
||||
std::string strBody{
|
||||
{std::istreambuf_iterator<char>(&mResponse)},
|
||||
std::istreambuf_iterator<char>()};
|
||||
|
||||
auto completeEc = ecResult;
|
||||
if (completeEc == boost::asio::error::eof && !mReceivedContentLength)
|
||||
completeEc.clear();
|
||||
|
||||
invokeComplete(completeEc, mStatus, mBody + strBody);
|
||||
}
|
||||
|
||||
// Call cancel the deadline timer and invoke the completion routine.
|
||||
@@ -516,6 +530,7 @@ private:
|
||||
boost::asio::streambuf mHeader;
|
||||
boost::asio::streambuf mResponse;
|
||||
std::string mBody;
|
||||
bool mReceivedContentLength = false;
|
||||
const unsigned short mPort;
|
||||
std::size_t const maxResponseSize_;
|
||||
int mStatus;
|
||||
|
||||
@@ -1585,6 +1585,10 @@ struct RPCCallImp
|
||||
// callbackFuncP.
|
||||
|
||||
// Receive reply
|
||||
if (ecResult)
|
||||
Throw<std::runtime_error>(
|
||||
"RPC transport error: " + ecResult.message());
|
||||
|
||||
if (strData.empty())
|
||||
Throw<std::runtime_error>(
|
||||
"no response from server. Please "
|
||||
@@ -1748,6 +1752,7 @@ rpcClient(
|
||||
}
|
||||
|
||||
{
|
||||
//@@start blocking-request
|
||||
boost::asio::io_service isService;
|
||||
RPCCall::fromNetwork(
|
||||
isService,
|
||||
@@ -1771,6 +1776,7 @@ rpcClient(
|
||||
headers);
|
||||
isService.run(); // This blocks until there are no more
|
||||
// outstanding async calls.
|
||||
//@@end blocking-request
|
||||
}
|
||||
if (jvOutput.isMember("result"))
|
||||
{
|
||||
@@ -1881,15 +1887,21 @@ fromNetwork(
|
||||
|
||||
// Send request
|
||||
|
||||
// Number of bytes to try to receive if no
|
||||
// Content-Length header received
|
||||
constexpr auto RPC_REPLY_MAX_BYTES = megabytes(256);
|
||||
// Number of bytes to try to receive if no Content-Length header is
|
||||
// received. Webhook event deliveries ("event") ignore the response
|
||||
// body, so a missing Content-Length must not pre-allocate the full
|
||||
// 256MB RPC reply budget per in-flight delivery (maxInFlight can be
|
||||
// 32 -> 8GB). Cap those small; genuine RPC replies (CLI) keep the
|
||||
// large budget.
|
||||
auto const RPC_REPLY_MAX_BYTES =
|
||||
(strMethod == "event") ? megabytes(1) : megabytes(256);
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
// auto constexpr RPC_NOTIFY = 10min; // Wietse: lolwut 10 minutes for one
|
||||
// HTTP call?
|
||||
auto constexpr RPC_NOTIFY = 30s;
|
||||
|
||||
//@@start async-request
|
||||
HTTPClient::request(
|
||||
bSSL,
|
||||
io_service,
|
||||
@@ -1914,6 +1926,7 @@ fromNetwork(
|
||||
std::placeholders::_3,
|
||||
j),
|
||||
j);
|
||||
//@@end async-request
|
||||
}
|
||||
|
||||
} // namespace RPCCall
|
||||
|
||||
@@ -24,29 +24,30 @@
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// Subscription object for JSON-RPC
|
||||
class RPCSubImp : public RPCSub
|
||||
class RPCSubImp : public RPCSub, public std::enable_shared_from_this<RPCSubImp>
|
||||
{
|
||||
public:
|
||||
RPCSubImp(
|
||||
InfoSub::Source& source,
|
||||
boost::asio::io_service& io_service,
|
||||
JobQueue& jobQueue,
|
||||
std::string const& strUrl,
|
||||
std::string const& strUsername,
|
||||
std::string const& strPassword,
|
||||
Logs& logs)
|
||||
Logs& logs,
|
||||
std::size_t maxQueueSize)
|
||||
: RPCSub(source)
|
||||
, m_io_service(io_service)
|
||||
, m_jobQueue(jobQueue)
|
||||
, mUrl(strUrl)
|
||||
, mSSL(false)
|
||||
, mUsername(strUsername)
|
||||
, mPassword(strPassword)
|
||||
, mSending(false)
|
||||
, maxQueueSize_(maxQueueSize)
|
||||
, j_(logs.journal("RPCSub"))
|
||||
, logs_(logs)
|
||||
{
|
||||
@@ -78,14 +79,26 @@ public:
|
||||
{
|
||||
std::lock_guard sl(mLock);
|
||||
|
||||
// Wietse: we're not going to limit this, this is admin-port only, scale
|
||||
// accordingly Dropping events just like this results in inconsistent
|
||||
// data on the receiving end if (mDeque.size() >= eventQueueMax)
|
||||
// {
|
||||
// // Drop the previous event.
|
||||
// JLOG(j_.warn()) << "RPCCall::fromNetwork drop";
|
||||
// mDeque.pop_back();
|
||||
// }
|
||||
if (mDeque.size() >= maxQueueSize_)
|
||||
{
|
||||
// Always advance mSeq so consumers can detect the gap, but
|
||||
// rate-limit the log: a hopelessly behind endpoint drops on
|
||||
// every send() and would otherwise flood the log. Warn on
|
||||
// the first drop of a run and then once per dropLogInterval.
|
||||
if (mDropped++ % dropLogInterval == 0)
|
||||
{
|
||||
JLOG(j_.warn())
|
||||
<< "RPCCall::fromNetwork drop: queue full ("
|
||||
<< mDeque.size() << "), seq=" << mSeq
|
||||
<< ", endpoint=" << mIp << ", dropped=" << mDropped;
|
||||
}
|
||||
++mSeq;
|
||||
return;
|
||||
}
|
||||
|
||||
// Endpoint caught up enough to accept again; reset so the next
|
||||
// overflow burst logs its first drop immediately.
|
||||
mDropped = 0;
|
||||
|
||||
auto jm = broadcast ? j_.debug() : j_.info();
|
||||
JLOG(jm) << "RPCCall::fromNetwork push: " << jvObj;
|
||||
@@ -97,10 +110,7 @@ public:
|
||||
// Start a sending thread.
|
||||
JLOG(j_.info()) << "RPCCall::fromNetwork start";
|
||||
|
||||
mSending = m_jobQueue.addJob(
|
||||
jtCLIENT_SUBSCRIBE, "RPCSub::sendThread", [this]() {
|
||||
sendThread();
|
||||
});
|
||||
startSendingJob();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,48 +131,66 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
// XXX Could probably create a bunch of send jobs in a single get of the
|
||||
// lock.
|
||||
// Maximum concurrent HTTP deliveries per batch. Bounds file
|
||||
// descriptor usage while still allowing parallel delivery to
|
||||
// capable endpoints. With a 1024 FD process limit shared across
|
||||
// peers, clients, and the node store, 32 per subscriber is a
|
||||
// meaningful but survivable chunk even with multiple subscribers.
|
||||
static constexpr int maxInFlight = 32;
|
||||
|
||||
// Log one drop warning per this many drops while the queue stays
|
||||
// full, to avoid flooding the log on a persistently behind endpoint.
|
||||
static constexpr std::size_t dropLogInterval = 1000;
|
||||
|
||||
// Schedule a sending job. Must be called under mLock. The job holds a
|
||||
// weak_ptr and re-locks it on entry, so the RPCSub is kept alive for
|
||||
// the duration of the batch even if it is unsubscribed (and would
|
||||
// otherwise be destroyed) concurrently — sendThread dereferences this
|
||||
// only via that strong ref. mDeque events are delivered until the sub
|
||||
// is gone, after which weak.lock() fails and the job is a no-op.
|
||||
void
|
||||
startSendingJob()
|
||||
{
|
||||
std::weak_ptr<RPCSubImp> weak = weak_from_this();
|
||||
mSending = m_jobQueue.addJob(
|
||||
jtCLIENT_SUBSCRIBE, "RPCSub::sendThread", [weak]() {
|
||||
if (auto self = weak.lock())
|
||||
self->sendThread();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
sendThread()
|
||||
{
|
||||
Json::Value jvEvent;
|
||||
bool bSend;
|
||||
// Process exactly ONE batch per job, then re-queue if more events
|
||||
// remain, rather than draining the whole backlog in a single job.
|
||||
// A local io_service's .run() blocks this worker thread for the
|
||||
// batch (up to the per-request timeout), so re-queueing between
|
||||
// batches keeps one slow/hung subscriber from monopolising a
|
||||
// job-queue worker and starving consensus/ledger/RPC work.
|
||||
//
|
||||
// mSending must be cleared under the lock on every non-requeue
|
||||
// exit path; if it ever stays set without a job in flight, send()
|
||||
// sees mSending == true and never restarts us, stalling the queue
|
||||
// forever — the original bug (xrpld issue #6341).
|
||||
boost::asio::io_service io_service;
|
||||
int dispatched = 0;
|
||||
|
||||
do
|
||||
try
|
||||
{
|
||||
{
|
||||
// Obtain the lock to manipulate the queue and change sending.
|
||||
std::lock_guard sl(mLock);
|
||||
|
||||
if (mDeque.empty())
|
||||
{
|
||||
mSending = false;
|
||||
bSend = false;
|
||||
}
|
||||
else
|
||||
while (!mDeque.empty() && dispatched < maxInFlight)
|
||||
{
|
||||
auto const [seq, env] = mDeque.front();
|
||||
|
||||
mDeque.pop_front();
|
||||
|
||||
jvEvent = env;
|
||||
Json::Value jvEvent = env;
|
||||
jvEvent["seq"] = seq;
|
||||
|
||||
bSend = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Send outside of the lock.
|
||||
if (bSend)
|
||||
{
|
||||
// XXX Might not need this in a try.
|
||||
try
|
||||
{
|
||||
JLOG(j_.info()) << "RPCCall::fromNetwork: " << mIp;
|
||||
|
||||
RPCCall::fromNetwork(
|
||||
m_io_service,
|
||||
io_service,
|
||||
mIp,
|
||||
mPort,
|
||||
mUsername,
|
||||
@@ -173,21 +201,51 @@ private:
|
||||
mSSL,
|
||||
true,
|
||||
logs_);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
JLOG(j_.info())
|
||||
<< "RPCCall::fromNetwork exception: " << e.what();
|
||||
++dispatched;
|
||||
}
|
||||
}
|
||||
} while (bSend);
|
||||
|
||||
// dispatched is always > 0 here (send() only starts a job
|
||||
// after enqueuing, and the re-queue below only fires with a
|
||||
// non-empty deque), but guard anyway so an empty batch can't
|
||||
// log/spin — it falls straight through to clear mSending.
|
||||
if (dispatched > 0)
|
||||
{
|
||||
JLOG(j_.info()) << "RPCCall::fromNetwork: " << mIp
|
||||
<< " dispatching " << dispatched << " events";
|
||||
|
||||
io_service.run();
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
// Bail rather than re-queue: a persistently failing endpoint
|
||||
// would otherwise spin the job queue. mSending is reset so the
|
||||
// next send() restarts delivery.
|
||||
JLOG(j_.warn()) << "RPCSub::sendThread exception: " << e.what();
|
||||
std::lock_guard sl(mLock);
|
||||
mSending = false;
|
||||
return;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
JLOG(j_.warn()) << "RPCSub::sendThread unknown exception";
|
||||
std::lock_guard sl(mLock);
|
||||
mSending = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Batch complete: re-queue for the next one (mSending stays set)
|
||||
// or clear mSending if the queue drained — both under the lock to
|
||||
// avoid a lost-wakeup race with send().
|
||||
std::lock_guard sl(mLock);
|
||||
if (mDeque.empty())
|
||||
mSending = false;
|
||||
else
|
||||
startSendingJob();
|
||||
}
|
||||
|
||||
private:
|
||||
// Wietse: we're not going to limit this, this is admin-port only, scale
|
||||
// accordingly enum { eventQueueMax = 32 };
|
||||
|
||||
boost::asio::io_service& m_io_service;
|
||||
JobQueue& m_jobQueue;
|
||||
|
||||
std::string mUrl;
|
||||
@@ -200,8 +258,15 @@ private:
|
||||
|
||||
int mSeq; // Next id to allocate.
|
||||
|
||||
std::size_t mDropped = 0; // Consecutive drops while queue is full.
|
||||
|
||||
bool mSending; // Sending threead is active.
|
||||
|
||||
// Maximum queued events before dropping. The default (16384) is a
|
||||
// ~10-minute buffer at 100+ events/ledger; a hopelessly behind
|
||||
// endpoint trips it and consumers detect the gap via the seq field.
|
||||
std::size_t const maxQueueSize_;
|
||||
|
||||
std::deque<std::pair<int, Json::Value>> mDeque;
|
||||
|
||||
beast::Journal const j_;
|
||||
@@ -217,21 +282,21 @@ RPCSub::RPCSub(InfoSub::Source& source) : InfoSub(source, Consumer())
|
||||
std::shared_ptr<RPCSub>
|
||||
make_RPCSub(
|
||||
InfoSub::Source& source,
|
||||
boost::asio::io_service& io_service,
|
||||
JobQueue& jobQueue,
|
||||
std::string const& strUrl,
|
||||
std::string const& strUsername,
|
||||
std::string const& strPassword,
|
||||
Logs& logs)
|
||||
Logs& logs,
|
||||
std::size_t maxQueueSize)
|
||||
{
|
||||
return std::make_shared<RPCSubImp>(
|
||||
std::ref(source),
|
||||
std::ref(io_service),
|
||||
std::ref(jobQueue),
|
||||
strUrl,
|
||||
strUsername,
|
||||
strPassword,
|
||||
logs);
|
||||
logs,
|
||||
maxQueueSize);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -76,7 +76,6 @@ doSubscribe(RPC::JsonContext& context)
|
||||
{
|
||||
auto rspSub = make_RPCSub(
|
||||
context.app.getOPs(),
|
||||
context.app.getIOService(),
|
||||
context.app.getJobQueue(),
|
||||
strUrl,
|
||||
strUsername,
|
||||
|
||||
Reference in New Issue
Block a user