diff --git a/hook/sfcodes.h b/hook/sfcodes.h index 77d13f6aa..8c7bc48f4 100644 --- a/hook/sfcodes.h +++ b/hook/sfcodes.h @@ -15,6 +15,7 @@ #define sfHookEmitCount ((1U << 16U) + 18U) #define sfHookExecutionIndex ((1U << 16U) + 19U) #define sfHookApiVersion ((1U << 16U) + 20U) +#define sfHookStateScale ((1U << 16U) + 21U) #define sfNetworkID ((2U << 16U) + 1U) #define sfFlags ((2U << 16U) + 2U) #define sfSourceTag ((2U << 16U) + 3U) diff --git a/src/ripple/app/hook/Enum.h b/src/ripple/app/hook/Enum.h index 19209389e..7f449958d 100644 --- a/src/ripple/app/hook/Enum.h +++ b/src/ripple/app/hook/Enum.h @@ -29,6 +29,8 @@ enum HookEmissionFlags : uint16_t { }; } // namespace ripple +using namespace ripple; + namespace hook { // RH TODO: put these somewhere better, and allow rules to be fed in inline uint32_t @@ -43,10 +45,26 @@ maxHookParameterValueSize(void) return 256; } -inline uint32_t -maxHookStateDataSize(void) +inline uint16_t +maxHookStateScale(void) { - return 256U; + return 16; +} + +inline uint32_t +maxHookStateDataSize(uint16_t hookStateScale) +{ + if (hookStateScale == 0) + { + // should not happen, but just in case + return 256U; + } + if (hookStateScale > maxHookStateScale()) + { + // should not happen, but just in case + return 256 * maxHookStateScale(); + } + return 256U * hookStateScale; } inline uint32_t diff --git a/src/ripple/app/hook/applyHook.h b/src/ripple/app/hook/applyHook.h index 011f50f3e..2c1f250bb 100644 --- a/src/ripple/app/hook/applyHook.h +++ b/src/ripple/app/hook/applyHook.h @@ -30,8 +30,9 @@ isEmittedTxn(ripple::STTx const& tx); class HookStateMap : public std::map< ripple::AccountID, // account that owns the state std::tuple< - int64_t, // remaining available ownercount - int64_t, // total namespace count + int64_t, // remaining available ownercount + int64_t, // total namespace count + uint16_t, // hook state scale std::map< ripple::uint256, // namespace std::map< @@ -465,9 +466,6 @@ apply( struct HookContext; -uint32_t -computeHookStateOwnerCount(uint32_t hookStateCount); - int64_t computeExecutionFee(uint64_t instructionCount); int64_t diff --git a/src/ripple/app/hook/impl/applyHook.cpp b/src/ripple/app/hook/impl/applyHook.cpp index fa9c5c614..d07e19be7 100644 --- a/src/ripple/app/hook/impl/applyHook.cpp +++ b/src/ripple/app/hook/impl/applyHook.cpp @@ -862,12 +862,6 @@ parseCurrency(uint8_t* cu_ptr, uint32_t cu_len) return {}; } -uint32_t -hook::computeHookStateOwnerCount(uint32_t hookStateCount) -{ - return hookStateCount; -} - inline int64_t serialize_keylet( ripple::Keylet& kl, @@ -1080,14 +1074,18 @@ hook::setHookState( return tefINTERNAL; // if the blob is too large don't set it - if (data.size() > hook::maxHookStateDataSize()) + uint16_t const hookStateScale = sleAccount->isFieldPresent(sfHookStateScale) + ? sleAccount->getFieldU16(sfHookStateScale) + : 1; + + if (data.size() > hook::maxHookStateDataSize(hookStateScale)) return temHOOK_DATA_TOO_LARGE; auto hookStateKeylet = ripple::keylet::hookState(acc, key, ns); auto hookStateDirKeylet = ripple::keylet::hookStateDir(acc, ns); uint32_t stateCount = sleAccount->getFieldU32(sfHookStateCount); - uint32_t oldStateReserve = computeHookStateOwnerCount(stateCount); + uint32_t oldStateCount = stateCount; auto hookState = view.peek(hookStateKeylet); @@ -1118,13 +1116,15 @@ hook::setHookState( if (stateCount > 0) --stateCount; // guard this because in the "impossible" event it is // already 0 we'll wrap back to int_max - // if removing this state entry would destroy the allotment then reduce // the owner count - if (computeHookStateOwnerCount(stateCount) < oldStateReserve) - adjustOwnerCount(view, sleAccount, -1, j); + if (stateCount < oldStateCount) + adjustOwnerCount(view, sleAccount, -hookStateScale, j); - sleAccount->setFieldU32(sfHookStateCount, stateCount); + if (view.rules().enabled(featureExtendedHookState) && stateCount == 0) + sleAccount->makeFieldAbsent(sfHookStateCount); + else + sleAccount->setFieldU32(sfHookStateCount, stateCount); if (nsDestroyed) hook::removeHookNamespaceEntry(*sleAccount, ns); @@ -1151,19 +1151,19 @@ hook::setHookState( { ++stateCount; - if (computeHookStateOwnerCount(stateCount) > oldStateReserve) + if (stateCount > oldStateCount) { // the hook used its allocated allotment of state entries for its // previous ownercount increment ownercount and give it another // allotment - ++ownerCount; + ownerCount += hookStateScale; XRPAmount const newReserve{view.fees().accountReserve(ownerCount)}; if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserve) return tecINSUFFICIENT_RESERVE; - adjustOwnerCount(view, sleAccount, 1, j); + adjustOwnerCount(view, sleAccount, hookStateScale, j); } // update state count @@ -1451,7 +1451,7 @@ lookup_state_cache( if (stateMap.find(acc) == stateMap.end()) return std::nullopt; - auto& stateMapAcc = std::get<2>(stateMap[acc]); + auto& stateMapAcc = std::get<3>(stateMap[acc]); if (stateMapAcc.find(ns) == stateMapAcc.end()) return std::nullopt; @@ -1486,6 +1486,7 @@ set_state_cache( if (stateMap.find(acc) == stateMap.end()) { + // new Account Key // if this is the first time this account has been interacted with // we will compute how many available reserve positions there are auto const& fees = hookCtx.applyCtx.view().fees(); @@ -1497,6 +1498,10 @@ set_state_cache( STAmount bal = accSLE->getFieldAmount(sfBalance); + uint16_t const hookStateScale = accSLE->isFieldPresent(sfHookStateScale) + ? accSLE->getFieldU16(sfHookStateScale) + : 1; + int64_t availableForReserves = bal.xrp().drops() - fees.accountReserve(accSLE->getFieldU32(sfOwnerCount)).drops(); @@ -1507,7 +1512,7 @@ set_state_cache( availableForReserves /= increment; - if (availableForReserves < 1 && modified) + if (availableForReserves < hookStateScale && modified) return RESERVE_INSUFFICIENT; int64_t namespaceCount = accSLE->isFieldPresent(sfHookNamespaces) @@ -1526,20 +1531,28 @@ set_state_cache( stateMap.modified_entry_count++; + // sanity check + if (view.rules().enabled(featureExtendedHookState) && + availableForReserves < hookStateScale) + return INTERNAL_ERROR; + stateMap[acc] = { - availableForReserves - 1, + availableForReserves - hookStateScale, namespaceCount, + hookStateScale, {{ns, {{key, {modified, data}}}}}}; return 1; } auto& availableForReserves = std::get<0>(stateMap[acc]); auto& namespaceCount = std::get<1>(stateMap[acc]); - auto& stateMapAcc = std::get<2>(stateMap[acc]); - bool const canReserveNew = availableForReserves > 0; + auto& hookStateScale = std::get<2>(stateMap[acc]); + auto& stateMapAcc = std::get<3>(stateMap[acc]); + bool const canReserveNew = availableForReserves >= hookStateScale; if (stateMapAcc.find(ns) == stateMapAcc.end()) { + // new Namespace Key if (modified) { if (!canReserveNew) @@ -1557,7 +1570,11 @@ set_state_cache( namespaceCount++; } - availableForReserves--; + if (view.rules().enabled(featureExtendedHookState) && + availableForReserves < hookStateScale) + return INTERNAL_ERROR; + + availableForReserves -= hookStateScale; stateMap.modified_entry_count++; } @@ -1569,11 +1586,17 @@ set_state_cache( auto& stateMapNs = stateMapAcc[ns]; if (stateMapNs.find(key) == stateMapNs.end()) { + // new State Key if (modified) { if (!canReserveNew) return RESERVE_INSUFFICIENT; - availableForReserves--; + + if (view.rules().enabled(featureExtendedHookState) && + availableForReserves < hookStateScale) + return INTERNAL_ERROR; + + availableForReserves -= hookStateScale; stateMap.modified_entry_count++; } @@ -1582,6 +1605,7 @@ set_state_cache( return 1; } + // existing State Key if (modified) { if (!stateMapNs[key].first) @@ -1670,7 +1694,15 @@ DEFINE_HOOK_FUNCTION( (aread_len && NOT_IN_BOUNDS(aread_ptr, aread_len, memory_length))) return OUT_OF_BOUNDS; - uint32_t maxSize = hook::maxHookStateDataSize(); + auto const sleAccount = view.peek(hookCtx.result.accountKeylet); + if (!sleAccount && view.rules().enabled(featureExtendedHookState)) + return tefINTERNAL; + + uint16_t const hookStateScale = sleAccount->isFieldPresent(sfHookStateScale) + ? sleAccount->getFieldU16(sfHookStateScale) + : 1; + + uint32_t maxSize = hook::maxHookStateDataSize(hookStateScale); if (read_len > maxSize) return TOO_BIG; @@ -1814,7 +1846,7 @@ hook::finalizeHookState( for (const auto& accEntry : stateMap) { const auto& acc = accEntry.first; - for (const auto& nsEntry : std::get<2>(accEntry.second)) + for (const auto& nsEntry : std::get<3>(accEntry.second)) { const auto& ns = nsEntry.first; for (const auto& cacheEntry : nsEntry.second) diff --git a/src/ripple/app/tx/impl/SetAccount.cpp b/src/ripple/app/tx/impl/SetAccount.cpp index 8cbee5fd7..94850eaad 100644 --- a/src/ripple/app/tx/impl/SetAccount.cpp +++ b/src/ripple/app/tx/impl/SetAccount.cpp @@ -184,6 +184,19 @@ SetAccount::preflight(PreflightContext const& ctx) return temMALFORMED; } + // HookStateScale + if (tx.isFieldPresent(sfHookStateScale)) + { + if (!ctx.rules.enabled(featureExtendedHookState)) + return temMALFORMED; + + uint16_t scale = tx.getFieldU16(sfHookStateScale); + if (scale == 0 || + scale > hook::maxHookStateScale()) // Min: 1, Max: 16 (256 + // * 16 = 4096 bytes) + return temMALFORMED; + } + return preflight2(ctx); } @@ -249,6 +262,20 @@ SetAccount::preclaim(PreclaimContext const& ctx) } } + // HookStateScale + if (ctx.tx.isFieldPresent(sfHookStateScale)) + { + uint16_t const newScale = ctx.tx.getFieldU16(sfHookStateScale); + uint16_t const currentScale = sle->getFieldU16(sfHookStateScale); + uint32_t const stateCount = sle->getFieldU32(sfHookStateCount); + if (stateCount > 0 && newScale < currentScale) + { + JLOG(ctx.j.trace()) + << "Cannot decrease HookStateScale if state count is not zero."; + return tecHAS_HOOK_STATE; + } + } + return tesSUCCESS; } @@ -629,6 +656,50 @@ SetAccount::doApply() if (uFlagsIn != uFlagsOut) sle->setFieldU32(sfFlags, uFlagsOut); + // HookStateScale + if (tx.isFieldPresent(sfHookStateScale)) + { + uint16_t const newScale = tx.getFieldU16(sfHookStateScale); + uint16_t const oldScale = sle->isFieldPresent(sfHookStateScale) + ? sle->getFieldU16(sfHookStateScale) + : 1; + if (newScale == oldScale) + { + // do nothing + } + else if (newScale == 1) + { + sle->makeFieldAbsent(sfHookStateScale); + } + else + { + // increase OwnerCount + uint32_t const stateCount = sle->getFieldU32(sfHookStateCount); + uint32_t const oldOwnerCount = sle->getFieldU32(sfOwnerCount); + + uint32_t const newOwnerCount = oldOwnerCount - + (oldScale * stateCount) + (newScale * stateCount); + + // sanity check + if (newOwnerCount < oldOwnerCount) + return tecINTERNAL; + + if (newOwnerCount != oldOwnerCount) + { + STAmount const balance = STAmount((*sle)[sfBalance]).xrp(); + XRPAmount const reserve = + view().fees().accountReserve(newOwnerCount); + if (balance < reserve) + return tecINSUFFICIENT_RESERVE; + + adjustOwnerCount( + view(), sle, newOwnerCount - oldOwnerCount, j_); + } + + sle->setFieldU16(sfHookStateScale, newScale); + } + } + return tesSUCCESS; } diff --git a/src/ripple/app/tx/impl/SetHook.cpp b/src/ripple/app/tx/impl/SetHook.cpp index 79e68e01d..9ca829557 100644 --- a/src/ripple/app/tx/impl/SetHook.cpp +++ b/src/ripple/app/tx/impl/SetHook.cpp @@ -858,6 +858,9 @@ SetHook::destroyNamespace( bool const fixEnabled = ctx.rules.enabled(fixNSDelete); bool partialDelete = false; uint32_t oldStateCount = sleAccount->getFieldU32(sfHookStateCount); + uint16_t scale = sleAccount->isFieldPresent(sfHookStateScale) + ? sleAccount->getFieldU16(sfHookStateScale) + : 1; std::vector toDelete; toDelete.reserve(sleDir->getFieldV256(sfIndexes).size()); @@ -929,6 +932,15 @@ SetHook::destroyNamespace( view.erase(sleItem); } + if (view.rules().enabled(featureExtendedHookState) && + oldStateCount < toDelete.size()) + { + JLOG(ctx.j.fatal()) << "HookSet(" << hook::log::NSDELETE_COUNT << ")[" + << HS_ACC() << "]: DeleteState " + << "stateCount less than zero (overflow)"; + return tefBAD_LEDGER; + } + uint32_t stateCount = oldStateCount - toDelete.size(); if (stateCount > oldStateCount) { @@ -945,7 +957,18 @@ SetHook::destroyNamespace( sleAccount->setFieldU32(sfHookStateCount, stateCount); if (ctx.rules.enabled(fixNSDelete)) - adjustOwnerCount(view, sleAccount, -toDelete.size(), ctx.j); + { + auto const ownerCount = sleAccount->getFieldU32(sfOwnerCount); + if (view.rules().enabled(featureExtendedHookState) && + ownerCount < toDelete.size() * scale) + { + JLOG(ctx.j.fatal()) << "HookSet(" << hook::log::NSDELETE_COUNT + << ")[" << HS_ACC() << "]: DeleteState " + << "OwnerCount less than zero (overflow)"; + return tefBAD_LEDGER; + } + adjustOwnerCount(view, sleAccount, -toDelete.size() * scale, ctx.j); + } if (!partialDelete && sleAccount->isFieldPresent(sfHookNamespaces)) hook::removeHookNamespaceEntry(*sleAccount, ns); diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index ad5b22bd7..ed6b4e73f 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -74,7 +74,7 @@ namespace detail { // Feature.cpp. Because it's only used to reserve storage, and determine how // large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than // the actual number of amendments. A LogicError on startup will verify this. -static constexpr std::size_t numFeatures = 87; +static constexpr std::size_t numFeatures = 88; /** Amendments that this server supports and the default voting behavior. Whether they are enabled depends on the Rules defined in the validated @@ -375,6 +375,7 @@ extern uint256 const featureDeepFreeze; extern uint256 const featureIOUIssuerWeakTSH; extern uint256 const featureCron; extern uint256 const fixInvalidTxFlags; +extern uint256 const featureExtendedHookState; } // namespace ripple diff --git a/src/ripple/protocol/SField.h b/src/ripple/protocol/SField.h index 2f9619de9..f507b2232 100644 --- a/src/ripple/protocol/SField.h +++ b/src/ripple/protocol/SField.h @@ -354,6 +354,7 @@ extern SF_UINT16 const sfHookStateChangeCount; extern SF_UINT16 const sfHookEmitCount; extern SF_UINT16 const sfHookExecutionIndex; extern SF_UINT16 const sfHookApiVersion; +extern SF_UINT16 const sfHookStateScale; // 32-bit integers (common) extern SF_UINT32 const sfNetworkID; diff --git a/src/ripple/protocol/TER.h b/src/ripple/protocol/TER.h index 31ad16a3c..573e0b628 100644 --- a/src/ripple/protocol/TER.h +++ b/src/ripple/protocol/TER.h @@ -343,6 +343,7 @@ enum TECcodes : TERUnderlyingType { tecINSUF_RESERVE_SELLER = 187, tecIMMUTABLE = 188, tecTOO_MANY_REMARKS = 189, + tecHAS_HOOK_STATE = 190, tecLAST_POSSIBLE_ENTRY = 255, }; diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index 415e18830..64d05f134 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -481,6 +481,7 @@ REGISTER_FEATURE(DeepFreeze, Supported::yes, VoteBehavior::De REGISTER_FEATURE(IOUIssuerWeakTSH, Supported::yes, VoteBehavior::DefaultNo); REGISTER_FEATURE(Cron, Supported::yes, VoteBehavior::DefaultNo); REGISTER_FIX (fixInvalidTxFlags, Supported::yes, VoteBehavior::DefaultYes); +REGISTER_FEATURE(ExtendedHookState, Supported::yes, VoteBehavior::DefaultNo); // The following amendments are obsolete, but must remain supported // because they could potentially get enabled. diff --git a/src/ripple/protocol/impl/LedgerFormats.cpp b/src/ripple/protocol/impl/LedgerFormats.cpp index 83303e620..def5f3000 100644 --- a/src/ripple/protocol/impl/LedgerFormats.cpp +++ b/src/ripple/protocol/impl/LedgerFormats.cpp @@ -68,6 +68,7 @@ LedgerFormats::LedgerFormats() {sfGovernanceMarks, soeOPTIONAL}, {sfAccountIndex, soeOPTIONAL}, {sfTouchCount, soeOPTIONAL}, + {sfHookStateScale, soeOPTIONAL}, {sfCron, soeOPTIONAL}, }, commonFields); diff --git a/src/ripple/protocol/impl/SField.cpp b/src/ripple/protocol/impl/SField.cpp index eeecaa126..c4f2ef85a 100644 --- a/src/ripple/protocol/impl/SField.cpp +++ b/src/ripple/protocol/impl/SField.cpp @@ -102,6 +102,7 @@ CONSTRUCT_TYPED_SFIELD(sfHookStateChangeCount, "HookStateChangeCount", UINT16, CONSTRUCT_TYPED_SFIELD(sfHookEmitCount, "HookEmitCount", UINT16, 18); CONSTRUCT_TYPED_SFIELD(sfHookExecutionIndex, "HookExecutionIndex", UINT16, 19); CONSTRUCT_TYPED_SFIELD(sfHookApiVersion, "HookApiVersion", UINT16, 20); +CONSTRUCT_TYPED_SFIELD(sfHookStateScale, "HookStateScale", UINT16, 21); // 32-bit integers (common) CONSTRUCT_TYPED_SFIELD(sfNetworkID, "NetworkID", UINT32, 1); diff --git a/src/ripple/protocol/impl/TER.cpp b/src/ripple/protocol/impl/TER.cpp index 30bcf46e2..08992c6a3 100644 --- a/src/ripple/protocol/impl/TER.cpp +++ b/src/ripple/protocol/impl/TER.cpp @@ -94,6 +94,8 @@ transResults() MAKE_ERROR(tecINSUF_RESERVE_SELLER, "The seller of an object has insufficient reserves, and thus cannot complete the sale."), MAKE_ERROR(tecIMMUTABLE, "The remark is marked immutable on the object, and therefore cannot be updated."), MAKE_ERROR(tecTOO_MANY_REMARKS, "The number of remarks on the object would exceed the limit of 32."), + MAKE_ERROR(tecHAS_HOOK_STATE, "Delete all hook state before reducing scale"), + MAKE_ERROR(tefALREADY, "The exact transaction was already in this ledger."), MAKE_ERROR(tefBAD_ADD_AUTH, "Not authorized to add account."), MAKE_ERROR(tefBAD_AUTH, "Transaction's public key is not authorized."), diff --git a/src/ripple/protocol/impl/TxFormats.cpp b/src/ripple/protocol/impl/TxFormats.cpp index efcb44752..789de36f2 100644 --- a/src/ripple/protocol/impl/TxFormats.cpp +++ b/src/ripple/protocol/impl/TxFormats.cpp @@ -60,6 +60,7 @@ TxFormats::TxFormats() {sfTickSize, soeOPTIONAL}, {sfTicketSequence, soeOPTIONAL}, {sfNFTokenMinter, soeOPTIONAL}, + {sfHookStateScale, soeOPTIONAL}, }, commonFields); diff --git a/src/test/app/SetHook_test.cpp b/src/test/app/SetHook_test.cpp index 75caade5e..8fef47656 100644 --- a/src/test/app/SetHook_test.cpp +++ b/src/test/app/SetHook_test.cpp @@ -879,6 +879,9 @@ public: auto const bob = Account{"bob"}; env.fund(XRP(10000), bob); + auto const carol = Account{"carol"}; + env.fund(XRP(10000), carol); + Json::Value jv; jv[jss::Account] = alice.human(); jv[jss::TransactionType] = jss::SetHook; @@ -962,6 +965,7 @@ public: data[3] == 'u' && data[4] == 'e' && data[5] == '\0'); BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == 2); + BEAST_EXPECT((*env.le(alice))[sfHookStateCount] == 1); } // delete the namespace @@ -990,7 +994,113 @@ public: // ensure the state object is gone BEAST_EXPECT(!env.le(stateKeylet)); - BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == fixNS ? 1 : 2); + BEAST_EXPECT((*env.le(alice))[sfOwnerCount] == (fixNS ? 1 : 2)); + BEAST_EXPECT(!(env.le("alice")->isFieldPresent(sfHookStateCount))); + } + + if (env.current()->rules().enabled(featureExtendedHookState)) + { + // Test hook with scaled state data + TestHook scaled_state_wasm = wasm[ + R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set (uint32_t read_ptr, uint32_t + read_len, uint32_t kread_ptr, uint32_t kread_len); + + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + extern int64_t slot_set(uint32_t, uint32_t, uint32_t); + extern int64_t slot_subfield(uint32_t, uint32_t, uint32_t); + extern int64_t slot(uint32_t, uint32_t, uint32_t); + extern int64_t hook_account(uint32_t, uint32_t); + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + + #define SBUF(x) x, sizeof(x) + #define TOO_BIG -3 + #define DOESNT_EXIST -5 + #define KEYLET_ACCOUNT 3 + + #define sfHookStateScale ((1U << 16U) + 21U) + + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x,sizeof(#x),__LINE__) + int64_t hook(uint32_t reserved ) + { + _g(1,1); + + uint8_t hook_acc[20]; + ASSERT(hook_account(hook_acc, 20) == 20); + uint8_t account_keylet[34]; + ASSERT(util_keylet(account_keylet, 34, KEYLET_ACCOUNT, + hook_acc, 20, 0,0,0,0) == 34); + + ASSERT(slot_set(account_keylet, 34, 1) == 1); + slot_subfield(1, sfHookStateScale, 2); + int64_t scale = slot(0,0,2); + + if (scale == 5) { + ASSERT(state_set(0, 256, SBUF("test1")) == 256); + ASSERT(state_set(0, 256*2, SBUF("test2")) == 256*2); + ASSERT(state_set(0, 256*3, SBUF("test3")) == 256*3); + ASSERT(state_set(0, 256*4, SBUF("test4")) == 256*4); + ASSERT(state_set(0, 256*5, SBUF("test5")) == 256*5); + ASSERT(state_set(0, 256*5+1, SBUF("test")) == TOO_BIG); + accept(0,0,scale); + } + rollback(0,0,scale); + } + )[test.hook]"]; + + HASH_WASM(scaled_state); + BEAST_EXPECT(!env.le(carol)->isFieldPresent(sfHookStateCount)); + + // Install hook on carol + Json::Value jv = + ripple::test::jtx::hook(carol, {{hso(scaled_state_wasm)}}, 0); + jv[jss::Hooks][0U][jss::Hook][jss::HookNamespace] = ns_str; + jv[jss::Hooks][0U][jss::Hook][jss::HookOn] = + to_string(UINT256_BIT[ttACCOUNT_SET]); + env(jv, M("Create scaled state hook"), HSFEE, ter(tesSUCCESS)); + env.close(); + + BEAST_EXPECT((*env.le(carol))[sfOwnerCount] == 1); + BEAST_EXPECT(!env.le(carol)->isFieldPresent(sfHookStateCount)); + + { + // HookStateScale => 5 + Json::Value jv = noop(carol); + jv[sfHookStateScale.fieldName] = 5; + env(jv, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(carol))[sfOwnerCount] == 1); + BEAST_EXPECT(!env.le(carol)->isFieldPresent(sfHookStateCount)); + + Json::Value invoke = invoke::invoke(carol); + env(invoke, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(carol))[sfOwnerCount] == 26); + BEAST_EXPECT((*env.le(carol))[sfHookStateCount] == 5); + } + + // Delete namespace to clean up state + Json::Value iv; + iv[jss::Flags] = hsfNSDELETE; + iv[jss::HookNamespace] = ns_str; + jv[jss::Hooks][0U][jss::Hook] = iv; + env(jv, M("Delete namespace"), HSFEE); + env.close(); + + // Verify state cleanup + BEAST_EXPECT( + (*env.le(carol))[sfOwnerCount] == features[fixNSDelete] ? 1 + : 26); + BEAST_EXPECT(!env.le(carol)->isFieldPresent(sfHookStateCount)); } } @@ -9028,12 +9138,16 @@ public: auto const david = Account{"david"}; auto const eve = Account{"eve"}; // small balance auto const frank = Account{"frank"}; // big balance + auto const gary = Account{"gary"}; + auto const hank = Account{"hank"}; env.fund(XRP(10000), alice); env.fund(XRP(10000), bob); env.fund(XRP(10000), cho); env.fund(XRP(1000000), david); env.fund(XRP(2600), eve); env.fund(XRP(1000000000), frank); + env.fund(XRP(10000), gary); + env.fund(XRP(10000), hank); // install a rollback hook on cho env(ripple::test::jtx::hook( @@ -9058,6 +9172,101 @@ public: BEAST_EXPECT((*env.le("alice"))[sfOwnerCount] == 0); } + // bounds and buffer size checks + { + TestHook hook = wasm[R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set ( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len + ); + extern int64_t otxn_param(uint32_t, uint32_t, uint32_t, uint32_t); + + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + #define TOO_SMALL (-4) + #define TOO_BIG (-3) + #define OUT_OF_BOUNDS (-1) + + int64_t hook(uint32_t reserved) + { + _g(1,1); + + // bounds and buffer size checks + { + // RH NOTE: readptr/len 0/0 = delete entry + + ASSERT(state_set(0,0,0,0) == TOO_SMALL); + ASSERT(state_set(0,0,0,33) == TOO_BIG); + ASSERT(state_set(0,0,0,1000000) == TOO_BIG); + ASSERT(state_set(0,0,1000000,1) == OUT_OF_BOUNDS); + + ASSERT(state_set(0,1000000, 0, 32) == OUT_OF_BOUNDS); + ASSERT(state_set(1000000, 0, 0, 32) == OUT_OF_BOUNDS); + + uint16_t size; + ASSERT(otxn_param(&size, 2, "SIZE", 4) > 0); + ASSERT(state_set(0, size, 0, 32) == TOO_BIG); + } + accept(0,0,0); + } + )[test.hook]"]; + + // install the hook on alice + env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), + M("set state_set 1"), + HSFEE); + env.close(); + + BEAST_EXPECT((*env.le("alice"))[sfOwnerCount] == 1); + + // invoke the hook with cho (rollback after alice's hooks have + // executed) + Json::Value payJv1 = pay(alice, cho, XRP(1)); + { + Json::Value params{Json::arrayValue}; + params[0U][jss::HookParameter][jss::HookParameterName] = + strHex(std::string("SIZE")); + params[0U][jss::HookParameter][jss::HookParameterValue] = + features[featureExtendedHookState] ? "0108" /* 2049 */ + : "0101" /* 257 */; + payJv1[jss::HookParameters] = params; + } + env(payJv1, + M("test state_set 1 rollback"), + fee(XRP(1)), + ter(tecHOOK_REJECTED)); + + BEAST_EXPECT((*env.le("alice"))[sfOwnerCount] == 1); + + auto const nsdir = env.le(nsdirkl); + BEAST_EXPECT(!nsdir); + + auto const state1 = env.le( + ripple::keylet::hookState(aliceid, beast::zero, beast::zero)); + BEAST_EXPECT(!state1); + + // invoke the hook from bob to alice, this will work + Json::Value payJv2 = pay(bob, alice, XRP(1)); + { + Json::Value params{Json::arrayValue}; + params[0U][jss::HookParameter][jss::HookParameterName] = + strHex(std::string("SIZE")); + params[0U][jss::HookParameter][jss::HookParameterValue] = + features[featureExtendedHookState] ? "0108" /* 2049 */ + : "0101" /* 257 */; + payJv2[jss::HookParameters] = params; + } + env(payJv2, M("test state_set 1"), fee(XRP(1))); + env.close(); + } + // first hook will set two state objects with different keys and data on // alice { @@ -9094,32 +9303,12 @@ public: #define ASSERT(x)\ if (!(x))\ rollback((uint32_t)#x, sizeof(#x), __LINE__); - #define TOO_SMALL (-4) - #define TOO_BIG (-3) - #define OUT_OF_BOUNDS (-1) #define SBUF(x) (uint32_t)(x), sizeof(x) - int64_t hook(uint32_t reserved ) + int64_t hook(uint32_t reserved) { _g(1,1); - - // bounds and buffer size checks - { - // RH NOTE: readptr/len 0/0 = delete entry - - ASSERT(state_set(0,0,0,0) == TOO_SMALL); - ASSERT(state_set(0,0,0,33) == TOO_BIG); - ASSERT(state_set(0,0,0,1000000) == TOO_BIG); - ASSERT(state_set(0,0,1000000,1) == OUT_OF_BOUNDS); - - ASSERT(state_set(0,1000000, 0, 32) == OUT_OF_BOUNDS); - ASSERT(state_set(1000000, 0, 0, 32) == OUT_OF_BOUNDS); - - ASSERT(state_set(0, 257, 0, 32) == TOO_BIG); - } - - // create state 1 { uint8_t key[32] = @@ -9130,27 +9319,24 @@ public: 0,0,0,0,0,0,0,0 }; - uint8_t data[4] = + uint8_t data[4] = { 0xCAU,0xFEU,0xBAU,0xBEU }; - ASSERT(state_set(SBUF(data), SBUF(key)) == sizeof(data)); } - // create state 2 + // create state 2 { uint8_t key[3] = { 1,2,3 }; - ASSERT(state_set(SBUF(data2), SBUF(key)) == sizeof(data2)); } - accept(0,0,0); } @@ -9719,6 +9905,210 @@ public: BEAST_EXPECT((*env.le("frank"))[sfOwnerCount] == 260); } + if (env.current()->rules().enabled(featureExtendedHookState)) + { + // Test hook with scaled state data + TestHook scaled_state_wasm = wasm[ + R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set (uint32_t read_ptr, uint32_t + read_len, uint32_t kread_ptr, uint32_t kread_len); + + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + extern int64_t slot_set(uint32_t, uint32_t, uint32_t); + extern int64_t slot_subfield(uint32_t, uint32_t, uint32_t); + extern int64_t slot(uint32_t, uint32_t, uint32_t); + extern int64_t hook_account(uint32_t, uint32_t); + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + + #define SBUF(x) x, sizeof(x) + #define TOO_BIG -3 + #define DOESNT_EXIST -5 + #define KEYLET_ACCOUNT 3 + + #define sfHookStateScale ((1U << 16U) + 21U) + + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x,sizeof(#x),__LINE__) + int64_t hook(uint32_t reserved ) + { + _g(1,1); + + uint8_t hook_acc[20]; + ASSERT(hook_account(hook_acc, 20) == 20); + uint8_t account_keylet[34]; + ASSERT(util_keylet(account_keylet, 34, KEYLET_ACCOUNT, + hook_acc, 20, 0,0,0,0) == 34); + + ASSERT(slot_set(account_keylet, 34, 1) == 1); + slot_subfield(1, sfHookStateScale, 2); + int64_t scale = slot(0,0,2); + + if (scale == DOESNT_EXIST) { + ASSERT(state_set(0, 256, SBUF("test0")) == 256); + ASSERT(state_set(0, 257, SBUF("test")) == TOO_BIG); + accept(0,0,scale); + } + if (scale == 2) { + ASSERT(state_set(0, 256, SBUF("test1")) == 256); + ASSERT(state_set(0, 256*2, SBUF("test2")) == 256*2); + ASSERT(state_set(0, 256*2+1, SBUF("test")) == + TOO_BIG); accept(0,0,scale); + } + if (scale == 5) { + ASSERT(state_set(0, 256, SBUF("test3")) == 256); + ASSERT(state_set(0, 256*5, SBUF("test4")) == 256*5); + ASSERT(state_set(0, 256*5+1, SBUF("test")) == + TOO_BIG); accept(0,0,scale); + } + rollback(0,0,scale); + } + )[test.hook]"]; + + HASH_WASM(scaled_state); + BEAST_EXPECT(!env.le(gary)->isFieldPresent(sfHookStateCount)); + + // Install hook on carol + Json::Value jv = + ripple::test::jtx::hook(gary, {{hso(scaled_state_wasm)}}, 0); + // jv[jss::Hooks][0U][jss::Hook][jss::HookNamespace] = ns_str; + jv[jss::Hooks][0U][jss::Hook][jss::HookOn] = + to_string(UINT256_BIT[ttACCOUNT_SET]); + env(jv, M("Create scaled state hook"), HSFEE, ter(tesSUCCESS)); + env.close(); + + BEAST_EXPECT((*env.le(gary))[sfOwnerCount] == 1); + BEAST_EXPECT(!env.le(gary)->isFieldPresent(sfHookStateCount)); + + { + // no HookStateScale + Json::Value invoke = invoke::invoke(gary); + env(invoke, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(gary))[sfOwnerCount] == 2); + BEAST_EXPECT((*env.le(gary))[sfHookStateCount] == 1); + } + + { + // HookStateScale => 2 + Json::Value jv = noop(gary); + jv[sfHookStateScale.fieldName] = 2; + env(jv, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(gary))[sfOwnerCount] == 3); + BEAST_EXPECT((*env.le(gary))[sfHookStateCount] == 1); + + Json::Value invoke = invoke::invoke(gary); + env(invoke, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(gary))[sfOwnerCount] == 7); + BEAST_EXPECT((*env.le(gary))[sfHookStateCount] == 3); + } + { + // HookStateScale => 5 + Json::Value jv = noop(gary); + jv[sfHookStateScale.fieldName] = 5; + env(jv, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(gary))[sfOwnerCount] == 16); + BEAST_EXPECT((*env.le(gary))[sfHookStateCount] == 3); + + Json::Value invoke = invoke::invoke(gary); + env(invoke, HSFEE); + env.close(); + BEAST_EXPECT((*env.le(gary))[sfOwnerCount] == 26); + BEAST_EXPECT((*env.le(gary))[sfHookStateCount] == 5); + } + } + + { + bool extHookStateEnabled = features[featureExtendedHookState]; + // tests for set_state_cache + if (extHookStateEnabled) + { + TestHook extended_state_reserve_hook = wasm[R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set ( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len + ); + extern int64_t state_foreign_set ( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len, + uint32_t nread_ptr, + uint32_t nread_len, + uint32_t aread_ptr, + uint32_t aread_len + ); + extern int64_t otxn_param(uint32_t, uint32_t, uint32_t, uint32_t); + #define RESERVE_INSUFFICIENT -38 + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + #define ASSERT_EQUAL(x, y)\ + if (!(x == y))\ + rollback((uint32_t)#x, sizeof(#x), x); + int64_t hook(uint32_t reserved) + { + _g(1,1); + { + // 1. first account for StateMap + ASSERT_EQUAL(state_set(0, 1, "1", 1), RESERVE_INSUFFICIENT); + // 2. first namespace for StateMap + ASSERT_EQUAL(state_foreign_set(0, 1, "1", 1, "1", 32, 0, 0), RESERVE_INSUFFICIENT); + // 3. first statekey for StateMap + ASSERT_EQUAL(state_set(0, 1, "2", 1), RESERVE_INSUFFICIENT); + // 4. existing statedata + ASSERT_EQUAL(state_set(0, 1, "1", 1), RESERVE_INSUFFICIENT); + } + accept(0,0,0); + } + )[test.hook]"]; + + // install the hook on gary + Json::Value jv = hso(extended_state_reserve_hook, overrideFlag); + jv[jss::HookOn] = + "fffffffffffffffffffffffffffffffffffffff7ffffffffffffffffff" + "bfffff"; // only invoke high + env(ripple::test::jtx::hook(hank, {{jv}}, 0), HSFEE); + env.close(); + + Json::Value jv1 = noop(hank); + jv1[sfHookStateScale.fieldName] = 8; + env(jv1, HSFEE); + env.close(); + + auto const caller = Account{"caller"}; + env.fund(XRP(10000), caller); + env.close(); + auto const payAmount = env.balance(hank) - + (env.current()->fees().accountReserve(1 + 8)) - + drops(1); // 8 + Hook + // reduce hank's balance + env(pay(hank, Account{"master"}, payAmount), fee(XRP(1))); + env.close(); + + // invoke the hook from alice + Json::Value invokeJv5 = invoke::invoke(caller, hank, ""); + env(invokeJv5, M("test state_set 15"), fee(XRP(1))); + env.close(); + } + } + // RH TODO: // check state can be set on emit callback // check namespacing provides for non-collision of same key @@ -12884,14 +13274,17 @@ public: using namespace test::jtx; static FeatureBitset const all{supported_amendments()}; - static std::array const feats{ + static std::array const feats{ all, all - fixXahauV2, all - fixXahauV1 - fixXahauV2, all - fixXahauV1 - fixXahauV2 - fixNSDelete, all - fixXahauV1 - fixXahauV2 - fixNSDelete - fixPageCap, all - fixXahauV1 - fixXahauV2 - fixNSDelete - fixPageCap - - featureHookCanEmit}; + featureHookCanEmit, + all - fixXahauV1 - fixXahauV2 - fixNSDelete - fixPageCap - + featureExtendedHookState, + }; if (BEAST_EXPECT(instance < feats.size())) { @@ -13058,7 +13451,8 @@ SETHOOK_TEST(1, false) SETHOOK_TEST(2, false) SETHOOK_TEST(3, false) SETHOOK_TEST(4, false) -SETHOOK_TEST(5, true) +SETHOOK_TEST(5, false) +SETHOOK_TEST(6, true) BEAST_DEFINE_TESTSUITE_PRIO(SetHook0, app, ripple, 2); BEAST_DEFINE_TESTSUITE_PRIO(SetHook1, app, ripple, 2); @@ -13066,6 +13460,7 @@ BEAST_DEFINE_TESTSUITE_PRIO(SetHook2, app, ripple, 2); BEAST_DEFINE_TESTSUITE_PRIO(SetHook3, app, ripple, 2); BEAST_DEFINE_TESTSUITE_PRIO(SetHook4, app, ripple, 2); BEAST_DEFINE_TESTSUITE_PRIO(SetHook5, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(SetHook6, app, ripple, 2); } // namespace test } // namespace ripple #undef M diff --git a/src/test/app/SetHook_wasm.h b/src/test/app/SetHook_wasm.h index a7e75c827..626e4a849 100644 --- a/src/test/app/SetHook_wasm.h +++ b/src/test/app/SetHook_wasm.h @@ -10,6 +10,187 @@ namespace ripple { namespace test { std::map> wasm = { /* ==== WASM: 0 ==== */ + {R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set (uint32_t read_ptr, uint32_t + read_len, uint32_t kread_ptr, uint32_t kread_len); + + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + extern int64_t slot_set(uint32_t, uint32_t, uint32_t); + extern int64_t slot_subfield(uint32_t, uint32_t, uint32_t); + extern int64_t slot(uint32_t, uint32_t, uint32_t); + extern int64_t hook_account(uint32_t, uint32_t); + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + + #define SBUF(x) x, sizeof(x) + #define TOO_BIG -3 + #define DOESNT_EXIST -5 + #define KEYLET_ACCOUNT 3 + + #define sfHookStateScale ((1U << 16U) + 21U) + + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x,sizeof(#x),__LINE__) + int64_t hook(uint32_t reserved ) + { + _g(1,1); + + uint8_t hook_acc[20]; + ASSERT(hook_account(hook_acc, 20) == 20); + uint8_t account_keylet[34]; + ASSERT(util_keylet(account_keylet, 34, KEYLET_ACCOUNT, + hook_acc, 20, 0,0,0,0) == 34); + + ASSERT(slot_set(account_keylet, 34, 1) == 1); + slot_subfield(1, sfHookStateScale, 2); + int64_t scale = slot(0,0,2); + + if (scale == 5) { + ASSERT(state_set(0, 256, SBUF("test1")) == 256); + ASSERT(state_set(0, 256*2, SBUF("test2")) == 256*2); + ASSERT(state_set(0, 256*3, SBUF("test3")) == 256*3); + ASSERT(state_set(0, 256*4, SBUF("test4")) == 256*4); + ASSERT(state_set(0, 256*5, SBUF("test5")) == 256*5); + ASSERT(state_set(0, 256*5+1, SBUF("test")) == TOO_BIG); + accept(0,0,scale); + } + rollback(0,0,scale); + } + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x35U, + 0x07U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x02U, 0x7FU, + 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, + 0x60U, 0x09U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, + 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, + 0x60U, 0x04U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x01U, + 0x7FU, 0x01U, 0x7EU, 0x02U, 0x89U, 0x01U, 0x09U, 0x03U, 0x65U, 0x6EU, + 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, + 0x0CU, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x5FU, 0x61U, 0x63U, 0x63U, 0x6FU, + 0x75U, 0x6EU, 0x74U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x08U, + 0x72U, 0x6FU, 0x6CU, 0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, 0x00U, 0x02U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x0BU, 0x75U, 0x74U, 0x69U, 0x6CU, 0x5FU, + 0x6BU, 0x65U, 0x79U, 0x6CU, 0x65U, 0x74U, 0x00U, 0x03U, 0x03U, 0x65U, + 0x6EU, 0x76U, 0x08U, 0x73U, 0x6CU, 0x6FU, 0x74U, 0x5FU, 0x73U, 0x65U, + 0x74U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0DU, 0x73U, 0x6CU, + 0x6FU, 0x74U, 0x5FU, 0x73U, 0x75U, 0x62U, 0x66U, 0x69U, 0x65U, 0x6CU, + 0x64U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x04U, 0x73U, 0x6CU, + 0x6FU, 0x74U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x09U, 0x73U, + 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x00U, 0x05U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, + 0x74U, 0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x06U, 0x05U, 0x03U, 0x01U, + 0x00U, 0x02U, 0x06U, 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0xC0U, 0x8BU, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xBDU, 0x0BU, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xC0U, 0x8BU, 0x04U, + 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, + 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x09U, 0x0AU, 0x81U, 0x84U, + 0x00U, 0x01U, 0xFDU, 0x83U, 0x00U, 0x02U, 0x01U, 0x7FU, 0x01U, 0x7EU, + 0x23U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6BU, + 0x22U, 0x01U, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, + 0x41U, 0x01U, 0x10U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, + 0x40U, 0x20U, 0x01U, 0x41U, 0x30U, 0x6AU, 0x41U, 0x14U, 0x10U, 0x81U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x14U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x21U, 0x42U, 0x22U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x20U, + 0x01U, 0x41U, 0x22U, 0x41U, 0x03U, 0x20U, 0x01U, 0x41U, 0x30U, 0x6AU, + 0x41U, 0x14U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, + 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x22U, 0x51U, 0x0DU, + 0x00U, 0x41U, 0xA1U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0xCDU, 0x00U, + 0x42U, 0x25U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, + 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0x22U, 0x41U, 0x01U, 0x10U, 0x84U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x01U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0xEEU, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x25U, 0x42U, 0x27U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x01U, 0x41U, + 0x95U, 0x80U, 0x04U, 0x41U, 0x02U, 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x02U, + 0x10U, 0x86U, 0x80U, 0x80U, 0x80U, 0x00U, 0x22U, 0x02U, 0x42U, 0x05U, + 0x52U, 0x0DU, 0x00U, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x80U, 0x02U, + 0x41U, 0x93U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, 0x02U, 0x51U, 0x0DU, 0x00U, + 0x41U, 0x99U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x28U, 0x42U, 0x2CU, + 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, + 0x41U, 0x00U, 0x41U, 0x80U, 0x04U, 0x41U, 0xC1U, 0x89U, 0x80U, 0x80U, + 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, + 0x80U, 0x04U, 0x51U, 0x0DU, 0x00U, 0x41U, 0xC7U, 0x89U, 0x80U, 0x80U, + 0x00U, 0x41U, 0x2CU, 0x42U, 0x2DU, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x80U, 0x06U, + 0x41U, 0xF3U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, 0x06U, 0x51U, 0x0DU, 0x00U, + 0x41U, 0xF9U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x2CU, 0x42U, 0x2EU, + 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, + 0x41U, 0x00U, 0x41U, 0x80U, 0x08U, 0x41U, 0xA5U, 0x8AU, 0x80U, 0x80U, + 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, + 0x80U, 0x08U, 0x51U, 0x0DU, 0x00U, 0x41U, 0xABU, 0x8AU, 0x80U, 0x80U, + 0x00U, 0x41U, 0x2CU, 0x42U, 0x2FU, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x80U, 0x0AU, + 0x41U, 0xD7U, 0x8AU, 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, 0x0AU, 0x51U, 0x0DU, 0x00U, + 0x41U, 0xDDU, 0x8AU, 0x80U, 0x80U, 0x00U, 0x41U, 0x2CU, 0x42U, 0x30U, + 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, + 0x41U, 0x00U, 0x41U, 0x81U, 0x0AU, 0x41U, 0x89U, 0x8BU, 0x80U, 0x80U, + 0x00U, 0x41U, 0x05U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, + 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x8EU, 0x8BU, 0x80U, 0x80U, 0x00U, + 0x41U, 0x2FU, 0x42U, 0x31U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x05U, 0x10U, 0x88U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, + 0x20U, 0x02U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, + 0x01U, 0x41U, 0xD0U, 0x00U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x20U, 0x02U, 0x0BU, 0x0BU, 0xC5U, 0x03U, 0x01U, 0x00U, 0x41U, + 0x80U, 0x08U, 0x0BU, 0xBDU, 0x03U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x5FU, + 0x61U, 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x28U, 0x68U, 0x6FU, + 0x6FU, 0x6BU, 0x5FU, 0x61U, 0x63U, 0x63U, 0x2CU, 0x20U, 0x32U, 0x30U, + 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x30U, 0x00U, 0x75U, 0x74U, + 0x69U, 0x6CU, 0x5FU, 0x6BU, 0x65U, 0x79U, 0x6CU, 0x65U, 0x74U, 0x28U, + 0x61U, 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x5FU, 0x6BU, 0x65U, + 0x79U, 0x6CU, 0x65U, 0x74U, 0x2CU, 0x20U, 0x33U, 0x34U, 0x2CU, 0x20U, + 0x4BU, 0x45U, 0x59U, 0x4CU, 0x45U, 0x54U, 0x5FU, 0x41U, 0x43U, 0x43U, + 0x4FU, 0x55U, 0x4EU, 0x54U, 0x2CU, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, + 0x5FU, 0x61U, 0x63U, 0x63U, 0x2CU, 0x20U, 0x32U, 0x30U, 0x2CU, 0x20U, + 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x33U, 0x34U, 0x00U, 0x73U, 0x6CU, 0x6FU, 0x74U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x61U, 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, + 0x74U, 0x5FU, 0x6BU, 0x65U, 0x79U, 0x6CU, 0x65U, 0x74U, 0x2CU, 0x20U, + 0x33U, 0x34U, 0x2CU, 0x20U, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, + 0x31U, 0x00U, 0x74U, 0x65U, 0x73U, 0x74U, 0x31U, 0x00U, 0x73U, 0x74U, + 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, + 0x20U, 0x32U, 0x35U, 0x36U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, + 0x28U, 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, 0x31U, 0x22U, 0x29U, 0x29U, + 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x00U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x32U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x2AU, 0x32U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, + 0x74U, 0x65U, 0x73U, 0x74U, 0x32U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x32U, 0x00U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x33U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x2AU, 0x33U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, + 0x74U, 0x65U, 0x73U, 0x74U, 0x33U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x33U, 0x00U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x34U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x2AU, 0x34U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, + 0x74U, 0x65U, 0x73U, 0x74U, 0x34U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x34U, 0x00U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x35U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x2AU, 0x35U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, + 0x74U, 0x65U, 0x73U, 0x74U, 0x35U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x35U, 0x00U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, + 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, + 0x35U, 0x2BU, 0x31U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, + 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, 0x49U, 0x47U, 0x00U, + }}, + + /* ==== WASM: 1 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i64))) @@ -59,7 +240,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 1 ==== */ + /* ==== WASM: 2 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i64))) @@ -113,7 +294,7 @@ std::map> wasm = { 0x14U, 0x10U, 0x00U, 0x1AU, 0x0CU, 0x00U, 0x0BU, 0x0BU, }}, - /* ==== WASM: 2 ==== */ + /* ==== WASM: 3 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -180,7 +361,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x20U, 0x02U, 0x0BU, }}, - /* ==== WASM: 3 ==== */ + /* ==== WASM: 4 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -286,7 +467,7 @@ std::map> wasm = { 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x03U, 0x0BU, }}, - /* ==== WASM: 4 ==== */ + /* ==== WASM: 5 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -361,7 +542,7 @@ std::map> wasm = { 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x05U, 0x0BU, }}, - /* ==== WASM: 5 ==== */ + /* ==== WASM: 6 ==== */ {R"[test.hook]( #include extern int32_t _g(uint32_t, uint32_t); @@ -978,7 +1159,7 @@ std::map> wasm = { 0x78U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 6 ==== */ + /* ==== WASM: 7 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1083,7 +1264,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 7 ==== */ + /* ==== WASM: 8 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1180,7 +1361,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 8 ==== */ + /* ==== WASM: 9 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1303,7 +1484,7 @@ std::map> wasm = { 0x4EU, 0x59U, 0x5FU, 0x4EU, 0x4FU, 0x4EU, 0x43U, 0x45U, 0x53U, 0x00U, }}, - /* ==== WASM: 9 ==== */ + /* ==== WASM: 10 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1383,7 +1564,7 @@ std::map> wasm = { 0x54U, 0x00U, }}, - /* ==== WASM: 10 ==== */ + /* ==== WASM: 11 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1428,7 +1609,7 @@ std::map> wasm = { 0x30U, 0x00U, }}, - /* ==== WASM: 11 ==== */ + /* ==== WASM: 12 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -1747,7 +1928,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 12 ==== */ + /* ==== WASM: 13 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -2533,7 +2714,7 @@ std::map> wasm = { 0x37U, 0x36U, 0x33U, 0x4CU, 0x4CU, 0x20U, 0x29U, 0x00U, }}, - /* ==== WASM: 13 ==== */ + /* ==== WASM: 14 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -2923,7 +3104,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 14 ==== */ + /* ==== WASM: 15 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3104,7 +3285,7 @@ std::map> wasm = { 0x38U, 0x4CU, 0x4CU, 0x29U, 0x00U, }}, - /* ==== WASM: 15 ==== */ + /* ==== WASM: 16 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3293,7 +3474,7 @@ std::map> wasm = { 0x29U, 0x00U, }}, - /* ==== WASM: 16 ==== */ + /* ==== WASM: 17 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -3532,7 +3713,7 @@ std::map> wasm = { 0x00U, 0x42U, 0x00U, 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 17 ==== */ + /* ==== WASM: 18 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -4234,7 +4415,7 @@ std::map> wasm = { 0x38U, 0x35U, 0x35U, 0x32U, 0x55U, 0x29U, 0x00U, }}, - /* ==== WASM: 18 ==== */ + /* ==== WASM: 19 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5579,7 +5760,7 @@ std::map> wasm = { 0x20U, 0x29U, 0x00U, }}, - /* ==== WASM: 19 ==== */ + /* ==== WASM: 20 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5681,7 +5862,7 @@ std::map> wasm = { 0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 20 ==== */ + /* ==== WASM: 21 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5724,7 +5905,7 @@ std::map> wasm = { 0x00U, 0x0BU, }}, - /* ==== WASM: 21 ==== */ + /* ==== WASM: 22 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -5872,7 +6053,7 @@ std::map> wasm = { 0x34U, 0x34U, 0x4CU, 0x4CU, 0x2CU, 0x20U, 0x33U, 0x29U, 0x00U, }}, - /* ==== WASM: 22 ==== */ + /* ==== WASM: 23 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -6200,7 +6381,7 @@ std::map> wasm = { 0x38U, 0x34U, 0x39U, 0x30U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 23 ==== */ + /* ==== WASM: 24 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -6405,7 +6586,7 @@ std::map> wasm = { 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 24 ==== */ + /* ==== WASM: 25 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -7089,7 +7270,7 @@ std::map> wasm = { 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 25 ==== */ + /* ==== WASM: 26 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -7384,7 +7565,7 @@ std::map> wasm = { 0x32U, 0x34U, 0x31U, 0x36U, 0x55U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 26 ==== */ + /* ==== WASM: 27 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8097,7 +8278,7 @@ std::map> wasm = { 0x31U, 0x33U, 0x33U, 0x38U, 0x20U, 0x29U, 0x00U, }}, - /* ==== WASM: 27 ==== */ + /* ==== WASM: 28 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8182,7 +8363,7 @@ std::map> wasm = { 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x30U, 0x00U, }}, - /* ==== WASM: 28 ==== */ + /* ==== WASM: 29 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8244,7 +8425,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x0BU, }}, - /* ==== WASM: 29 ==== */ + /* ==== WASM: 30 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8321,7 +8502,7 @@ std::map> wasm = { 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 30 ==== */ + /* ==== WASM: 31 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8398,7 +8579,7 @@ std::map> wasm = { 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 31 ==== */ + /* ==== WASM: 32 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8655,7 +8836,7 @@ std::map> wasm = { 0x00U, 0x00U, }}, - /* ==== WASM: 32 ==== */ + /* ==== WASM: 33 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -8813,7 +8994,7 @@ std::map> wasm = { 0x04U, 0x00U, 0x00U, }}, - /* ==== WASM: 33 ==== */ + /* ==== WASM: 34 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9166,7 +9347,7 @@ std::map> wasm = { 0x00U, 0x2AU, 0x04U, 0x00U, 0x00U, 0x31U, 0x04U, 0x00U, 0x00U, }}, - /* ==== WASM: 34 ==== */ + /* ==== WASM: 35 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9199,7 +9380,7 @@ std::map> wasm = { 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU, }}, - /* ==== WASM: 35 ==== */ + /* ==== WASM: 36 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9426,7 +9607,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 36 ==== */ + /* ==== WASM: 37 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9457,7 +9638,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU, }}, - /* ==== WASM: 37 ==== */ + /* ==== WASM: 38 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9768,7 +9949,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 38 ==== */ + /* ==== WASM: 39 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9845,7 +10026,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 39 ==== */ + /* ==== WASM: 40 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9879,7 +10060,7 @@ std::map> wasm = { 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x0BU, }}, - /* ==== WASM: 40 ==== */ + /* ==== WASM: 41 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -9966,7 +10147,7 @@ std::map> wasm = { 0x32U, 0x00U, }}, - /* ==== WASM: 41 ==== */ + /* ==== WASM: 42 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10000,7 +10181,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 42 ==== */ + /* ==== WASM: 43 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10140,7 +10321,7 @@ std::map> wasm = { 0x54U, 0x5FU, 0x4DU, 0x45U, 0x54U, 0x00U, }}, - /* ==== WASM: 43 ==== */ + /* ==== WASM: 44 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10330,7 +10511,7 @@ std::map> wasm = { 0x31U, 0x34U, 0x00U, }}, - /* ==== WASM: 44 ==== */ + /* ==== WASM: 45 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10484,7 +10665,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 45 ==== */ + /* ==== WASM: 46 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10645,7 +10826,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 46 ==== */ + /* ==== WASM: 47 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10802,7 +10983,7 @@ std::map> wasm = { 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U, }}, - /* ==== WASM: 47 ==== */ + /* ==== WASM: 48 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -10887,7 +11068,7 @@ std::map> wasm = { 0x74U, 0x79U, 0x70U, 0x65U, 0x28U, 0x29U, 0x00U, }}, - /* ==== WASM: 48 ==== */ + /* ==== WASM: 49 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11144,7 +11325,7 @@ std::map> wasm = { 0x00U, 0x00U, }}, - /* ==== WASM: 49 ==== */ + /* ==== WASM: 50 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11382,7 +11563,7 @@ std::map> wasm = { 0x3EU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 50 ==== */ + /* ==== WASM: 51 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11478,7 +11659,7 @@ std::map> wasm = { 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 51 ==== */ + /* ==== WASM: 52 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11588,7 +11769,7 @@ std::map> wasm = { 0x20U, 0x31U, 0x00U, }}, - /* ==== WASM: 52 ==== */ + /* ==== WASM: 53 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11718,7 +11899,7 @@ std::map> wasm = { 0x30U, 0x30U, 0x30U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 53 ==== */ + /* ==== WASM: 54 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -11992,7 +12173,7 @@ std::map> wasm = { 0x30U, 0x00U, }}, - /* ==== WASM: 54 ==== */ + /* ==== WASM: 55 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12129,7 +12310,7 @@ std::map> wasm = { 0x2CU, 0x20U, 0x73U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x31U, 0x00U, }}, - /* ==== WASM: 55 ==== */ + /* ==== WASM: 56 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12423,7 +12604,7 @@ std::map> wasm = { 0x5FU, 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U, }}, - /* ==== WASM: 56 ==== */ + /* ==== WASM: 57 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12657,7 +12838,7 @@ std::map> wasm = { 0x5FU, 0x53U, 0x4CU, 0x4FU, 0x54U, 0x53U, 0x00U, }}, - /* ==== WASM: 57 ==== */ + /* ==== WASM: 58 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -12953,7 +13134,7 @@ std::map> wasm = { 0x2CU, 0x20U, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 58 ==== */ + /* ==== WASM: 59 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13157,7 +13338,7 @@ std::map> wasm = { 0x6EU, 0x74U, 0x32U, 0x22U, 0x20U, 0x2BU, 0x20U, 0x69U, 0x29U, 0x00U, }}, - /* ==== WASM: 59 ==== */ + /* ==== WASM: 60 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13274,7 +13455,7 @@ std::map> wasm = { 0x69U, 0x29U, 0x00U, }}, - /* ==== WASM: 60 ==== */ + /* ==== WASM: 61 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13383,7 +13564,7 @@ std::map> wasm = { 0x6EU, 0x74U, 0x65U, 0x6EU, 0x74U, 0x32U, 0x22U, 0x29U, 0x00U, }}, - /* ==== WASM: 61 ==== */ + /* ==== WASM: 62 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13656,7 +13837,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 62 ==== */ + /* ==== WASM: 63 ==== */ {R"[test.hook]( #include #define sfInvoiceID ((5U << 16U) + 17U) @@ -13875,7 +14056,7 @@ std::map> wasm = { 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 63 ==== */ + /* ==== WASM: 64 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -13987,7 +14168,7 @@ std::map> wasm = { 0x58U, 0x49U, 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 64 ==== */ + /* ==== WASM: 65 ==== */ {R"[test.hook]( #include #define sfInvoiceID ((5U << 16U) + 17U) @@ -14123,7 +14304,143 @@ std::map> wasm = { 0x3DU, 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 65 ==== */ + /* ==== WASM: 66 ==== */ + {R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set ( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len + ); + extern int64_t otxn_param(uint32_t, uint32_t, uint32_t, uint32_t); + + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + #define TOO_SMALL (-4) + #define TOO_BIG (-3) + #define OUT_OF_BOUNDS (-1) + + int64_t hook(uint32_t reserved) + { + _g(1,1); + + // bounds and buffer size checks + { + // RH NOTE: readptr/len 0/0 = delete entry + + ASSERT(state_set(0,0,0,0) == TOO_SMALL); + ASSERT(state_set(0,0,0,33) == TOO_BIG); + ASSERT(state_set(0,0,0,1000000) == TOO_BIG); + ASSERT(state_set(0,0,1000000,1) == OUT_OF_BOUNDS); + + ASSERT(state_set(0,1000000, 0, 32) == OUT_OF_BOUNDS); + ASSERT(state_set(1000000, 0, 0, 32) == OUT_OF_BOUNDS); + + uint16_t size; + ASSERT(otxn_param(&size, 2, "SIZE", 4) > 0); + ASSERT(state_set(0, size, 0, 32) == TOO_BIG); + } + accept(0,0,0); + } + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x1BU, + 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x04U, 0x7FU, + 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, + 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, 0x47U, 0x05U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x00U, 0x03U, + 0x65U, 0x6EU, 0x76U, 0x09U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x08U, + 0x72U, 0x6FU, 0x6CU, 0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, 0x00U, 0x02U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x0AU, 0x6FU, 0x74U, 0x78U, 0x6EU, 0x5FU, + 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, + 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, + 0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U, 0x00U, 0x02U, 0x06U, + 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0xC0U, 0x8AU, 0x04U, 0x0BU, 0x7FU, + 0x00U, 0x41U, 0xB6U, 0x0AU, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, + 0x0BU, 0x7FU, 0x00U, 0x41U, 0xC0U, 0x8AU, 0x04U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, + 0x6FU, 0x6BU, 0x00U, 0x05U, 0x0AU, 0x8AU, 0x83U, 0x00U, 0x01U, 0x86U, + 0x83U, 0x00U, 0x02U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x23U, 0x80U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x41U, 0x10U, 0x6BU, 0x22U, 0x01U, 0x24U, 0x80U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x80U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, + 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x42U, 0x7CU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x80U, 0x88U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x20U, 0x42U, 0x1DU, 0x10U, 0x82U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, + 0x41U, 0x00U, 0x41U, 0x21U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x42U, 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xA0U, 0x88U, 0x80U, 0x80U, + 0x00U, 0x41U, 0x1FU, 0x42U, 0x1EU, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, + 0x00U, 0x41U, 0xC0U, 0x84U, 0x3DU, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x42U, 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xBFU, 0x88U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x24U, 0x42U, 0x1FU, 0x10U, 0x82U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, + 0x41U, 0xC0U, 0x84U, 0x3DU, 0x41U, 0x01U, 0x10U, 0x81U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xE3U, 0x88U, + 0x80U, 0x80U, 0x00U, 0x41U, 0x2AU, 0x42U, 0x20U, 0x10U, 0x82U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, + 0xC0U, 0x84U, 0x3DU, 0x41U, 0x00U, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x8DU, + 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x2DU, 0x42U, 0x22U, 0x10U, 0x82U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0xC0U, + 0x84U, 0x3DU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x20U, 0x10U, 0x81U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, + 0xBAU, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x2EU, 0x42U, 0x23U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x20U, + 0x01U, 0x41U, 0x0EU, 0x6AU, 0x41U, 0x02U, 0x41U, 0xE8U, 0x89U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x04U, 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x42U, 0x00U, 0x55U, 0x0DU, 0x00U, 0x41U, 0xEDU, 0x89U, 0x80U, 0x80U, + 0x00U, 0x41U, 0x24U, 0x42U, 0x26U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x20U, 0x01U, 0x2FU, + 0x01U, 0x0EU, 0x41U, 0x00U, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x42U, 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x91U, 0x8AU, + 0x80U, 0x80U, 0x00U, 0x41U, 0x25U, 0x42U, 0x27U, 0x10U, 0x82U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, + 0x00U, 0x10U, 0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, + 0x41U, 0x10U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, + 0x02U, 0x0BU, 0x0BU, 0xBEU, 0x02U, 0x01U, 0x00U, 0x41U, 0x80U, 0x08U, + 0x0BU, 0xB6U, 0x02U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, + 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, + 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x53U, + 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, + 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, + 0x2CU, 0x33U, 0x33U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, + 0x4FU, 0x5FU, 0x42U, 0x49U, 0x47U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, + 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x30U, 0x2CU, + 0x30U, 0x2CU, 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x29U, + 0x20U, 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, 0x49U, + 0x47U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, + 0x74U, 0x28U, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x31U, 0x30U, 0x30U, 0x30U, + 0x30U, 0x30U, 0x30U, 0x2CU, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, + 0x4FU, 0x55U, 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, + 0x4EU, 0x44U, 0x53U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x31U, 0x30U, 0x30U, 0x30U, + 0x30U, 0x30U, 0x30U, 0x2CU, 0x20U, 0x30U, 0x2CU, 0x20U, 0x33U, 0x32U, + 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x4FU, 0x55U, 0x54U, 0x5FU, 0x4FU, + 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, 0x73U, + 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x31U, + 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x2CU, 0x20U, 0x30U, 0x2CU, + 0x20U, 0x30U, 0x2CU, 0x20U, 0x33U, 0x32U, 0x29U, 0x20U, 0x3DU, 0x3DU, + 0x20U, 0x4FU, 0x55U, 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, + 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, 0x53U, 0x49U, 0x5AU, 0x45U, 0x00U, + 0x6FU, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU, + 0x28U, 0x26U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x2CU, 0x20U, 0x32U, 0x2CU, + 0x20U, 0x22U, 0x53U, 0x49U, 0x5AU, 0x45U, 0x22U, 0x2CU, 0x20U, 0x34U, + 0x29U, 0x20U, 0x3EU, 0x20U, 0x30U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, + 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x73U, + 0x69U, 0x7AU, 0x65U, 0x2CU, 0x20U, 0x30U, 0x2CU, 0x20U, 0x33U, 0x32U, + 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, + 0x49U, 0x47U, 0x00U, + }}, + + /* ==== WASM: 67 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14157,32 +14474,12 @@ std::map> wasm = { #define ASSERT(x)\ if (!(x))\ rollback((uint32_t)#x, sizeof(#x), __LINE__); - #define TOO_SMALL (-4) - #define TOO_BIG (-3) - #define OUT_OF_BOUNDS (-1) #define SBUF(x) (uint32_t)(x), sizeof(x) - int64_t hook(uint32_t reserved ) + int64_t hook(uint32_t reserved) { _g(1,1); - - // bounds and buffer size checks - { - // RH NOTE: readptr/len 0/0 = delete entry - - ASSERT(state_set(0,0,0,0) == TOO_SMALL); - ASSERT(state_set(0,0,0,33) == TOO_BIG); - ASSERT(state_set(0,0,0,1000000) == TOO_BIG); - ASSERT(state_set(0,0,1000000,1) == OUT_OF_BOUNDS); - - ASSERT(state_set(0,1000000, 0, 32) == OUT_OF_BOUNDS); - ASSERT(state_set(1000000, 0, 0, 32) == OUT_OF_BOUNDS); - - ASSERT(state_set(0, 257, 0, 32) == TOO_BIG); - } - - // create state 1 { uint8_t key[32] = @@ -14193,27 +14490,24 @@ std::map> wasm = { 0,0,0,0,0,0,0,0 }; - uint8_t data[4] = + uint8_t data[4] = { 0xCAU,0xFEU,0xBAU,0xBEU }; - ASSERT(state_set(SBUF(data), SBUF(key)) == sizeof(data)); } - // create state 2 + // create state 2 { uint8_t key[3] = { 1,2,3 }; - ASSERT(state_set(SBUF(data2), SBUF(key)) == sizeof(data2)); } - accept(0,0,0); } @@ -14229,119 +14523,63 @@ std::map> wasm = { 0x72U, 0x6FU, 0x6CU, 0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, 0x00U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U, - 0x00U, 0x02U, 0x06U, 0x27U, 0x06U, 0x7FU, 0x01U, 0x41U, 0x80U, 0x8CU, - 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xF3U, 0x0BU, 0x0BU, 0x7FU, 0x00U, - 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x8CU, 0x04U, + 0x00U, 0x02U, 0x06U, 0x27U, 0x06U, 0x7FU, 0x01U, 0x41U, 0xF0U, 0x89U, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xE7U, 0x09U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xF0U, 0x89U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, - 0x6BU, 0x00U, 0x04U, 0x0AU, 0x85U, 0x84U, 0x00U, 0x01U, 0x81U, 0x84U, + 0x6BU, 0x00U, 0x04U, 0x0AU, 0xEAU, 0x81U, 0x00U, 0x01U, 0xE6U, 0x81U, 0x00U, 0x02U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x23U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x30U, 0x6BU, 0x22U, 0x01U, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x80U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, - 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, - 0x42U, 0x7CU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x80U, 0x89U, 0x80U, 0x80U, - 0x00U, 0x41U, 0x20U, 0x42U, 0x30U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, - 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, - 0x00U, 0x41U, 0x21U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, - 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xA0U, 0x89U, 0x80U, 0x80U, 0x00U, - 0x41U, 0x1FU, 0x42U, 0x31U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, - 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, - 0x41U, 0xC0U, 0x84U, 0x3DU, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, - 0x42U, 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xBFU, 0x89U, 0x80U, 0x80U, - 0x00U, 0x41U, 0x24U, 0x42U, 0x32U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, - 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, - 0xC0U, 0x84U, 0x3DU, 0x41U, 0x01U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, - 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xE3U, 0x89U, 0x80U, - 0x80U, 0x00U, 0x41U, 0x2AU, 0x42U, 0x33U, 0x10U, 0x82U, 0x80U, 0x80U, - 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0xC0U, - 0x84U, 0x3DU, 0x41U, 0x00U, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, 0x80U, - 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x8DU, 0x8AU, - 0x80U, 0x80U, 0x00U, 0x41U, 0x2DU, 0x42U, 0x35U, 0x10U, 0x82U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0xC0U, 0x84U, - 0x3DU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xBAU, - 0x8AU, 0x80U, 0x80U, 0x00U, 0x41U, 0x2EU, 0x42U, 0x36U, 0x10U, 0x82U, - 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, - 0x41U, 0x81U, 0x02U, 0x41U, 0x00U, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x42U, 0x7DU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xE8U, - 0x8AU, 0x80U, 0x80U, 0x00U, 0x41U, 0x24U, 0x42U, 0x38U, 0x10U, 0x82U, - 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x20U, 0x01U, 0x41U, 0x28U, - 0x6AU, 0x42U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x20U, - 0x6AU, 0x42U, 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x42U, 0x00U, - 0x37U, 0x03U, 0x18U, 0x20U, 0x01U, 0x42U, 0x00U, 0x37U, 0x03U, 0x10U, - 0x20U, 0x01U, 0x41U, 0xCAU, 0xFDU, 0xEBU, 0xF5U, 0x7BU, 0x36U, 0x02U, - 0x0CU, 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0x0CU, 0x6AU, 0x41U, 0x04U, - 0x20U, 0x01U, 0x41U, 0x10U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x42U, 0x04U, 0x51U, 0x0DU, 0x00U, 0x41U, 0x8CU, - 0x8BU, 0x80U, 0x80U, 0x00U, 0x41U, 0x31U, 0x42U, 0xCCU, 0x00U, 0x10U, - 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x20U, 0x01U, 0x41U, - 0x12U, 0x6AU, 0x41U, 0x00U, 0x2DU, 0x00U, 0xBFU, 0x8BU, 0x80U, 0x80U, - 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x01U, 0x41U, 0x00U, 0x2FU, 0x00U, - 0xBDU, 0x8BU, 0x80U, 0x80U, 0x00U, 0x3BU, 0x01U, 0x10U, 0x02U, 0x40U, - 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x80U, 0x01U, 0x20U, - 0x01U, 0x41U, 0x10U, 0x6AU, 0x41U, 0x03U, 0x10U, 0x81U, 0x80U, 0x80U, - 0x80U, 0x00U, 0x42U, 0x80U, 0x01U, 0x51U, 0x0DU, 0x00U, 0x41U, 0xC0U, - 0x8BU, 0x80U, 0x80U, 0x00U, 0x41U, 0x33U, 0x42U, 0xD7U, 0x00U, 0x10U, - 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, - 0x00U, 0x42U, 0x00U, 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, - 0x20U, 0x01U, 0x41U, 0x30U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, - 0x00U, 0x20U, 0x02U, 0x0BU, 0x0BU, 0x82U, 0x04U, 0x02U, 0x00U, 0x41U, - 0x80U, 0x08U, 0x0BU, 0x80U, 0x01U, 0x23U, 0x13U, 0x96U, 0x68U, 0x78U, - 0xDCU, 0xABU, 0xC4U, 0x40U, 0x26U, 0x07U, 0x2BU, 0xA3U, 0xD2U, 0x0CU, - 0x69U, 0x40U, 0xDDU, 0xCDU, 0xE7U, 0x38U, 0x9BU, 0x0BU, 0xA9U, 0x6CU, - 0x3CU, 0xB3U, 0x87U, 0x37U, 0x02U, 0x81U, 0xE8U, 0x2BU, 0xDDU, 0x5DU, - 0xBBU, 0x40U, 0xD9U, 0x66U, 0x96U, 0x6FU, 0xC1U, 0x6BU, 0xE8U, 0xD4U, - 0x7CU, 0x7BU, 0x62U, 0x14U, 0x4CU, 0xD1U, 0x4BU, 0xAAU, 0x99U, 0x36U, - 0x75U, 0xE9U, 0x22U, 0xADU, 0x0FU, 0x5FU, 0x94U, 0x1DU, 0x86U, 0xEBU, - 0xA8U, 0x13U, 0x99U, 0xF9U, 0x98U, 0xFFU, 0xCAU, 0x5BU, 0x86U, 0x2FU, - 0xDFU, 0x67U, 0x8FU, 0xE2U, 0xE3U, 0xC3U, 0x37U, 0xCCU, 0x47U, 0x0FU, - 0x33U, 0x88U, 0xB0U, 0x33U, 0x3BU, 0x02U, 0x55U, 0x67U, 0x16U, 0xA4U, - 0xFBU, 0x8EU, 0x85U, 0x6FU, 0xD8U, 0x84U, 0x16U, 0xA3U, 0x54U, 0x18U, - 0x34U, 0x06U, 0x0EU, 0xF6U, 0x65U, 0x34U, 0x05U, 0x26U, 0x7EU, 0x05U, - 0x74U, 0xDAU, 0x09U, 0xBFU, 0x55U, 0x8CU, 0x75U, 0x92U, 0xACU, 0x33U, - 0xFBU, 0x01U, 0x8DU, 0x00U, 0x41U, 0x80U, 0x09U, 0x0BU, 0xF3U, 0x02U, - 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, - 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x29U, 0x20U, 0x3DU, - 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, - 0x4CU, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, - 0x74U, 0x28U, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x33U, 0x33U, - 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, - 0x49U, 0x47U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, - 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x31U, - 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, - 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, 0x49U, 0x47U, 0x00U, 0x73U, - 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, - 0x2CU, 0x30U, 0x2CU, 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, - 0x2CU, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x4FU, 0x55U, 0x54U, - 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, - 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, - 0x28U, 0x30U, 0x2CU, 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, - 0x2CU, 0x20U, 0x30U, 0x2CU, 0x20U, 0x33U, 0x32U, 0x29U, 0x20U, 0x3DU, - 0x3DU, 0x20U, 0x4FU, 0x55U, 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, - 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, - 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x31U, 0x30U, 0x30U, 0x30U, - 0x30U, 0x30U, 0x30U, 0x2CU, 0x20U, 0x30U, 0x2CU, 0x20U, 0x30U, 0x2CU, - 0x20U, 0x33U, 0x32U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x4FU, 0x55U, - 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, - 0x53U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, - 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x37U, 0x2CU, 0x20U, - 0x30U, 0x2CU, 0x20U, 0x33U, 0x32U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, - 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, 0x49U, 0x47U, 0x00U, 0x73U, 0x74U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x41U, 0x28U, 0x6AU, 0x42U, + 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x41U, 0x20U, 0x6AU, 0x42U, + 0x00U, 0x37U, 0x03U, 0x00U, 0x20U, 0x01U, 0x42U, 0x00U, 0x37U, 0x03U, + 0x18U, 0x20U, 0x01U, 0x42U, 0x00U, 0x37U, 0x03U, 0x10U, 0x20U, 0x01U, + 0x41U, 0xCAU, 0xFDU, 0xEBU, 0xF5U, 0x7BU, 0x36U, 0x02U, 0x0CU, 0x02U, + 0x40U, 0x20U, 0x01U, 0x41U, 0x0CU, 0x6AU, 0x41U, 0x04U, 0x20U, 0x01U, + 0x41U, 0x10U, 0x6AU, 0x41U, 0x20U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x42U, 0x04U, 0x51U, 0x0DU, 0x00U, 0x41U, 0x80U, 0x89U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x31U, 0x42U, 0x37U, 0x10U, 0x82U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x1AU, 0x0BU, 0x20U, 0x01U, 0x41U, 0x12U, 0x6AU, 0x41U, + 0x00U, 0x2DU, 0x00U, 0xB3U, 0x89U, 0x80U, 0x80U, 0x00U, 0x3AU, 0x00U, + 0x00U, 0x20U, 0x01U, 0x41U, 0x00U, 0x2FU, 0x00U, 0xB1U, 0x89U, 0x80U, + 0x80U, 0x00U, 0x3BU, 0x01U, 0x10U, 0x02U, 0x40U, 0x41U, 0x80U, 0x88U, + 0x80U, 0x80U, 0x00U, 0x41U, 0x80U, 0x01U, 0x20U, 0x01U, 0x41U, 0x10U, + 0x6AU, 0x41U, 0x03U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, + 0x80U, 0x01U, 0x51U, 0x0DU, 0x00U, 0x41U, 0xB4U, 0x89U, 0x80U, 0x80U, + 0x00U, 0x41U, 0x33U, 0x42U, 0xC1U, 0x00U, 0x10U, 0x82U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, + 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, 0x41U, + 0x30U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x20U, 0x02U, + 0x0BU, 0x0BU, 0xF5U, 0x01U, 0x02U, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, + 0x80U, 0x01U, 0x23U, 0x13U, 0x96U, 0x68U, 0x78U, 0xDCU, 0xABU, 0xC4U, + 0x40U, 0x26U, 0x07U, 0x2BU, 0xA3U, 0xD2U, 0x0CU, 0x69U, 0x40U, 0xDDU, + 0xCDU, 0xE7U, 0x38U, 0x9BU, 0x0BU, 0xA9U, 0x6CU, 0x3CU, 0xB3U, 0x87U, + 0x37U, 0x02U, 0x81U, 0xE8U, 0x2BU, 0xDDU, 0x5DU, 0xBBU, 0x40U, 0xD9U, + 0x66U, 0x96U, 0x6FU, 0xC1U, 0x6BU, 0xE8U, 0xD4U, 0x7CU, 0x7BU, 0x62U, + 0x14U, 0x4CU, 0xD1U, 0x4BU, 0xAAU, 0x99U, 0x36U, 0x75U, 0xE9U, 0x22U, + 0xADU, 0x0FU, 0x5FU, 0x94U, 0x1DU, 0x86U, 0xEBU, 0xA8U, 0x13U, 0x99U, + 0xF9U, 0x98U, 0xFFU, 0xCAU, 0x5BU, 0x86U, 0x2FU, 0xDFU, 0x67U, 0x8FU, + 0xE2U, 0xE3U, 0xC3U, 0x37U, 0xCCU, 0x47U, 0x0FU, 0x33U, 0x88U, 0xB0U, + 0x33U, 0x3BU, 0x02U, 0x55U, 0x67U, 0x16U, 0xA4U, 0xFBU, 0x8EU, 0x85U, + 0x6FU, 0xD8U, 0x84U, 0x16U, 0xA3U, 0x54U, 0x18U, 0x34U, 0x06U, 0x0EU, + 0xF6U, 0x65U, 0x34U, 0x05U, 0x26U, 0x7EU, 0x05U, 0x74U, 0xDAU, 0x09U, + 0xBFU, 0x55U, 0x8CU, 0x75U, 0x92U, 0xACU, 0x33U, 0xFBU, 0x01U, 0x8DU, + 0x00U, 0x41U, 0x80U, 0x09U, 0x0BU, 0x67U, 0x73U, 0x74U, 0x61U, 0x74U, + 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x53U, 0x42U, 0x55U, 0x46U, + 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x29U, 0x2CU, 0x20U, 0x53U, 0x42U, + 0x55U, 0x46U, 0x28U, 0x6BU, 0x65U, 0x79U, 0x29U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x6FU, 0x66U, 0x28U, 0x64U, + 0x61U, 0x74U, 0x61U, 0x29U, 0x00U, 0x01U, 0x02U, 0x03U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x53U, 0x42U, - 0x55U, 0x46U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x29U, 0x2CU, 0x20U, - 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x6BU, 0x65U, 0x79U, 0x29U, 0x29U, - 0x20U, 0x3DU, 0x3DU, 0x20U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x6FU, 0x66U, - 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x29U, 0x00U, 0x01U, 0x02U, 0x03U, - 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, - 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x32U, - 0x29U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x6BU, 0x65U, - 0x79U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x73U, 0x69U, 0x7AU, - 0x65U, 0x6FU, 0x66U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x32U, 0x29U, - 0x00U, + 0x55U, 0x46U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x32U, 0x29U, 0x2CU, + 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x6BU, 0x65U, 0x79U, 0x29U, + 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x6FU, + 0x66U, 0x28U, 0x64U, 0x61U, 0x74U, 0x61U, 0x32U, 0x29U, 0x00U, }}, - /* ==== WASM: 66 ==== */ + /* ==== WASM: 68 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14453,7 +14691,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 67 ==== */ + /* ==== WASM: 69 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14547,7 +14785,7 @@ std::map> wasm = { 0x61U, 0x64U, 0x5BU, 0x69U, 0x5DU, 0x00U, }}, - /* ==== WASM: 68 ==== */ + /* ==== WASM: 70 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14680,7 +14918,7 @@ std::map> wasm = { 0x64U, 0x5BU, 0x69U, 0x5DU, 0x00U, }}, - /* ==== WASM: 69 ==== */ + /* ==== WASM: 71 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -14768,7 +15006,7 @@ std::map> wasm = { 0x61U, 0x74U, 0x61U, 0x29U, 0x00U, }}, - /* ==== WASM: 70 ==== */ + /* ==== WASM: 72 ==== */ {R"[test.hook]( #include #define sfInvoiceID ((5U << 16U) + 17U) @@ -14879,7 +15117,326 @@ std::map> wasm = { 0x20U, 0x33U, 0x32U, 0x00U, }}, - /* ==== WASM: 71 ==== */ + /* ==== WASM: 73 ==== */ + {R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set (uint32_t read_ptr, uint32_t + read_len, uint32_t kread_ptr, uint32_t kread_len); + + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + extern int64_t slot_set(uint32_t, uint32_t, uint32_t); + extern int64_t slot_subfield(uint32_t, uint32_t, uint32_t); + extern int64_t slot(uint32_t, uint32_t, uint32_t); + extern int64_t hook_account(uint32_t, uint32_t); + extern int64_t util_keylet(uint32_t, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); + + #define SBUF(x) x, sizeof(x) + #define TOO_BIG -3 + #define DOESNT_EXIST -5 + #define KEYLET_ACCOUNT 3 + + #define sfHookStateScale ((1U << 16U) + 21U) + + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x,sizeof(#x),__LINE__) + int64_t hook(uint32_t reserved ) + { + _g(1,1); + + uint8_t hook_acc[20]; + ASSERT(hook_account(hook_acc, 20) == 20); + uint8_t account_keylet[34]; + ASSERT(util_keylet(account_keylet, 34, KEYLET_ACCOUNT, + hook_acc, 20, 0,0,0,0) == 34); + + ASSERT(slot_set(account_keylet, 34, 1) == 1); + slot_subfield(1, sfHookStateScale, 2); + int64_t scale = slot(0,0,2); + + if (scale == DOESNT_EXIST) { + ASSERT(state_set(0, 256, SBUF("test0")) == 256); + ASSERT(state_set(0, 257, SBUF("test")) == TOO_BIG); + accept(0,0,scale); + } + if (scale == 2) { + ASSERT(state_set(0, 256, SBUF("test1")) == 256); + ASSERT(state_set(0, 256*2, SBUF("test2")) == 256*2); + ASSERT(state_set(0, 256*2+1, SBUF("test")) == + TOO_BIG); accept(0,0,scale); + } + if (scale == 5) { + ASSERT(state_set(0, 256, SBUF("test3")) == 256); + ASSERT(state_set(0, 256*5, SBUF("test4")) == 256*5); + ASSERT(state_set(0, 256*5+1, SBUF("test")) == + TOO_BIG); accept(0,0,scale); + } + rollback(0,0,scale); + } + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x35U, + 0x07U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x02U, 0x7FU, + 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, + 0x60U, 0x09U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, + 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, + 0x60U, 0x04U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x01U, + 0x7FU, 0x01U, 0x7EU, 0x02U, 0x89U, 0x01U, 0x09U, 0x03U, 0x65U, 0x6EU, + 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, + 0x0CU, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x5FU, 0x61U, 0x63U, 0x63U, 0x6FU, + 0x75U, 0x6EU, 0x74U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x08U, + 0x72U, 0x6FU, 0x6CU, 0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, 0x00U, 0x02U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x0BU, 0x75U, 0x74U, 0x69U, 0x6CU, 0x5FU, + 0x6BU, 0x65U, 0x79U, 0x6CU, 0x65U, 0x74U, 0x00U, 0x03U, 0x03U, 0x65U, + 0x6EU, 0x76U, 0x08U, 0x73U, 0x6CU, 0x6FU, 0x74U, 0x5FU, 0x73U, 0x65U, + 0x74U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0DU, 0x73U, 0x6CU, + 0x6FU, 0x74U, 0x5FU, 0x73U, 0x75U, 0x62U, 0x66U, 0x69U, 0x65U, 0x6CU, + 0x64U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x04U, 0x73U, 0x6CU, + 0x6FU, 0x74U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x09U, 0x73U, + 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x00U, 0x05U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, + 0x74U, 0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x06U, 0x05U, 0x03U, 0x01U, + 0x00U, 0x02U, 0x06U, 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0x90U, 0x8CU, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x8FU, 0x0CU, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x90U, 0x8CU, 0x04U, + 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, + 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x09U, 0x0AU, 0x82U, 0x85U, + 0x00U, 0x01U, 0xFEU, 0x84U, 0x00U, 0x02U, 0x01U, 0x7FU, 0x02U, 0x7EU, + 0x23U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0xD0U, 0x00U, 0x6BU, + 0x22U, 0x01U, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, + 0x41U, 0x01U, 0x10U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, + 0x40U, 0x20U, 0x01U, 0x41U, 0x30U, 0x6AU, 0x41U, 0x14U, 0x10U, 0x81U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x14U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x21U, 0x42U, 0x22U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x20U, + 0x01U, 0x41U, 0x22U, 0x41U, 0x03U, 0x20U, 0x01U, 0x41U, 0x30U, 0x6AU, + 0x41U, 0x14U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x00U, + 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x22U, 0x51U, 0x0DU, + 0x00U, 0x41U, 0xA1U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0xCDU, 0x00U, + 0x42U, 0x25U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, + 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0x22U, 0x41U, 0x01U, 0x10U, 0x84U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x01U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0xEEU, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x25U, 0x42U, 0x27U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x01U, 0x41U, + 0x95U, 0x80U, 0x04U, 0x41U, 0x02U, 0x10U, 0x85U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x02U, + 0x10U, 0x86U, 0x80U, 0x80U, 0x80U, 0x00U, 0x22U, 0x02U, 0x42U, 0x05U, + 0x7CU, 0x22U, 0x03U, 0x42U, 0x0AU, 0x56U, 0x0DU, 0x00U, 0x02U, 0x40U, + 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x20U, 0x03U, 0xA7U, 0x0EU, + 0x0BU, 0x00U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x04U, 0x01U, 0x04U, + 0x04U, 0x02U, 0x00U, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x80U, + 0x02U, 0x41U, 0x93U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, 0x10U, + 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, 0x02U, 0x51U, 0x0DU, + 0x00U, 0x41U, 0x99U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x28U, 0x42U, + 0x2CU, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x42U, + 0x7BU, 0x21U, 0x03U, 0x41U, 0x00U, 0x41U, 0x81U, 0x02U, 0x41U, 0xC1U, + 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x05U, 0x10U, 0x87U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x42U, 0x7DU, 0x51U, 0x0DU, 0x02U, 0x41U, 0xC6U, 0x89U, + 0x80U, 0x80U, 0x00U, 0x41U, 0x2BU, 0x42U, 0x2DU, 0x10U, 0x82U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x0CU, 0x02U, 0x0BU, 0x02U, 0x40U, 0x41U, + 0x00U, 0x41U, 0x80U, 0x02U, 0x41U, 0xF1U, 0x89U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x06U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, + 0x02U, 0x51U, 0x0DU, 0x00U, 0x41U, 0xF7U, 0x89U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x28U, 0x42U, 0x31U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x80U, 0x04U, 0x41U, + 0x9FU, 0x8AU, 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, 0x04U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0xA5U, 0x8AU, 0x80U, 0x80U, 0x00U, 0x41U, 0x2CU, 0x42U, 0x32U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x42U, 0x02U, 0x21U, + 0x03U, 0x41U, 0x00U, 0x41U, 0x81U, 0x04U, 0x41U, 0xC1U, 0x89U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x05U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x42U, 0x7DU, 0x51U, 0x0DU, 0x01U, 0x41U, 0xD1U, 0x8AU, 0x80U, 0x80U, + 0x00U, 0x41U, 0x2FU, 0x42U, 0x34U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x0CU, 0x01U, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, + 0x80U, 0x02U, 0x41U, 0x80U, 0x8BU, 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, + 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x80U, 0x02U, 0x51U, + 0x0DU, 0x00U, 0x41U, 0x86U, 0x8BU, 0x80U, 0x80U, 0x00U, 0x41U, 0x28U, + 0x42U, 0x37U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, + 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x80U, 0x0AU, 0x41U, 0xAEU, 0x8BU, + 0x80U, 0x80U, 0x00U, 0x41U, 0x06U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x42U, 0x80U, 0x0AU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xB4U, 0x8BU, + 0x80U, 0x80U, 0x00U, 0x41U, 0x2CU, 0x42U, 0x38U, 0x10U, 0x82U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x42U, 0x05U, 0x21U, 0x03U, 0x41U, + 0x00U, 0x41U, 0x81U, 0x0AU, 0x41U, 0xC1U, 0x89U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x05U, 0x10U, 0x87U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x7DU, + 0x51U, 0x0DU, 0x00U, 0x41U, 0xE0U, 0x8BU, 0x80U, 0x80U, 0x00U, 0x41U, + 0x2FU, 0x42U, 0x3AU, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, + 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x03U, 0x10U, 0x88U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, + 0x02U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, + 0x41U, 0xD0U, 0x00U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x20U, 0x02U, 0x0BU, 0x0BU, 0x97U, 0x04U, 0x01U, 0x00U, 0x41U, 0x80U, + 0x08U, 0x0BU, 0x8FU, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x5FU, 0x61U, + 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x28U, 0x68U, 0x6FU, 0x6FU, + 0x6BU, 0x5FU, 0x61U, 0x63U, 0x63U, 0x2CU, 0x20U, 0x32U, 0x30U, 0x29U, + 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x30U, 0x00U, 0x75U, 0x74U, 0x69U, + 0x6CU, 0x5FU, 0x6BU, 0x65U, 0x79U, 0x6CU, 0x65U, 0x74U, 0x28U, 0x61U, + 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x5FU, 0x6BU, 0x65U, 0x79U, + 0x6CU, 0x65U, 0x74U, 0x2CU, 0x20U, 0x33U, 0x34U, 0x2CU, 0x20U, 0x4BU, + 0x45U, 0x59U, 0x4CU, 0x45U, 0x54U, 0x5FU, 0x41U, 0x43U, 0x43U, 0x4FU, + 0x55U, 0x4EU, 0x54U, 0x2CU, 0x20U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x5FU, + 0x61U, 0x63U, 0x63U, 0x2CU, 0x20U, 0x32U, 0x30U, 0x2CU, 0x20U, 0x30U, + 0x2CU, 0x30U, 0x2CU, 0x30U, 0x2CU, 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, + 0x20U, 0x33U, 0x34U, 0x00U, 0x73U, 0x6CU, 0x6FU, 0x74U, 0x5FU, 0x73U, + 0x65U, 0x74U, 0x28U, 0x61U, 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, + 0x5FU, 0x6BU, 0x65U, 0x79U, 0x6CU, 0x65U, 0x74U, 0x2CU, 0x20U, 0x33U, + 0x34U, 0x2CU, 0x20U, 0x31U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x31U, + 0x00U, 0x74U, 0x65U, 0x73U, 0x74U, 0x30U, 0x00U, 0x73U, 0x74U, 0x61U, + 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, + 0x32U, 0x35U, 0x36U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, + 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, 0x30U, 0x22U, 0x29U, 0x29U, 0x20U, + 0x3DU, 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x00U, 0x74U, 0x65U, 0x73U, + 0x74U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, + 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x37U, 0x2CU, 0x20U, + 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, + 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, + 0x5FU, 0x42U, 0x49U, 0x47U, 0x00U, 0x74U, 0x65U, 0x73U, 0x74U, 0x31U, + 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, + 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2CU, 0x20U, 0x53U, + 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, 0x31U, + 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x00U, 0x74U, 0x65U, 0x73U, 0x74U, 0x32U, 0x00U, 0x73U, 0x74U, 0x61U, + 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, + 0x32U, 0x35U, 0x36U, 0x2AU, 0x32U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, + 0x46U, 0x28U, 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, 0x32U, 0x22U, 0x29U, + 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x32U, + 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, + 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x32U, 0x2BU, + 0x31U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, 0x74U, + 0x65U, 0x73U, 0x74U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, + 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, 0x49U, 0x47U, 0x00U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x33U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, 0x74U, 0x65U, + 0x73U, 0x74U, 0x33U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, + 0x32U, 0x35U, 0x36U, 0x00U, 0x74U, 0x65U, 0x73U, 0x74U, 0x34U, 0x00U, + 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, + 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, 0x2AU, 0x35U, 0x2CU, 0x20U, + 0x53U, 0x42U, 0x55U, 0x46U, 0x28U, 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, + 0x34U, 0x22U, 0x29U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x32U, 0x35U, + 0x36U, 0x2AU, 0x35U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x32U, 0x35U, 0x36U, + 0x2AU, 0x35U, 0x2BU, 0x31U, 0x2CU, 0x20U, 0x53U, 0x42U, 0x55U, 0x46U, + 0x28U, 0x22U, 0x74U, 0x65U, 0x73U, 0x74U, 0x22U, 0x29U, 0x29U, 0x20U, + 0x3DU, 0x3DU, 0x20U, 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x42U, 0x49U, 0x47U, + 0x00U, + }}, + + /* ==== WASM: 74 ==== */ + {R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + 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 state_set ( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len + ); + extern int64_t state_foreign_set ( + uint32_t read_ptr, + uint32_t read_len, + uint32_t kread_ptr, + uint32_t kread_len, + uint32_t nread_ptr, + uint32_t nread_len, + uint32_t aread_ptr, + uint32_t aread_len + ); + extern int64_t otxn_param(uint32_t, uint32_t, uint32_t, uint32_t); + #define RESERVE_INSUFFICIENT -38 + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + #define ASSERT_EQUAL(x, y)\ + if (!(x == y))\ + rollback((uint32_t)#x, sizeof(#x), x); + int64_t hook(uint32_t reserved) + { + _g(1,1); + { + // 1. first account for StateMap + ASSERT_EQUAL(state_set(0, 1, "1", 1), RESERVE_INSUFFICIENT); + // 2. first namespace for StateMap + ASSERT_EQUAL(state_foreign_set(0, 1, "1", 1, "1", 32, 0, 0), RESERVE_INSUFFICIENT); + // 3. first statekey for StateMap + ASSERT_EQUAL(state_set(0, 1, "2", 1), RESERVE_INSUFFICIENT); + // 4. existing statedata + ASSERT_EQUAL(state_set(0, 1, "1", 1), RESERVE_INSUFFICIENT); + } + accept(0,0,0); + } + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x27U, + 0x05U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x04U, 0x7FU, + 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, + 0x01U, 0x7EU, 0x60U, 0x08U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, + 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, + 0x4EU, 0x05U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, + 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x09U, 0x73U, 0x74U, 0x61U, 0x74U, + 0x65U, 0x5FU, 0x73U, 0x65U, 0x74U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, + 0x76U, 0x08U, 0x72U, 0x6FU, 0x6CU, 0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, + 0x00U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x11U, 0x73U, 0x74U, 0x61U, + 0x74U, 0x65U, 0x5FU, 0x66U, 0x6FU, 0x72U, 0x65U, 0x69U, 0x67U, 0x6EU, + 0x5FU, 0x73U, 0x65U, 0x74U, 0x00U, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, + 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U, + 0x02U, 0x01U, 0x04U, 0x05U, 0x03U, 0x01U, 0x00U, 0x02U, 0x06U, 0x21U, + 0x05U, 0x7FU, 0x01U, 0x41U, 0xF0U, 0x88U, 0x04U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0xE3U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, + 0x7FU, 0x00U, 0x41U, 0xF0U, 0x88U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, + 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, + 0x6BU, 0x00U, 0x05U, 0x0AU, 0xA6U, 0x82U, 0x00U, 0x01U, 0xA2U, 0x82U, + 0x00U, 0x01U, 0x01U, 0x7EU, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x80U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, + 0x01U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, 0x10U, + 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x5AU, 0x51U, 0x0DU, 0x00U, + 0x41U, 0x82U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x18U, 0x41U, 0x00U, + 0x41U, 0x01U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, + 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x10U, 0x82U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x01U, + 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, 0x41U, 0x80U, + 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x20U, 0x41U, 0x00U, 0x41U, 0x00U, + 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x5AU, 0x51U, 0x0DU, + 0x00U, 0x41U, 0x9AU, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x2FU, 0x41U, + 0x00U, 0x41U, 0x01U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, + 0x01U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x20U, 0x41U, + 0x00U, 0x41U, 0x00U, 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, + 0x00U, 0x41U, 0x01U, 0x41U, 0xC9U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, + 0x01U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x5AU, 0x51U, + 0x0DU, 0x00U, 0x41U, 0xCBU, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x18U, + 0x41U, 0x00U, 0x41U, 0x01U, 0x41U, 0xC9U, 0x88U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x01U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x10U, 0x82U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, + 0x41U, 0x01U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, + 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x5AU, 0x51U, 0x0DU, + 0x00U, 0x41U, 0x82U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x18U, 0x41U, + 0x00U, 0x41U, 0x01U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, + 0x01U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x10U, 0x82U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, + 0x00U, 0x10U, 0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, 0x01U, + 0x0BU, 0x0BU, 0x6AU, 0x01U, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x63U, + 0x31U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, 0x5FU, 0x73U, 0x65U, + 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x31U, 0x2CU, 0x20U, 0x22U, 0x31U, + 0x22U, 0x2CU, 0x20U, 0x31U, 0x29U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, + 0x65U, 0x5FU, 0x66U, 0x6FU, 0x72U, 0x65U, 0x69U, 0x67U, 0x6EU, 0x5FU, + 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x31U, 0x2CU, 0x20U, + 0x22U, 0x31U, 0x22U, 0x2CU, 0x20U, 0x31U, 0x2CU, 0x20U, 0x22U, 0x31U, + 0x22U, 0x2CU, 0x20U, 0x33U, 0x32U, 0x2CU, 0x20U, 0x30U, 0x2CU, 0x20U, + 0x30U, 0x29U, 0x00U, 0x32U, 0x00U, 0x73U, 0x74U, 0x61U, 0x74U, 0x65U, + 0x5FU, 0x73U, 0x65U, 0x74U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x31U, 0x2CU, + 0x20U, 0x22U, 0x32U, 0x22U, 0x2CU, 0x20U, 0x31U, 0x29U, 0x00U, + }}, + + /* ==== WASM: 75 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -15491,7 +16048,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 72 ==== */ + /* ==== WASM: 76 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -15841,7 +16398,7 @@ std::map> wasm = { 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 73 ==== */ + /* ==== WASM: 77 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -15977,7 +16534,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 74 ==== */ + /* ==== WASM: 78 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16150,7 +16707,7 @@ std::map> wasm = { 0x54U, 0x5FU, 0x45U, 0x58U, 0x49U, 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 75 ==== */ + /* ==== WASM: 79 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16298,7 +16855,7 @@ std::map> wasm = { 0x30U, 0x00U, 0x22U, 0x00U, 0x00U, 0x00U, 0x00U, }}, - /* ==== WASM: 76 ==== */ + /* ==== WASM: 80 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16395,7 +16952,7 @@ std::map> wasm = { 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 77 ==== */ + /* ==== WASM: 81 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16454,7 +17011,7 @@ std::map> wasm = { 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, }}, - /* ==== WASM: 78 ==== */ + /* ==== WASM: 82 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16513,7 +17070,7 @@ std::map> wasm = { 0x4EU, 0x44U, 0x53U, 0x00U, }}, - /* ==== WASM: 79 ==== */ + /* ==== WASM: 83 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -18342,7 +18899,7 @@ std::map> wasm = { 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 80 ==== */ + /* ==== WASM: 84 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -19622,7 +20179,7 @@ std::map> wasm = { 0x29U, 0x2CU, 0x20U, 0x30U, 0x2CU, 0x30U, 0x20U, 0x29U, 0x29U, 0x00U, }}, - /* ==== WASM: 81 ==== */ + /* ==== WASM: 85 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -22555,7 +23112,7 @@ std::map> wasm = { 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 82 ==== */ + /* ==== WASM: 86 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -24520,7 +25077,7 @@ std::map> wasm = { 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 83 ==== */ + /* ==== WASM: 87 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -24805,7 +25362,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 84 ==== */ + /* ==== WASM: 88 ==== */ {R"[test.hook]( #include extern int32_t _g(uint32_t, uint32_t); @@ -25392,7 +25949,7 @@ std::map> wasm = { 0x4EU, 0x5FU, 0x46U, 0x41U, 0x49U, 0x4CU, 0x55U, 0x52U, 0x45U, 0x00U, }}, - /* ==== WASM: 85 ==== */ + /* ==== WASM: 89 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -25421,7 +25978,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 86 ==== */ + /* ==== WASM: 90 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -25453,7 +26010,7 @@ std::map> wasm = { 0x20U, 0x52U, 0x65U, 0x6AU, 0x65U, 0x63U, 0x74U, 0x65U, 0x64U, 0x00U, }}, - /* ==== WASM: 87 ==== */ + /* ==== WASM: 91 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32 i64) (result i64))) @@ -25480,7 +26037,7 @@ std::map> wasm = { 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, 0x00U, 0x0BU, }}, - /* ==== WASM: 88 ==== */ + /* ==== WASM: 92 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i32))) @@ -25533,7 +26090,7 @@ std::map> wasm = { 0x00U, 0x1AU, 0x0BU, }}, - /* ==== WASM: 89 ==== */ + /* ==== WASM: 93 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -32176,7 +32733,7 @@ std::map> wasm = { 0x39U, 0x30U, 0x31U, 0x32U, 0x33U, 0x00U, }}, - /* ==== WASM: 90 ==== */ + /* ==== WASM: 94 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -32222,7 +32779,7 @@ std::map> wasm = { 0x0BU, 0x06U, 0x76U, 0x61U, 0x6CU, 0x75U, 0x65U, 0x00U, }}, - /* ==== WASM: 91 ==== */ + /* ==== WASM: 95 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); diff --git a/src/test/rpc/AccountSet_test.cpp b/src/test/rpc/AccountSet_test.cpp index 19a5a12dd..ebb08cefe 100644 --- a/src/test/rpc/AccountSet_test.cpp +++ b/src/test/rpc/AccountSet_test.cpp @@ -544,6 +544,8 @@ public: void testTicket() { + testcase("Ticket"); + using namespace test::jtx; Env env(*this); Account const alice("alice"); @@ -574,6 +576,104 @@ public: env.close(); } + void + testHookStateScale() + { + testcase("HookStateScale"); + + using namespace test::jtx; + Env env(*this, supported_amendments() - featureExtendedHookState); + Account const alice("alice"); + + env.fund(XRP(10000), alice); + env.close(); + + // disabled + auto jt = noop(alice); + jt[sfHookStateScale.fieldName] = 1; + env(jt, ter(temMALFORMED)); + env.close(); + + env.enableFeature(featureExtendedHookState); + env.close(); + + // set invalid HookStateScale (0 or > 16) + for (uint16_t scale : {0, 17}) + { + jt[sfHookStateScale.fieldName] = scale; + env(jt, ter(temMALFORMED)); + } + + // set HookStateScale to 1 + jt[sfHookStateScale.fieldName] = 1; + env(jt); + env.close(); + BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfHookStateScale)); + + // increase HookStateScale to 16 + jt[sfHookStateScale.fieldName] = 16; + env(jt); + env.close(); + BEAST_EXPECT(env.le(alice)->getFieldU16(sfHookStateScale) == 16); + + // decrease HookStateScale to 8 + jt[sfHookStateScale.fieldName] = 8; + env(jt); + env.close(); + BEAST_EXPECT(env.le(alice)->getFieldU16(sfHookStateScale) == 8); + + // reset HookStateScale + jt[sfHookStateScale.fieldName] = 1; + env(jt); + env.close(); + BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfHookStateScale)); + + // test OwnerCount + // This prevents an exception for sfMintedNFTokens when the AccountRoot + // template is applied. + { + uint256 const nftId0{token::getNextID(env, alice, 0u)}; + env(token::mint(alice, 0u)); + env(token::burn(alice, nftId0)); + env.close(); + } + auto applyCount = [&](uint16_t scale, + uint32_t stateCount, + uint32_t ownerCount) { + return env.app().openLedger().modify( + [&](OpenView& view, beast::Journal j) -> bool { + auto const sle = view.read(keylet::account(alice.id())); + if (!sle) + return false; + auto replacement = std::make_shared(*sle, sle->key()); + (*replacement)[sfHookStateScale] = scale; + (*replacement)[sfHookStateCount] = stateCount; + (*replacement)[sfOwnerCount] = ownerCount; + view.rawReplace(replacement); + return true; + }); + }; + applyCount(5, 10, 100); + + // remove, but HookStateCount exists + jt[sfHookStateScale.fieldName] = 1; + env(jt, ter(tecHAS_HOOK_STATE)); + // decrease, but HookStateCount exists + jt[sfHookStateScale.fieldName] = 4; + env(jt, ter(tecHAS_HOOK_STATE)); + // increase + jt[sfHookStateScale.fieldName] = 6; + env(jt, ter(tesSUCCESS)); + BEAST_EXPECT(env.le(alice)->getFieldU16(sfHookStateScale) == 6); + BEAST_EXPECT(env.le(alice)->getFieldU32(sfHookStateCount) == 10); + BEAST_EXPECT(env.le(alice)->getFieldU32(sfOwnerCount) == 110); + + // check InsufficientReserve + applyCount(1, 100, 200); + jt[sfHookStateScale.fieldName] = 16; + env(jt, ter(tecINSUFFICIENT_RESERVE)); + } + void run() override { @@ -590,6 +690,7 @@ public: testRequireAuthWithDir(); testTransferRate(); testTicket(); + testHookStateScale(); } };