Compare commits

...

2 Commits

Author SHA1 Message Date
Richard Holland
e57c9add25 fix permisisons on inject 2024-01-22 09:37:42 +00:00
Denis Angell
f64e626a3f Fix: TSH Updates & Emitted Txn (#261)
fixXahauV2
* refactor tsh
* add uritoken mint/cancel tsh
* add flags to hookexections meta and nonce to hookemissions meta

Co-authored-by: Richard Holland <richard.holland@starstone.co.nz>
2024-01-22 10:25:36 +01:00
9 changed files with 1119 additions and 706 deletions

View File

@@ -20,6 +20,12 @@ enum HookSetFlags : uint8_t {
hsfNSDELETE = 0b00000010U, // delete namespace
hsfCOLLECT = 0b00000100U, // allow collect calls on this hook
};
enum HookEmissionFlags : uint16_t {
hefSTRONG = 0x1,
hefCALLBACK = 0x2,
hefDOAAW = 0x4,
};
} // namespace ripple
namespace hook {

View File

@@ -45,43 +45,6 @@ public:
};
using namespace ripple;
static const std::map<uint16_t, uint8_t> TSHAllowances = {
{ttPAYMENT, tshROLLBACK},
{ttESCROW_CREATE, tshROLLBACK},
{ttESCROW_FINISH, tshROLLBACK},
{ttACCOUNT_SET, tshNONE},
{ttESCROW_CANCEL, tshCOLLECT},
{ttREGULAR_KEY_SET, tshROLLBACK},
{ttOFFER_CREATE, tshCOLLECT},
{ttOFFER_CANCEL, tshNONE},
{ttTICKET_CREATE, tshNONE},
{ttSIGNER_LIST_SET, tshROLLBACK},
{ttPAYCHAN_CREATE, tshROLLBACK},
{ttPAYCHAN_FUND, tshCOLLECT},
{ttPAYCHAN_CLAIM, tshCOLLECT},
{ttCHECK_CREATE, tshROLLBACK},
{ttCHECK_CASH, tshROLLBACK},
{ttCHECK_CANCEL, tshCOLLECT},
{ttDEPOSIT_PREAUTH, tshROLLBACK},
{ttTRUST_SET, tshCOLLECT},
{ttACCOUNT_DELETE, tshROLLBACK},
{ttHOOK_SET, tshNONE},
{ttNFTOKEN_MINT, tshROLLBACK},
{ttNFTOKEN_BURN, tshCOLLECT},
{ttNFTOKEN_CREATE_OFFER, tshROLLBACK},
{ttNFTOKEN_CANCEL_OFFER, tshCOLLECT},
{ttNFTOKEN_ACCEPT_OFFER, tshROLLBACK},
{ttCLAIM_REWARD, tshROLLBACK},
{ttINVOKE, tshROLLBACK},
{ttURITOKEN_MINT, tshNONE},
{ttURITOKEN_BURN, tshROLLBACK},
{ttURITOKEN_BUY, tshROLLBACK},
{ttURITOKEN_CREATE_SELL_OFFER, tshROLLBACK},
{ttURITOKEN_CANCEL_SELL_OFFER, tshNONE},
{ttIMPORT, tshROLLBACK},
{ttGENESIS_MINT, tshCOLLECT},
};
std::vector<std::pair<AccountID, bool>>
getTransactionalStakeHolders(STTx const& tx, ReadView const& rv);
} // namespace hook

View File

@@ -38,19 +38,10 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
uint16_t tt = tx.getFieldU16(sfTransactionType);
uint8_t tsh = tshNONE;
if (auto const& found = hook::TSHAllowances.find(tt);
found != hook::TSHAllowances.end())
tsh = found->second;
else
return {};
std::map<AccountID, std::pair<int, bool>> tshEntries;
int upto = 0;
bool canRollback = tsh & tshROLLBACK;
auto const ADD_TSH = [&otxnAcc, &tshEntries, &upto](
const AccountID& acc_r, bool rb) {
if (acc_r != *otxnAcc)
@@ -62,6 +53,9 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
}
};
bool const tshSTRONG = true; // tshROLLBACK
bool const tshWEAK = false; // tshCOLLECT
auto const getNFTOffer =
[](std::optional<uint256> id,
ReadView const& rv) -> std::shared_ptr<const SLE> {
@@ -72,12 +66,13 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
};
bool const fixV1 = rv.rules().enabled(fixXahauV1);
bool const fixV2 = rv.rules().enabled(fixXahauV2);
switch (tt)
{
case ttIMPORT: {
if (tx.isFieldPresent(sfIssuer))
ADD_TSH(tx.getAccountID(sfIssuer), canRollback);
ADD_TSH(tx.getAccountID(sfIssuer), fixV2 ? tshWEAK : tshSTRONG);
break;
}
@@ -107,11 +102,11 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
{
// the owner burns their token, and the issuer is a weak TSH
if (*otxnAcc == owner && rv.exists(keylet::account(issuer)))
ADD_TSH(issuer, false);
ADD_TSH(issuer, tshWEAK);
// the issuer burns the owner's token, and the owner is a weak
// TSH
else if (rv.exists(keylet::account(owner)))
ADD_TSH(owner, false);
ADD_TSH(owner, tshWEAK);
break;
}
@@ -121,13 +116,13 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (*otxnAcc == owner)
{
// the owner burns their token, and the issuer is a weak TSH
ADD_TSH(issuer, true);
ADD_TSH(issuer, tshSTRONG);
}
else
{
// the issuer burns the owner's token, and the owner is a
// weak TSH
ADD_TSH(owner, true);
ADD_TSH(owner, tshSTRONG);
}
}
@@ -148,17 +143,46 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (owner != tx.getAccountID(sfAccount))
{
// current owner is a strong TSH
ADD_TSH(owner, canRollback);
ADD_TSH(owner, tshSTRONG);
}
// issuer is also a strong TSH if the burnable flag is set
auto const issuer = ut->getAccountID(sfIssuer);
if (issuer != owner)
ADD_TSH(issuer, ut->getFlags() & lsfBurnable);
ADD_TSH(
issuer,
(ut->getFlags() & lsfBurnable) ? tshSTRONG : tshWEAK);
break;
}
case ttURITOKEN_MINT: {
// destination is a strong tsh
if (fixV2 && tx.isFieldPresent(sfDestination))
ADD_TSH(tx.getAccountID(sfDestination), tshSTRONG);
break;
}
case ttURITOKEN_CANCEL_SELL_OFFER: {
if (!fixV2)
break;
Keylet const id{ltURI_TOKEN, tx.getFieldH256(sfURITokenID)};
if (!rv.exists(id))
return {};
auto const ut = rv.read(id);
if (!ut || ut->getFieldU16(sfLedgerEntryType) != ltURI_TOKEN)
return {};
if (ut->isFieldPresent(sfDestination))
{
auto const dest = ut->getAccountID(sfDestination);
ADD_TSH(dest, tshWEAK);
}
break;
}
case ttURITOKEN_CREATE_SELL_OFFER: {
Keylet const id{ltURI_TOKEN, tx.getFieldH256(sfURITokenID)};
if (!rv.exists(id))
@@ -173,11 +197,13 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
// issuer is a strong TSH if the burnable flag is set
if (issuer != owner)
ADD_TSH(issuer, ut->getFlags() & lsfBurnable);
ADD_TSH(
issuer,
(ut->getFlags() & lsfBurnable) ? tshSTRONG : tshWEAK);
// destination is a strong tsh
if (tx.isFieldPresent(sfDestination))
ADD_TSH(tx.getAccountID(sfDestination), canRollback);
ADD_TSH(tx.getAccountID(sfDestination), tshSTRONG);
break;
}
@@ -186,7 +212,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
case ttNFTOKEN_MINT:
case ttCLAIM_REWARD: {
if (tx.isFieldPresent(sfIssuer))
ADD_TSH(tx.getAccountID(sfIssuer), canRollback);
ADD_TSH(tx.getAccountID(sfIssuer), tshSTRONG);
break;
};
@@ -209,7 +235,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
ADD_TSH(issuer, issuerCanRollback);
if (hasOwner)
ADD_TSH(owner, canRollback);
ADD_TSH(owner, tshWEAK);
break;
}
@@ -228,16 +254,16 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (bo)
{
ADD_TSH(bo->getAccountID(sfOwner), canRollback);
ADD_TSH(bo->getAccountID(sfOwner), tshSTRONG);
if (bo->isFieldPresent(sfDestination))
ADD_TSH(bo->getAccountID(sfDestination), canRollback);
ADD_TSH(bo->getAccountID(sfDestination), tshWEAK);
}
if (so)
{
ADD_TSH(so->getAccountID(sfOwner), canRollback);
ADD_TSH(so->getAccountID(sfOwner), tshSTRONG);
if (so->isFieldPresent(sfDestination))
ADD_TSH(so->getAccountID(sfDestination), canRollback);
ADD_TSH(so->getAccountID(sfDestination), tshWEAK);
}
break;
@@ -253,24 +279,21 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
auto const offer = getNFTOffer(offerID, rv);
if (offer)
{
ADD_TSH(offer->getAccountID(sfOwner), canRollback);
ADD_TSH(offer->getAccountID(sfOwner), tshSTRONG);
if (offer->isFieldPresent(sfDestination))
ADD_TSH(
offer->getAccountID(sfDestination), canRollback);
ADD_TSH(offer->getAccountID(sfDestination), tshWEAK);
// issuer can't stop people canceling their offers, but can
// get weak executions
uint256 nid = offer->getFieldH256(sfNFTokenID);
auto const issuer = nft::getIssuer(nid);
ADD_TSH(issuer, false);
ADD_TSH(issuer, tshWEAK);
}
}
break;
}
// self transactions
case ttURITOKEN_MINT:
case ttURITOKEN_CANCEL_SELL_OFFER:
case ttACCOUNT_SET:
case ttOFFER_CANCEL:
case ttTICKET_CREATE:
@@ -283,14 +306,14 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
case ttREGULAR_KEY_SET: {
if (!tx.isFieldPresent(sfRegularKey))
return {};
ADD_TSH(tx.getAccountID(sfRegularKey), canRollback);
ADD_TSH(tx.getAccountID(sfRegularKey), tshSTRONG);
break;
}
case ttDEPOSIT_PREAUTH: {
if (!tx.isFieldPresent(sfAuthorize))
return {};
ADD_TSH(tx.getAccountID(sfAuthorize), canRollback);
ADD_TSH(tx.getAccountID(sfAuthorize), tshSTRONG);
break;
}
@@ -302,7 +325,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
case ttPAYCHAN_CREATE:
case ttINVOKE: {
if (destAcc)
ADD_TSH(*destAcc, canRollback);
ADD_TSH(*destAcc, tshSTRONG);
break;
}
@@ -313,7 +336,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
auto const& lim = tx.getFieldAmount(sfLimitAmount);
AccountID const& issuer = lim.getIssuer();
ADD_TSH(issuer, canRollback);
ADD_TSH(issuer, tshWEAK);
break;
}
@@ -348,11 +371,11 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
// the source account is a strong transacitonal stakeholder for
// fin and can
ADD_TSH(src, true);
ADD_TSH(src, tshSTRONG);
// the dest acc is a strong tsh for fin and weak for can
if (src != dst)
ADD_TSH(dst, tt == ttESCROW_FINISH);
ADD_TSH(dst, tt == ttESCROW_FINISH ? tshSTRONG : tshWEAK);
break;
}
@@ -368,8 +391,10 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (!escrow)
return {};
ADD_TSH(escrow->getAccountID(sfAccount), true);
ADD_TSH(escrow->getAccountID(sfDestination), canRollback);
ADD_TSH(escrow->getAccountID(sfAccount), tshSTRONG);
ADD_TSH(
escrow->getAccountID(sfDestination),
tt == ttESCROW_FINISH ? tshSTRONG : tshWEAK);
break;
}
}
@@ -383,8 +408,8 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (!chan)
return {};
ADD_TSH(chan->getAccountID(sfAccount), true);
ADD_TSH(chan->getAccountID(sfDestination), canRollback);
ADD_TSH(chan->getAccountID(sfAccount), tshSTRONG);
ADD_TSH(chan->getAccountID(sfDestination), tshWEAK);
break;
}
@@ -397,8 +422,8 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
if (!check)
return {};
ADD_TSH(check->getAccountID(sfAccount), true);
ADD_TSH(check->getAccountID(sfDestination), canRollback);
ADD_TSH(check->getAccountID(sfAccount), tshSTRONG);
ADD_TSH(check->getAccountID(sfDestination), tshWEAK);
break;
}
@@ -408,7 +433,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
STArray const& signerEntries = tx.getFieldArray(sfSignerEntries);
for (auto const& entryObj : signerEntries)
if (entryObj.isFieldPresent(sfAccount))
ADD_TSH(entryObj.getAccountID(sfAccount), canRollback);
ADD_TSH(entryObj.getAccountID(sfAccount), tshSTRONG);
break;
}
@@ -420,7 +445,7 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
{
if (mint.isFieldPresent(sfDestination))
{
ADD_TSH(mint.getAccountID(sfDestination), canRollback);
ADD_TSH(mint.getAccountID(sfDestination), tshWEAK);
}
}
}
@@ -1832,7 +1857,7 @@ hook::finalizeHookResult(
uint16_t exec_index = avi.nextHookExecutionIndex();
// apply emitted transactions to the ledger (by adding them to the emitted
// directory) if we are allowed to
std::vector<uint256> emission_txnid;
std::map<uint256 /* txnid */, uint256 /* emit nonce */> emission_txnid;
if (doEmit)
{
@@ -1853,7 +1878,12 @@ hook::finalizeHookResult(
if (!sleEmitted)
{
emission_txnid.push_back(id);
auto const& emitDetails = const_cast<ripple::STTx&>(*ptr)
.getField(sfEmitDetails)
.downcast<STObject>();
emission_txnid.emplace(
id, emitDetails.getFieldH256(sfEmitNonce));
sleEmitted = std::make_shared<SLE>(emittedId);
// RH TODO: add a new constructor to STObject to avoid this
@@ -1885,6 +1915,7 @@ hook::finalizeHookResult(
}
}
bool const fixV2 = applyCtx.view().rules().enabled(fixXahauV2);
// add a metadata entry for this hook execution result
{
STObject meta{sfHookExecution};
@@ -1911,6 +1942,19 @@ hook::finalizeHookResult(
meta.setFieldU16(sfHookExecutionIndex, exec_index);
meta.setFieldU16(sfHookStateChangeCount, hookResult.changedStateCount);
meta.setFieldH256(sfHookHash, hookResult.hookHash);
// add informational flags in fix2
if (fixV2)
{
uint32_t flags = 0;
if (hookResult.isStrong)
flags |= hefSTRONG;
if (hookResult.isCallback)
flags |= hefCALLBACK;
if (hookResult.executeAgainAsWeak)
flags |= hefDOAAW;
meta.setFieldU32(sfFlags, flags);
}
avi.addHookExecutionMetaData(std::move(meta));
}
@@ -1918,12 +1962,14 @@ hook::finalizeHookResult(
if (applyCtx.view().rules().enabled(featureHooksUpdate1) &&
!emission_txnid.empty())
{
for (auto const& etxnid : emission_txnid)
for (auto const& [etxnid, enonce] : emission_txnid)
{
STObject meta{sfHookEmission};
meta.setFieldH256(sfHookHash, hookResult.hookHash);
meta.setAccountID(sfHookAccount, hookResult.account);
meta.setFieldH256(sfEmittedTxnID, etxnid);
if (fixV2)
meta.setFieldH256(sfEmitNonce, enonce);
avi.addHookEmissionMetaData(std::move(meta));
}
}

View File

@@ -72,13 +72,15 @@ InnerObjectFormats::InnerObjectFormats()
{sfHookInstructionCount, soeREQUIRED},
{sfHookExecutionIndex, soeREQUIRED},
{sfHookStateChangeCount, soeREQUIRED},
{sfHookEmitCount, soeREQUIRED}});
{sfHookEmitCount, soeREQUIRED},
{sfFlags, soeOPTIONAL}});
add(sfHookEmission.jsonName.c_str(),
sfHookEmission.getCode(),
{{sfHookHash, soeREQUIRED},
{sfHookAccount, soeREQUIRED},
{sfEmittedTxnID, soeREQUIRED}});
{sfEmittedTxnID, soeREQUIRED},
{sfEmitNonce, soeOPTIONAL}});
add(sfHookDefinition.jsonName.c_str(),
sfHookDefinition.getCode(),

View File

@@ -47,9 +47,6 @@ getFailHard(RPC::JsonContext const& context)
Json::Value
doInject(RPC::JsonContext& context)
{
if (context.role != Role::ADMIN)
return RPC::make_error(
rpcNOT_SUPPORTED, "Signing is not supported by this server.");
if (context.role != Role::ADMIN)
return rpcError(rpcNO_PERMISSION);

View File

@@ -141,7 +141,7 @@ Handler const handlerArray[]{
{"ripple_path_find", byRef(&doRipplePathFind), Role::USER, NO_CONDITION},
{"sign", byRef(&doSign), Role::USER, NO_CONDITION},
{"sign_for", byRef(&doSignFor), Role::USER, NO_CONDITION},
{"inject", byRef(&doInject), Role::USER, NEEDS_CURRENT_LEDGER},
{"inject", byRef(&doInject), Role::ADMIN, NEEDS_CURRENT_LEDGER},
{"submit", byRef(&doSubmit), Role::USER, NEEDS_CURRENT_LEDGER},
{"submit_multisigned",
byRef(&doSubmitMultiSigned),

View File

@@ -4996,6 +4996,7 @@ class Import_test : public beast::unit_test::suite
*this, network::makeNetworkVLConfig(21337, keys)};
auto const feeDrops = env.current()->fees().base;
bool const fixV2 = env.current()->rules().enabled(fixXahauV2);
// confirm total coins header
auto const initCoins = env.current()->info().drops;
@@ -5015,6 +5016,10 @@ class Import_test : public beast::unit_test::suite
env.fund(XRP(10000), alice, issuer);
env.close();
// fixXahauV2 - tshWEAK
env(fset(issuer, asfTshCollect));
env.close();
std::string const createCodeHex =
"0061736D01000000011C0460057F7F7F7F7F017E60037F7F7E017E60027F7F"
"017F60017F017E02250303656E76057472616365000003656E7608726F6C6C"
@@ -5029,8 +5034,8 @@ class Import_test : public beast::unit_test::suite
std::string ns_str =
"CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECA"
"FE";
Json::Value jv =
ripple::test::jtx::hook(issuer, {{hso(createCodeHex)}}, 0);
Json::Value jv = ripple::test::jtx::hook(
issuer, {{hso(createCodeHex)}}, hsfOVERRIDE | hsfCOLLECT);
jv[jss::Hooks][0U][jss::Hook][jss::HookNamespace] = ns_str;
jv[jss::Hooks][0U][jss::Hook][jss::HookOn] =
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFFFFFFBFFF"
@@ -5041,32 +5046,37 @@ class Import_test : public beast::unit_test::suite
auto const preAlice = env.balance(alice);
auto const preCoins = env.current()->info().drops;
auto const result = fixV2 ? ter(tesSUCCESS) : ter(tecHOOK_REJECTED);
env(import::import(
alice, import::loadXpop(ImportTCAccountSet::w_seed)),
import::issuer(issuer),
fee(1'000'000),
ter(tecHOOK_REJECTED));
result);
env.close();
// confirm fee was burned but no mint
// fixXahauV2
auto const mintXAH = fixV2 ? XRP(1000) : XRP(0);
// confirm fee was burned mint / no mint
auto const postAlice = env.balance(alice);
BEAST_EXPECT(postAlice == preAlice - XRP(1));
BEAST_EXPECT(postAlice == preAlice - XRP(1) + mintXAH);
// confirm total coins header
auto const postCoins = env.current()->info().drops;
BEAST_EXPECT(postCoins == preCoins - XRP(1));
BEAST_EXPECT(postCoins == preCoins - XRP(1) + mintXAH);
// resubmit import without issuer - no trigger hook
// resubmit import without issuer
auto const result2 =
fixV2 ? ter(tefPAST_IMPORT_SEQ) : ter(tesSUCCESS);
env(import::import(
alice, import::loadXpop(ImportTCAccountSet::w_seed)),
fee(feeDrops * 10),
ter(tesSUCCESS));
result2);
env.close();
// total burn = (burn drops + burn fee drops) - fee drops
auto const totalBurn = XRP(1000) - (feeDrops * 10);
// total burn
auto const totalBurn = fixV2 ? XRP(0) : XRP(1000) - (feeDrops * 10);
// confirm fee was minted
// confirm fee was minted / not minted
auto const postAlice2 = env.balance(alice);
BEAST_EXPECT(postAlice2 == postAlice + totalBurn);
@@ -5921,6 +5931,7 @@ public:
{
using namespace test::jtx;
FeatureBitset const all{supported_amendments()};
testWithFeats(all - fixXahauV2);
testWithFeats(all);
}

View File

@@ -48,91 +48,368 @@ private:
jv[jss::Flags] = hsfOVERRIDE | hsfCOLLECT;
}
const std::vector<uint8_t> CallbackHook = {
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x35U,
0x08U, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x05U,
0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x02U, 0x7FU,
0x7FU, 0x01U, 0x7EU, 0x60U, 0x04U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U,
0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x00U, 0x01U, 0x7EU,
0x60U, 0x03U, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x02U, 0x7FU,
0x7FU, 0x01U, 0x7FU, 0x02U, 0xAEU, 0x01U, 0x0BU, 0x03U, 0x65U, 0x6EU,
0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x00U,
0x03U, 0x65U, 0x6EU, 0x76U, 0x05U, 0x74U, 0x72U, 0x61U, 0x63U, 0x65U,
0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0CU, 0x68U, 0x6FU, 0x6FU,
0x6BU, 0x5FU, 0x61U, 0x63U, 0x63U, 0x6FU, 0x75U, 0x6EU, 0x74U, 0x00U,
0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0AU, 0x75U, 0x74U, 0x69U, 0x6CU,
0x5FU, 0x61U, 0x63U, 0x63U, 0x69U, 0x64U, 0x00U, 0x03U, 0x03U, 0x65U,
0x6EU, 0x76U, 0x0CU, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x72U, 0x65U,
0x73U, 0x65U, 0x72U, 0x76U, 0x65U, 0x00U, 0x04U, 0x03U, 0x65U, 0x6EU,
0x76U, 0x0AU, 0x6CU, 0x65U, 0x64U, 0x67U, 0x65U, 0x72U, 0x5FU, 0x73U,
0x65U, 0x71U, 0x00U, 0x05U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0AU, 0x6FU,
0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, 0x69U, 0x65U, 0x6CU, 0x64U, 0x00U,
0x06U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0CU, 0x65U, 0x74U, 0x78U, 0x6EU,
0x5FU, 0x64U, 0x65U, 0x74U, 0x61U, 0x69U, 0x6CU, 0x73U, 0x00U, 0x02U,
0x03U, 0x65U, 0x6EU, 0x76U, 0x0DU, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU,
0x66U, 0x65U, 0x65U, 0x5FU, 0x62U, 0x61U, 0x73U, 0x65U, 0x00U, 0x02U,
0x03U, 0x65U, 0x6EU, 0x76U, 0x04U, 0x65U, 0x6DU, 0x69U, 0x74U, 0x00U,
0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x07U,
0x03U, 0x03U, 0x02U, 0x04U, 0x04U, 0x05U, 0x03U, 0x01U, 0x00U, 0x02U,
0x06U, 0x31U, 0x08U, 0x7FU, 0x01U, 0x41U, 0xE0U, 0x8BU, 0x04U, 0x0BU,
0x7FU, 0x00U, 0x41U, 0xA0U, 0x09U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U,
0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xD1U, 0x0BU, 0x0BU, 0x7FU, 0x00U,
0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xE0U, 0x8BU, 0x04U,
0x0BU, 0x7FU, 0x00U, 0x41U, 0x00U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x01U,
0x0BU, 0x07U, 0x0FU, 0x02U, 0x04U, 0x63U, 0x62U, 0x61U, 0x6BU, 0x00U,
0x0BU, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x0CU, 0x0AU, 0xA6U,
0x8EU, 0x00U, 0x02U, 0x8BU, 0x82U, 0x00U, 0x02U, 0x03U, 0x7EU, 0x04U,
0x7FU, 0x02U, 0x7EU, 0x23U, 0x00U, 0x21U, 0x04U, 0x20U, 0x04U, 0x41U,
0x10U, 0x6BU, 0x21U, 0x04U, 0x20U, 0x04U, 0x24U, 0x00U, 0x20U, 0x04U,
0x20U, 0x00U, 0x36U, 0x02U, 0x0CU, 0x20U, 0x04U, 0x41U, 0x08U, 0x6AU,
0x21U, 0x06U, 0x20U, 0x06U, 0x21U, 0x00U, 0x20U, 0x04U, 0x20U, 0x00U,
0x36U, 0x02U, 0x04U, 0x20U, 0x04U, 0x28U, 0x02U, 0x0CU, 0x21U, 0x00U,
0x20U, 0x00U, 0xADU, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x18U, 0x88U,
0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U,
0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x04U, 0x28U, 0x02U, 0x04U,
0x21U, 0x05U, 0x20U, 0x05U, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U,
0x04U, 0x28U, 0x02U, 0x0CU, 0x21U, 0x00U, 0x20U, 0x00U, 0xADU, 0x21U,
0x01U, 0x20U, 0x01U, 0x42U, 0x10U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U,
0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U,
0x00U, 0x20U, 0x04U, 0x28U, 0x02U, 0x04U, 0x21U, 0x05U, 0x20U, 0x05U,
0x20U, 0x00U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x04U, 0x28U, 0x02U, 0x0CU,
0x21U, 0x00U, 0x20U, 0x00U, 0xADU, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U,
0x08U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U,
0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x04U, 0x28U,
0x02U, 0x04U, 0x21U, 0x05U, 0x20U, 0x05U, 0x20U, 0x00U, 0x3AU, 0x00U,
0x02U, 0x20U, 0x04U, 0x28U, 0x02U, 0x0CU, 0x21U, 0x00U, 0x20U, 0x00U,
0xADU, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x00U, 0x88U, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U,
0xA7U, 0x21U, 0x00U, 0x20U, 0x04U, 0x28U, 0x02U, 0x04U, 0x21U, 0x05U,
0x20U, 0x05U, 0x20U, 0x00U, 0x3AU, 0x00U, 0x03U, 0x20U, 0x06U, 0x21U,
0x00U, 0x20U, 0x00U, 0x41U, 0x04U, 0x42U, 0x32U, 0x10U, 0x00U, 0x21U,
0x02U, 0x20U, 0x02U, 0x1AU, 0x20U, 0x04U, 0x41U, 0x10U, 0x6AU, 0x21U,
0x00U, 0x20U, 0x00U, 0x24U, 0x00U, 0x42U, 0x00U, 0x21U, 0x03U, 0x42U,
0x00U, 0x0BU, 0x0BU, 0x94U, 0x8CU, 0x00U, 0x02U, 0x09U, 0x7EU, 0x05U,
0x7FU, 0x02U, 0x40U, 0x02U, 0x40U, 0x23U, 0x00U, 0x21U, 0x0BU, 0x20U,
0x0BU, 0x41U, 0x80U, 0x01U, 0x6BU, 0x21U, 0x0BU, 0x20U, 0x0BU, 0x24U,
0x00U, 0x20U, 0x0BU, 0x20U, 0x00U, 0x36U, 0x02U, 0x7CU, 0x41U, 0xFBU,
0x08U, 0x41U, 0x15U, 0x41U, 0xE7U, 0x08U, 0x41U, 0x14U, 0x41U, 0x00U,
0x10U, 0x01U, 0x21U, 0x02U, 0x20U, 0x02U, 0x1AU, 0x41U, 0x9DU, 0x0AU,
0x41U, 0x14U, 0x10U, 0x02U, 0x21U, 0x03U, 0x20U, 0x03U, 0x1AU, 0x41U,
0xB3U, 0x0AU, 0x41U, 0x14U, 0x41U, 0x84U, 0x08U, 0x41U, 0x23U, 0x10U,
0x03U, 0x21U, 0x01U, 0x20U, 0x0BU, 0x20U, 0x01U, 0x37U, 0x03U, 0x58U,
0x41U, 0x01U, 0x10U, 0x04U, 0x21U, 0x04U, 0x20U, 0x04U, 0x1AU, 0x10U,
0x05U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x00U,
0x41U, 0x01U, 0x6AU, 0x21U, 0x00U, 0x20U, 0x0BU, 0x20U, 0x00U, 0x36U,
0x02U, 0x54U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x54U, 0x21U, 0x00U, 0x20U,
0x00U, 0x41U, 0xFFU, 0x01U, 0x71U, 0x21U, 0x00U, 0x20U, 0x00U, 0x41U,
0x18U, 0x74U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x54U, 0x21U,
0x0AU, 0x20U, 0x0AU, 0x41U, 0x80U, 0xFEU, 0x03U, 0x71U, 0x21U, 0x0AU,
0x20U, 0x0AU, 0x41U, 0x08U, 0x74U, 0x21U, 0x0AU, 0x20U, 0x00U, 0x20U,
0x0AU, 0x72U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x54U, 0x21U,
0x0AU, 0x20U, 0x0AU, 0x41U, 0x80U, 0x80U, 0xFCU, 0x07U, 0x71U, 0x21U,
0x0AU, 0x20U, 0x0AU, 0x41U, 0x08U, 0x76U, 0x21U, 0x0AU, 0x20U, 0x00U,
0x20U, 0x0AU, 0x72U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x54U,
0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x80U, 0x80U, 0x80U, 0x78U, 0x71U,
0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x18U, 0x76U, 0x21U, 0x0AU, 0x20U,
0x00U, 0x20U, 0x0AU, 0x72U, 0x21U, 0x00U, 0x41U, 0x00U, 0x20U, 0x00U,
0x36U, 0x02U, 0xB4U, 0x09U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x54U, 0x21U,
0x00U, 0x20U, 0x00U, 0x41U, 0x04U, 0x6AU, 0x21U, 0x00U, 0x20U, 0x0BU,
0x20U, 0x00U, 0x36U, 0x02U, 0x50U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x50U,
0x21U, 0x00U, 0x20U, 0x00U, 0x41U, 0xFFU, 0x01U, 0x71U, 0x21U, 0x00U,
0x20U, 0x00U, 0x41U, 0x18U, 0x74U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U,
0x02U, 0x50U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x80U, 0xFEU, 0x03U,
0x71U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x08U, 0x74U, 0x21U, 0x0AU,
0x20U, 0x00U, 0x20U, 0x0AU, 0x72U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U,
0x02U, 0x50U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x80U, 0x80U, 0xFCU,
0x07U, 0x71U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x08U, 0x76U, 0x21U,
0x0AU, 0x20U, 0x00U, 0x20U, 0x0AU, 0x72U, 0x21U, 0x00U, 0x20U, 0x0BU,
0x28U, 0x02U, 0x50U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x80U, 0x80U,
0x80U, 0x78U, 0x71U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x18U, 0x76U,
0x21U, 0x0AU, 0x20U, 0x00U, 0x20U, 0x0AU, 0x72U, 0x21U, 0x00U, 0x41U,
0x00U, 0x20U, 0x00U, 0x36U, 0x02U, 0xBAU, 0x09U, 0x20U, 0x0BU, 0x42U,
0xC0U, 0x84U, 0x3DU, 0x37U, 0x03U, 0x48U, 0x20U, 0x0BU, 0x41U, 0xBFU,
0x09U, 0x36U, 0x02U, 0x44U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x48U, 0x21U,
0x01U, 0x20U, 0x01U, 0x42U, 0x38U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U,
0x42U, 0x3FU, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xC0U, 0x00U,
0x7CU, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU,
0x28U, 0x02U, 0x44U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU,
0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x44U, 0x20U,
0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U,
0x48U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x30U, 0x88U, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U,
0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x44U, 0x21U, 0x0AU,
0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U,
0x0CU, 0x36U, 0x02U, 0x44U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U,
0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x48U, 0x21U, 0x01U, 0x20U, 0x01U,
0x42U, 0x28U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U,
0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU,
0x28U, 0x02U, 0x44U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU,
0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x44U, 0x20U,
0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U,
0x48U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x20U, 0x88U, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U,
0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x44U, 0x21U, 0x0AU,
0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U,
0x0CU, 0x36U, 0x02U, 0x44U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U,
0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x48U, 0x21U, 0x01U, 0x20U, 0x01U,
0x42U, 0x18U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U,
0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU,
0x28U, 0x02U, 0x44U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU,
0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x44U, 0x20U,
0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U,
0x48U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x10U, 0x88U, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U,
0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x44U, 0x21U, 0x0AU,
0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U,
0x0CU, 0x36U, 0x02U, 0x44U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U,
0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x48U, 0x21U, 0x01U, 0x20U, 0x01U,
0x42U, 0x08U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U,
0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU,
0x28U, 0x02U, 0x44U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU,
0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x44U, 0x20U,
0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U,
0x48U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x00U, 0x88U, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U,
0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x44U, 0x21U, 0x0AU,
0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U,
0x0CU, 0x36U, 0x02U, 0x44U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U,
0x00U, 0x41U, 0xAEU, 0x09U, 0x41U, 0x04U, 0x41U, 0x83U, 0x80U, 0x08U,
0x10U, 0x06U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x04U, 0x51U, 0x21U,
0x00U, 0x20U, 0x00U, 0x41U, 0x01U, 0x71U, 0x21U, 0x00U, 0x20U, 0x00U,
0x45U, 0x21U, 0x00U, 0x20U, 0x00U, 0x45U, 0x21U, 0x00U, 0x0BU, 0x20U,
0x00U, 0x04U, 0x40U, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0x2EU, 0x3AU,
0x00U, 0xADU, 0x09U, 0x01U, 0x0BU, 0x05U, 0x01U, 0x0BU, 0x0BU, 0x02U,
0x7EU, 0x02U, 0x40U, 0x02U, 0x40U, 0x41U, 0xC7U, 0x0AU, 0x41U, 0x8AU,
0x01U, 0x10U, 0x07U, 0x21U, 0x05U, 0x20U, 0x05U, 0x1AU, 0x41U, 0xA0U,
0x09U, 0x41U, 0xB1U, 0x02U, 0x10U, 0x08U, 0x21U, 0x01U, 0x20U, 0x0BU,
0x20U, 0x01U, 0x37U, 0x03U, 0x38U, 0x20U, 0x0BU, 0x41U, 0xF0U, 0x09U,
0x36U, 0x02U, 0x34U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x38U, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0x38U, 0x87U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U,
0x3FU, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xC0U, 0x00U, 0x7CU,
0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U,
0x02U, 0x34U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U,
0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x34U, 0x20U, 0x0AU,
0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x38U,
0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x30U, 0x87U, 0x21U, 0x01U, 0x20U,
0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U,
0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x34U, 0x21U, 0x0AU, 0x20U,
0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU,
0x36U, 0x02U, 0x34U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U,
0x20U, 0x0BU, 0x29U, 0x03U, 0x38U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U,
0x28U, 0x87U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U,
0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U,
0x02U, 0x34U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U,
0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x34U, 0x20U, 0x0AU,
0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x38U,
0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x20U, 0x87U, 0x21U, 0x01U, 0x20U,
0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U,
0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x34U, 0x21U, 0x0AU, 0x20U,
0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU,
0x36U, 0x02U, 0x34U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U,
0x20U, 0x0BU, 0x29U, 0x03U, 0x38U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U,
0x18U, 0x87U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U,
0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U,
0x02U, 0x34U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U,
0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x34U, 0x20U, 0x0AU,
0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x38U,
0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x10U, 0x87U, 0x21U, 0x01U, 0x20U,
0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U,
0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x34U, 0x21U, 0x0AU, 0x20U,
0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU,
0x36U, 0x02U, 0x34U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U,
0x20U, 0x0BU, 0x29U, 0x03U, 0x38U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U,
0x08U, 0x87U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U,
0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0BU, 0x28U,
0x02U, 0x34U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U,
0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU, 0x36U, 0x02U, 0x34U, 0x20U, 0x0AU,
0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0BU, 0x29U, 0x03U, 0x38U,
0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x00U, 0x87U, 0x21U, 0x01U, 0x20U,
0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U,
0x21U, 0x00U, 0x20U, 0x0BU, 0x28U, 0x02U, 0x34U, 0x21U, 0x0AU, 0x20U,
0x0AU, 0x41U, 0x01U, 0x6AU, 0x21U, 0x0CU, 0x20U, 0x0BU, 0x20U, 0x0CU,
0x36U, 0x02U, 0x34U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U,
0x41U, 0x80U, 0x08U, 0x41U, 0x03U, 0x41U, 0xA0U, 0x09U, 0x41U, 0xB1U,
0x02U, 0x41U, 0x01U, 0x10U, 0x01U, 0x21U, 0x06U, 0x20U, 0x06U, 0x1AU,
0x20U, 0x0BU, 0x41U, 0x10U, 0x6AU, 0x21U, 0x00U, 0x20U, 0x00U, 0x41U,
0x20U, 0x41U, 0xA0U, 0x09U, 0x41U, 0xB1U, 0x02U, 0x10U, 0x09U, 0x21U,
0x01U, 0x20U, 0x0BU, 0x20U, 0x01U, 0x37U, 0x03U, 0x08U, 0x20U, 0x0BU,
0x29U, 0x03U, 0x08U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x00U, 0x55U,
0x21U, 0x00U, 0x20U, 0x00U, 0x41U, 0x01U, 0x71U, 0x21U, 0x00U, 0x20U,
0x00U, 0x45U, 0x21U, 0x00U, 0x20U, 0x00U, 0x45U, 0x21U, 0x00U, 0x0BU,
0x20U, 0x00U, 0x04U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x41U, 0xA7U,
0x08U, 0x41U, 0x20U, 0x42U, 0xF5U, 0x00U, 0x10U, 0x00U, 0x21U, 0x07U,
0x20U, 0x07U, 0x1AU, 0x0BU, 0x01U, 0x0BU, 0x05U, 0x01U, 0x0BU, 0x0BU,
0x02U, 0x7EU, 0x02U, 0x7EU, 0x41U, 0xC7U, 0x08U, 0x41U, 0x20U, 0x42U,
0xF7U, 0x00U, 0x10U, 0x00U, 0x21U, 0x08U, 0x20U, 0x08U, 0x1AU, 0x41U,
0x01U, 0x41U, 0x01U, 0x10U, 0x0AU, 0x21U, 0x0DU, 0x20U, 0x0DU, 0x1AU,
0x20U, 0x0BU, 0x41U, 0x80U, 0x01U, 0x6AU, 0x21U, 0x00U, 0x20U, 0x00U,
0x24U, 0x00U, 0x42U, 0x00U, 0x21U, 0x09U, 0x42U, 0x00U, 0x0BU, 0x0BU,
0x0BU, 0x0BU, 0x0BU, 0x88U, 0x02U, 0x04U, 0x00U, 0x41U, 0x80U, 0x08U,
0x0BU, 0x90U, 0x01U, 0x74U, 0x78U, 0x6EU, 0x00U, 0x72U, 0x50U, 0x4DU,
0x68U, 0x37U, 0x50U, 0x69U, 0x39U, 0x63U, 0x74U, 0x36U, 0x39U, 0x39U,
0x69U, 0x5AU, 0x55U, 0x54U, 0x57U, 0x61U, 0x79U, 0x74U, 0x4AU, 0x55U,
0x6FU, 0x48U, 0x63U, 0x4AU, 0x37U, 0x63U, 0x67U, 0x79U, 0x7AU, 0x69U,
0x4BU, 0x00U, 0x63U, 0x61U, 0x6CU, 0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU,
0x2EU, 0x63U, 0x3AU, 0x20U, 0x54U, 0x78U, 0x20U, 0x65U, 0x6DU, 0x69U,
0x74U, 0x74U, 0x65U, 0x64U, 0x20U, 0x73U, 0x75U, 0x63U, 0x63U, 0x65U,
0x73U, 0x73U, 0x2EU, 0x00U, 0x63U, 0x61U, 0x6CU, 0x6CU, 0x62U, 0x61U,
0x63U, 0x6BU, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x54U, 0x78U, 0x20U, 0x65U,
0x6DU, 0x69U, 0x74U, 0x74U, 0x65U, 0x64U, 0x20U, 0x66U, 0x61U, 0x69U,
0x6CU, 0x75U, 0x72U, 0x65U, 0x2EU, 0x00U, 0x63U, 0x61U, 0x6CU, 0x6CU,
0x62U, 0x61U, 0x63U, 0x6BU, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x43U, 0x61U,
0x6CU, 0x6CU, 0x65U, 0x64U, 0x2EU, 0x00U, 0x22U, 0x63U, 0x61U, 0x6CU,
0x6CU, 0x62U, 0x61U, 0x63U, 0x6BU, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x43U,
0x61U, 0x6CU, 0x6CU, 0x65U, 0x64U, 0x2EU, 0x22U, 0x00U, 0x41U, 0xA0U,
0x09U, 0x0BU, 0x5AU, 0x12U, 0x00U, 0x00U, 0x22U, 0x80U, 0x00U, 0x00U,
0x00U, 0x24U, 0x00U, 0x00U, 0x00U, 0x00U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x20U, 0x1AU, 0x00U, 0x00U, 0x00U, 0x00U, 0x20U, 0x1BU, 0x00U,
0x00U, 0x00U, 0x00U, 0x61U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x68U, 0x40U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x73U, 0x21U, 0x00U, 0x41U, 0x9BU, 0x0AU, 0x0BU, 0x02U, 0x81U,
0x14U, 0x00U, 0x41U, 0xB1U, 0x0AU, 0x0BU, 0x02U, 0x83U, 0x14U};
const std::vector<uint8_t> TshHook = {
0x00U, 0x61U, 0x73U, 0x6dU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x1cU,
0x04U, 0x60U, 0x05U, 0x7fU, 0x7fU, 0x7fU, 0x7fU, 0x7fU, 0x01U, 0x7eU,
0x60U, 0x03U, 0x7fU, 0x7fU, 0x7eU, 0x01U, 0x7eU, 0x60U, 0x02U, 0x7fU,
0x7fU, 0x01U, 0x7fU, 0x60U, 0x01U, 0x7fU, 0x01U, 0x7eU, 0x02U, 0x23U,
0x03U, 0x03U, 0x65U, 0x6eU, 0x76U, 0x05U, 0x74U, 0x72U, 0x61U, 0x63U,
0x65U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6eU, 0x76U, 0x06U, 0x61U, 0x63U,
0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6eU, 0x76U,
0x02U, 0x5fU, 0x67U, 0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x03U, 0x05U,
0x03U, 0x01U, 0x00U, 0x02U, 0x06U, 0x2bU, 0x07U, 0x7fU, 0x01U, 0x41U,
0xc0U, 0x8bU, 0x04U, 0x0bU, 0x7fU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0bU,
0x7fU, 0x00U, 0x41U, 0xb8U, 0x0bU, 0x0bU, 0x7fU, 0x00U, 0x41U, 0x80U,
0x08U, 0x0bU, 0x7fU, 0x00U, 0x41U, 0xc0U, 0x8bU, 0x04U, 0x0bU, 0x7fU,
0x00U, 0x41U, 0x00U, 0x0bU, 0x7fU, 0x00U, 0x41U, 0x01U, 0x0bU, 0x07U,
0x08U, 0x01U, 0x04U, 0x68U, 0x6fU, 0x6fU, 0x6bU, 0x00U, 0x03U, 0x0aU,
0xf3U, 0x81U, 0x00U, 0x01U, 0xefU, 0x81U, 0x00U, 0x01U, 0x01U, 0x7fU,
0x23U, 0x00U, 0x41U, 0x10U, 0x6bU, 0x22U, 0x01U, 0x24U, 0x00U, 0x20U,
0x01U, 0x20U, 0x00U, 0x36U, 0x02U, 0x0cU, 0x41U, 0x9aU, 0x0bU, 0x41U,
0x0fU, 0x41U, 0xbdU, 0x09U, 0x41U, 0x0eU, 0x41U, 0x00U, 0x10U, 0x00U,
0x1aU, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x20U,
0x01U, 0x28U, 0x02U, 0x0cU, 0x0eU, 0x03U, 0x00U, 0x01U, 0x02U, 0x03U,
0x0bU, 0x41U, 0xd9U, 0x0aU, 0x41U, 0xc0U, 0x00U, 0x41U, 0xfeU, 0x08U,
0x41U, 0x3fU, 0x41U, 0x00U, 0x10U, 0x00U, 0x1aU, 0x0cU, 0x02U, 0x0bU,
0x41U, 0x9bU, 0x0aU, 0x41U, 0x3dU, 0x41U, 0xc2U, 0x08U, 0x41U, 0x3cU,
0x41U, 0x00U, 0x10U, 0x00U, 0x1aU, 0x0cU, 0x01U, 0x0bU, 0x41U, 0xd7U,
0x09U, 0x41U, 0xc3U, 0x00U, 0x41U, 0x80U, 0x08U, 0x41U, 0xc2U, 0x00U,
0x41U, 0x00U, 0x10U, 0x00U, 0x1aU, 0x0bU, 0x41U, 0xaaU, 0x0bU, 0x41U,
0x0dU, 0x41U, 0xcbU, 0x09U, 0x41U, 0x0cU, 0x41U, 0x00U, 0x10U, 0x00U,
0x1aU, 0x20U, 0x01U, 0x20U, 0x01U, 0x41U, 0x08U, 0x6aU, 0x22U, 0x00U,
0x36U, 0x02U, 0x04U, 0x20U, 0x01U, 0x28U, 0x02U, 0x04U, 0x20U, 0x01U,
0x35U, 0x02U, 0x0cU, 0x42U, 0x18U, 0x88U, 0x42U, 0xffU, 0x01U, 0x83U,
0x3cU, 0x00U, 0x00U, 0x20U, 0x01U, 0x28U, 0x02U, 0x04U, 0x20U, 0x01U,
0x35U, 0x02U, 0x0cU, 0x42U, 0x10U, 0x88U, 0x42U, 0xffU, 0x01U, 0x83U,
0x3cU, 0x00U, 0x01U, 0x20U, 0x01U, 0x28U, 0x02U, 0x04U, 0x20U, 0x01U,
0x35U, 0x02U, 0x0cU, 0x42U, 0x08U, 0x88U, 0x42U, 0xffU, 0x01U, 0x83U,
0x3cU, 0x00U, 0x02U, 0x20U, 0x01U, 0x28U, 0x02U, 0x04U, 0x20U, 0x01U,
0x35U, 0x02U, 0x0cU, 0x42U, 0xffU, 0x01U, 0x83U, 0x3cU, 0x00U, 0x03U,
0x20U, 0x00U, 0x41U, 0x04U, 0x42U, 0x18U, 0x10U, 0x01U, 0x1aU, 0x41U,
0x01U, 0x41U, 0x01U, 0x10U, 0x02U, 0x1aU, 0x20U, 0x01U, 0x41U, 0x10U,
0x6aU, 0x24U, 0x00U, 0x42U, 0x00U, 0x0bU, 0x0bU, 0xbfU, 0x03U, 0x01U,
0x00U, 0x41U, 0x80U, 0x08U, 0x0bU, 0xb7U, 0x03U, 0x74U, 0x73U, 0x68U,
0x2eU, 0x63U, 0x3aU, 0x20U, 0x57U, 0x65U, 0x61U, 0x6bU, 0x20U, 0x41U,
0x67U, 0x61U, 0x69U, 0x6eU, 0x2eU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U,
0x75U, 0x74U, 0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U,
0x74U, 0x72U, 0x61U, 0x6eU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6fU,
0x6eU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6cU, 0x69U,
0x65U, 0x64U, 0x20U, 0x74U, 0x6fU, 0x20U, 0x6cU, 0x65U, 0x64U, 0x67U,
0x65U, 0x72U, 0x00U, 0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U,
0x57U, 0x65U, 0x61U, 0x6bU, 0x2eU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U,
0x75U, 0x74U, 0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U,
0x74U, 0x72U, 0x61U, 0x6eU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6fU,
0x6eU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6cU, 0x69U,
0x65U, 0x64U, 0x20U, 0x74U, 0x6fU, 0x20U, 0x6cU, 0x65U, 0x64U, 0x67U,
0x65U, 0x72U, 0x00U, 0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U,
0x53U, 0x74U, 0x72U, 0x6fU, 0x6eU, 0x67U, 0x2eU, 0x20U, 0x45U, 0x78U,
0x65U, 0x63U, 0x75U, 0x74U, 0x65U, 0x20U, 0x42U, 0x45U, 0x46U, 0x4fU,
0x52U, 0x45U, 0x20U, 0x74U, 0x72U, 0x61U, 0x6eU, 0x73U, 0x61U, 0x63U,
0x74U, 0x69U, 0x6fU, 0x6eU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U,
0x70U, 0x6cU, 0x69U, 0x65U, 0x64U, 0x20U, 0x74U, 0x6fU, 0x20U, 0x6cU,
0x65U, 0x64U, 0x67U, 0x65U, 0x72U, 0x00U, 0x74U, 0x73U, 0x68U, 0x2eU,
0x63U, 0x3aU, 0x20U, 0x53U, 0x74U, 0x61U, 0x72U, 0x74U, 0x2eU, 0x00U,
0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U, 0x45U, 0x6eU, 0x64U,
0x2eU, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U,
0x57U, 0x65U, 0x61U, 0x6bU, 0x20U, 0x41U, 0x67U, 0x61U, 0x69U, 0x6eU,
0x2eU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U, 0x75U, 0x74U, 0x65U, 0x20U,
0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U, 0x74U, 0x72U, 0x61U, 0x6eU,
0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6fU, 0x6eU, 0x20U, 0x69U, 0x73U,
0x20U, 0x61U, 0x70U, 0x70U, 0x6cU, 0x69U, 0x65U, 0x64U, 0x20U, 0x74U,
0x6fU, 0x20U, 0x6cU, 0x65U, 0x64U, 0x67U, 0x65U, 0x72U, 0x22U, 0x00U,
0x22U, 0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U, 0x57U, 0x65U,
0x61U, 0x6bU, 0x2eU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U, 0x75U, 0x74U,
0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U, 0x74U, 0x72U,
0x61U, 0x6eU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6fU, 0x6eU, 0x20U,
0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6cU, 0x69U, 0x65U, 0x64U,
0x20U, 0x74U, 0x6fU, 0x20U, 0x6cU, 0x65U, 0x64U, 0x67U, 0x65U, 0x72U,
0x22U, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U,
0x53U, 0x74U, 0x72U, 0x6fU, 0x6eU, 0x67U, 0x2eU, 0x20U, 0x45U, 0x78U,
0x65U, 0x63U, 0x75U, 0x74U, 0x65U, 0x20U, 0x42U, 0x45U, 0x46U, 0x4fU,
0x52U, 0x45U, 0x20U, 0x74U, 0x72U, 0x61U, 0x6eU, 0x73U, 0x61U, 0x63U,
0x74U, 0x69U, 0x6fU, 0x6eU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U,
0x70U, 0x6cU, 0x69U, 0x65U, 0x64U, 0x20U, 0x74U, 0x6fU, 0x20U, 0x6cU,
0x65U, 0x64U, 0x67U, 0x65U, 0x72U, 0x22U, 0x00U, 0x22U, 0x74U, 0x73U,
0x68U, 0x2eU, 0x63U, 0x3aU, 0x20U, 0x53U, 0x74U, 0x61U, 0x72U, 0x74U,
0x2eU, 0x22U, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U, 0x2eU, 0x63U, 0x3aU,
0x20U, 0x45U, 0x6eU, 0x64U, 0x2eU, 0x22U};
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x28U,
0x06U, 0x60U, 0x05U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU,
0x60U, 0x04U, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x00U,
0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U,
0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU,
0x02U, 0x45U, 0x05U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x05U, 0x74U, 0x72U,
0x61U, 0x63U, 0x65U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0AU,
0x6FU, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x70U, 0x61U, 0x72U, 0x61U, 0x6DU,
0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0AU, 0x68U, 0x6FU, 0x6FU,
0x6BU, 0x5FU, 0x61U, 0x67U, 0x61U, 0x69U, 0x6EU, 0x00U, 0x02U, 0x03U,
0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U,
0x00U, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U,
0x04U, 0x03U, 0x02U, 0x01U, 0x05U, 0x05U, 0x03U, 0x01U, 0x00U, 0x02U,
0x06U, 0x2BU, 0x07U, 0x7FU, 0x01U, 0x41U, 0xC0U, 0x8BU, 0x04U, 0x0BU,
0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xBCU,
0x0BU, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U,
0x41U, 0xC0U, 0x8BU, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x00U, 0x0BU,
0x7FU, 0x00U, 0x41U, 0x01U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U,
0x6FU, 0x6FU, 0x6BU, 0x00U, 0x05U, 0x0AU, 0x8EU, 0x84U, 0x00U, 0x01U,
0x8AU, 0x84U, 0x00U, 0x02U, 0x09U, 0x7EU, 0x05U, 0x7FU, 0x02U, 0x40U,
0x02U, 0x40U, 0x23U, 0x00U, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x41U, 0x10U,
0x6BU, 0x21U, 0x0AU, 0x20U, 0x0AU, 0x24U, 0x00U, 0x20U, 0x0AU, 0x20U,
0x00U, 0x36U, 0x02U, 0x0CU, 0x41U, 0x9EU, 0x0BU, 0x41U, 0x0FU, 0x41U,
0xC1U, 0x09U, 0x41U, 0x0EU, 0x41U, 0x00U, 0x10U, 0x00U, 0x21U, 0x02U,
0x20U, 0x02U, 0x1AU, 0x20U, 0x0AU, 0x41U, 0x0BU, 0x6AU, 0x21U, 0x00U,
0x20U, 0x00U, 0x41U, 0x01U, 0x41U, 0xBDU, 0x09U, 0x41U, 0x03U, 0x10U,
0x01U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x01U, 0x51U, 0x21U, 0x00U,
0x20U, 0x00U, 0x41U, 0x01U, 0x71U, 0x21U, 0x00U, 0x20U, 0x00U, 0x45U,
0x21U, 0x00U, 0x20U, 0x00U, 0x45U, 0x21U, 0x00U, 0x0BU, 0x20U, 0x00U,
0x04U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x10U, 0x02U, 0x21U, 0x03U,
0x20U, 0x03U, 0x1AU, 0x0BU, 0x01U, 0x0BU, 0x05U, 0x01U, 0x0BU, 0x0BU,
0x02U, 0x7EU, 0x02U, 0x40U, 0x20U, 0x0AU, 0x28U, 0x02U, 0x0CU, 0x21U,
0x00U, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U,
0x40U, 0x20U, 0x00U, 0x0EU, 0x03U, 0x02U, 0x01U, 0x00U, 0x04U, 0x0BU,
0x02U, 0x40U, 0x02U, 0x40U, 0x02U, 0x40U, 0x41U, 0xDBU, 0x09U, 0x41U,
0xC3U, 0x00U, 0x41U, 0x80U, 0x08U, 0x41U, 0xC2U, 0x00U, 0x41U, 0x00U,
0x10U, 0x00U, 0x21U, 0x04U, 0x20U, 0x04U, 0x1AU, 0x0BU, 0x0CU, 0x06U,
0x0BU, 0x00U, 0x0BU, 0x00U, 0x0BU, 0x02U, 0x40U, 0x02U, 0x40U, 0x02U,
0x40U, 0x41U, 0x9FU, 0x0AU, 0x41U, 0x3DU, 0x41U, 0xC2U, 0x08U, 0x41U,
0x3CU, 0x41U, 0x00U, 0x10U, 0x00U, 0x21U, 0x05U, 0x20U, 0x05U, 0x1AU,
0x0BU, 0x0CU, 0x05U, 0x0BU, 0x00U, 0x0BU, 0x00U, 0x0BU, 0x02U, 0x40U,
0x02U, 0x40U, 0x02U, 0x40U, 0x41U, 0xDDU, 0x0AU, 0x41U, 0xC0U, 0x00U,
0x41U, 0xFEU, 0x08U, 0x41U, 0x3FU, 0x41U, 0x00U, 0x10U, 0x00U, 0x21U,
0x06U, 0x20U, 0x06U, 0x1AU, 0x0BU, 0x01U, 0x0BU, 0x0BU, 0x0BU, 0x0BU,
0x0BU, 0x02U, 0x7EU, 0x02U, 0x7EU, 0x41U, 0xAEU, 0x0BU, 0x41U, 0x0DU,
0x41U, 0xCFU, 0x09U, 0x41U, 0x0CU, 0x41U, 0x00U, 0x10U, 0x00U, 0x21U,
0x07U, 0x20U, 0x07U, 0x1AU, 0x20U, 0x0AU, 0x41U, 0x07U, 0x6AU, 0x21U,
0x0CU, 0x20U, 0x0CU, 0x21U, 0x00U, 0x20U, 0x0AU, 0x20U, 0x00U, 0x36U,
0x02U, 0x00U, 0x20U, 0x0AU, 0x28U, 0x02U, 0x0CU, 0x21U, 0x00U, 0x20U,
0x00U, 0xADU, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x18U, 0x88U, 0x21U,
0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U,
0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0AU, 0x28U, 0x02U, 0x00U, 0x21U,
0x0BU, 0x20U, 0x0BU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x00U, 0x20U, 0x0AU,
0x28U, 0x02U, 0x0CU, 0x21U, 0x00U, 0x20U, 0x00U, 0xADU, 0x21U, 0x01U,
0x20U, 0x01U, 0x42U, 0x10U, 0x88U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U,
0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U,
0x20U, 0x0AU, 0x28U, 0x02U, 0x00U, 0x21U, 0x0BU, 0x20U, 0x0BU, 0x20U,
0x00U, 0x3AU, 0x00U, 0x01U, 0x20U, 0x0AU, 0x28U, 0x02U, 0x0CU, 0x21U,
0x00U, 0x20U, 0x00U, 0xADU, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x08U,
0x88U, 0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U,
0x01U, 0x20U, 0x01U, 0xA7U, 0x21U, 0x00U, 0x20U, 0x0AU, 0x28U, 0x02U,
0x00U, 0x21U, 0x0BU, 0x20U, 0x0BU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x02U,
0x20U, 0x0AU, 0x28U, 0x02U, 0x0CU, 0x21U, 0x00U, 0x20U, 0x00U, 0xADU,
0x21U, 0x01U, 0x20U, 0x01U, 0x42U, 0x00U, 0x88U, 0x21U, 0x01U, 0x20U,
0x01U, 0x42U, 0xFFU, 0x01U, 0x83U, 0x21U, 0x01U, 0x20U, 0x01U, 0xA7U,
0x21U, 0x00U, 0x20U, 0x0AU, 0x28U, 0x02U, 0x00U, 0x21U, 0x0BU, 0x20U,
0x0BU, 0x20U, 0x00U, 0x3AU, 0x00U, 0x03U, 0x20U, 0x0CU, 0x21U, 0x00U,
0x20U, 0x00U, 0x41U, 0x04U, 0x42U, 0x1CU, 0x10U, 0x03U, 0x21U, 0x08U,
0x20U, 0x08U, 0x1AU, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x04U, 0x21U,
0x0DU, 0x20U, 0x0DU, 0x1AU, 0x20U, 0x0AU, 0x41U, 0x10U, 0x6AU, 0x21U,
0x00U, 0x20U, 0x00U, 0x24U, 0x00U, 0x42U, 0x00U, 0x21U, 0x09U, 0x42U,
0x00U, 0x0BU, 0x0BU, 0x0BU, 0x0BU, 0x0BU, 0xC3U, 0x03U, 0x01U, 0x00U,
0x41U, 0x80U, 0x08U, 0x0BU, 0xBBU, 0x03U, 0x74U, 0x73U, 0x68U, 0x2EU,
0x63U, 0x3AU, 0x20U, 0x57U, 0x65U, 0x61U, 0x6BU, 0x20U, 0x41U, 0x67U,
0x61U, 0x69U, 0x6EU, 0x2EU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U, 0x75U,
0x74U, 0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U, 0x74U,
0x72U, 0x61U, 0x6EU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU,
0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6CU, 0x69U, 0x65U,
0x64U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x6CU, 0x65U, 0x64U, 0x67U, 0x65U,
0x72U, 0x00U, 0x74U, 0x73U, 0x68U, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x57U,
0x65U, 0x61U, 0x6BU, 0x2EU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U, 0x75U,
0x74U, 0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U, 0x74U,
0x72U, 0x61U, 0x6EU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU,
0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6CU, 0x69U, 0x65U,
0x64U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x6CU, 0x65U, 0x64U, 0x67U, 0x65U,
0x72U, 0x00U, 0x74U, 0x73U, 0x68U, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x53U,
0x74U, 0x72U, 0x6FU, 0x6EU, 0x67U, 0x2EU, 0x20U, 0x45U, 0x78U, 0x65U,
0x63U, 0x75U, 0x74U, 0x65U, 0x20U, 0x42U, 0x45U, 0x46U, 0x4FU, 0x52U,
0x45U, 0x20U, 0x74U, 0x72U, 0x61U, 0x6EU, 0x73U, 0x61U, 0x63U, 0x74U,
0x69U, 0x6FU, 0x6EU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U,
0x6CU, 0x69U, 0x65U, 0x64U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x6CU, 0x65U,
0x64U, 0x67U, 0x65U, 0x72U, 0x00U, 0x41U, 0x41U, 0x57U, 0x00U, 0x74U,
0x73U, 0x68U, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x53U, 0x74U, 0x61U, 0x72U,
0x74U, 0x2EU, 0x00U, 0x74U, 0x73U, 0x68U, 0x2EU, 0x63U, 0x3AU, 0x20U,
0x45U, 0x6EU, 0x64U, 0x2EU, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U, 0x2EU,
0x63U, 0x3AU, 0x20U, 0x57U, 0x65U, 0x61U, 0x6BU, 0x20U, 0x41U, 0x67U,
0x61U, 0x69U, 0x6EU, 0x2EU, 0x20U, 0x45U, 0x78U, 0x65U, 0x63U, 0x75U,
0x74U, 0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U, 0x20U, 0x74U,
0x72U, 0x61U, 0x6EU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU,
0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6CU, 0x69U, 0x65U,
0x64U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x6CU, 0x65U, 0x64U, 0x67U, 0x65U,
0x72U, 0x22U, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U, 0x2EU, 0x63U, 0x3AU,
0x20U, 0x57U, 0x65U, 0x61U, 0x6BU, 0x2EU, 0x20U, 0x45U, 0x78U, 0x65U,
0x63U, 0x75U, 0x74U, 0x65U, 0x20U, 0x41U, 0x46U, 0x54U, 0x45U, 0x52U,
0x20U, 0x74U, 0x72U, 0x61U, 0x6EU, 0x73U, 0x61U, 0x63U, 0x74U, 0x69U,
0x6FU, 0x6EU, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, 0x70U, 0x70U, 0x6CU,
0x69U, 0x65U, 0x64U, 0x20U, 0x74U, 0x6FU, 0x20U, 0x6CU, 0x65U, 0x64U,
0x67U, 0x65U, 0x72U, 0x22U, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U, 0x2EU,
0x63U, 0x3AU, 0x20U, 0x53U, 0x74U, 0x72U, 0x6FU, 0x6EU, 0x67U, 0x2EU,
0x20U, 0x45U, 0x78U, 0x65U, 0x63U, 0x75U, 0x74U, 0x65U, 0x20U, 0x42U,
0x45U, 0x46U, 0x4FU, 0x52U, 0x45U, 0x20U, 0x74U, 0x72U, 0x61U, 0x6EU,
0x73U, 0x61U, 0x63U, 0x74U, 0x69U, 0x6FU, 0x6EU, 0x20U, 0x69U, 0x73U,
0x20U, 0x61U, 0x70U, 0x70U, 0x6CU, 0x69U, 0x65U, 0x64U, 0x20U, 0x74U,
0x6FU, 0x20U, 0x6CU, 0x65U, 0x64U, 0x67U, 0x65U, 0x72U, 0x22U, 0x00U,
0x22U, 0x74U, 0x73U, 0x68U, 0x2EU, 0x63U, 0x3AU, 0x20U, 0x53U, 0x74U,
0x61U, 0x72U, 0x74U, 0x2EU, 0x22U, 0x00U, 0x22U, 0x74U, 0x73U, 0x68U,
0x2EU, 0x63U, 0x3AU, 0x20U, 0x45U, 0x6EU, 0x64U, 0x2EU, 0x22U};
void
addWeakTSH(jtx::Env& env, jtx::Account const& account)
@@ -151,7 +428,21 @@ private:
using namespace test::jtx;
auto const tshFlag = testStrong ? overrideFlag : collectFlag;
env(hook(account, {{hso(TshHook, tshFlag)}}, 0),
fee(XRP(1)),
fee(XRP(2)),
ter(tesSUCCESS));
env.close();
}
void
setCallbackHook(
jtx::Env& env,
jtx::Account const& account,
bool const& testStrong)
{
using namespace test::jtx;
auto const tshFlag = testStrong ? overrideFlag : collectFlag;
env(hook(account, {{hso(CallbackHook, tshFlag)}}, 0),
fee(XRP(2)),
ter(tesSUCCESS));
env.close();
}
@@ -219,6 +510,22 @@ private:
}
}
void
validateTSHFlags(jtx::Env& env, Json::Value meta, uint32_t const& expected)
{
auto const executions = meta[sfHookExecutions.jsonName];
auto const execution = executions[0u][sfHookExecution.jsonName];
bool const fixV2 = env.current()->rules().enabled(fixXahauV2);
if (fixV2)
{
BEAST_EXPECT(execution[sfFlags.jsonName] == expected);
}
else
{
BEAST_REQUIRE(!execution[sfFlags.jsonName]);
}
}
void
testTSHStrongWeak(
jtx::Env& env,
@@ -1776,7 +2083,7 @@ private:
{{hso(TshHook, overrideFlag),
hso(genesis::MintTestHook, overrideFlag)}},
0),
fee(XRP(1)),
fee(XRP(2)),
ter(tesSUCCESS));
env.close();
@@ -1960,7 +2267,11 @@ private:
env.close();
// verify tsh hook triggered
testTSHStrongWeak(env, tshSTRONG, __LINE__);
bool const fixV2 = env.current()->rules().enabled(fixXahauV2);
auto const expected =
(fixV2 ? (testStrong ? tshNONE : tshWEAK)
: (testStrong ? tshSTRONG : tshSTRONG));
testTSHStrongWeak(env, expected, __LINE__);
}
}
@@ -2159,9 +2470,14 @@ private:
auto const USD = gw["USD"];
env.fund(XRP(1000), account, cross, gw);
env.close();
env.trust(USD(100000), account);
env.trust(USD(100000), cross);
env.close();
env(pay(gw, cross, USD(10000)));
env.close();
// gw create offer
env(offer(gw, USD(1000), XRP(1000)));
env(offer(cross, XRP(1000), USD(1000)));
env.close();
// set tsh collect
@@ -2178,7 +2494,8 @@ private:
env.close();
// verify tsh hook triggered
testTSHStrongWeak(env, tshNONE, __LINE__);
auto const expected = testStrong ? tshNONE : tshWEAK;
testTSHStrongWeak(env, expected, __LINE__);
}
}
@@ -3024,16 +3341,16 @@ private:
// | otxn | tfBurnable | tsh | mint | burn | buy | sell | cancel
// | O | false | O | N/A | S | N/A | S | S
// | O | false | I | N/A | N | N/A | W | N/A
// | O | false | B | N/A | N/A | N/A | N | N/A
// | O | true | B | N/A | N/A | N/A | N | N/A
// | O | false | B | N/A | N/A | N/A | N | N
// | O | true | B | N/A | N/A | N/A | N | N
// | O | true | O | N/A | S | N/A | S | S
// | O | true | I | N/A | N | N/A | S | N/A
// | I | false | O | N/A | N/A | N/A | N/A | N/A
// | I | false | I | S | N/A | N/A | N/A | N/A
// | I | false | B | N | N/A | N/A | N/A | N/A
// | I | false | B | S | N/A | N/A | N/A | N/A
// | I | true | O | N/A | N | N/A | N/A | N/A
// | I | true | I | S | S | N/A | N/A | N/A
// | I | true | B | N | N/A | N/A | N/A | N/A
// | I | true | B | S | N/A | N/A | N/A | N/A
// | B | true | O | N/A | N/A | S | N/A | N/A
// | B | true | B | N/A | N/A | S | N/A | N/A
// | B | false | I | N/A | N/A | W | N/A | N/A
@@ -3089,7 +3406,7 @@ private:
// otxn: issuer
// flag: not burnable
// tsh buyer
// w/s: none
// w/s: strong
for (bool const testStrong : {true, false})
{
test::jtx::Env env{
@@ -3122,7 +3439,11 @@ private:
env.close();
// verify tsh hook triggered
testTSHStrongWeak(env, tshNONE, __LINE__);
bool const fixV2 = env.current()->rules().enabled(fixXahauV2);
auto const expected =
(fixV2 ? (testStrong ? tshSTRONG : tshSTRONG)
: (testStrong ? tshNONE : tshNONE));
testTSHStrongWeak(env, expected, __LINE__);
}
// otxn: issuer
@@ -3168,7 +3489,7 @@ private:
// otxn: issuer
// flag: burnable
// tsh buyer
// w/s: none
// w/s: strong
for (bool const testStrong : {true, false})
{
test::jtx::Env env{
@@ -3202,7 +3523,11 @@ private:
env.close();
// verify tsh hook triggered
testTSHStrongWeak(env, tshNONE, __LINE__);
bool const fixV2 = env.current()->rules().enabled(fixXahauV2);
auto const expected =
(fixV2 ? (testStrong ? tshSTRONG : tshSTRONG)
: (testStrong ? tshNONE : tshNONE));
testTSHStrongWeak(env, expected, __LINE__);
}
}
@@ -4351,133 +4676,11 @@ private:
env.fund(XRP(1000), account, dest);
env.close();
auto setHook = [](test::jtx::Account const& account) {
std::string const createCodeHex =
"0061736D0100000001350860057F7F7F7F7F017E60017F017E60047F7F7F7F"
"017E60037F7F7E017E60027F7F017E60037F7F7F017E60027F7F017F600001"
"7E02CD010D03656E76057472616365000003656E760C6574786E5F72657365"
"727665000103656E760A7574696C5F6163636964000203656E760974726163"
"655F6E756D000303656E760C686F6F6B5F6163636F756E74000403656E760A"
"6F74786E5F6669656C64000503656E7608726F6C6C6261636B000303656E76"
"025F67000603656E7606616363657074000303656E760A6C65646765725F73"
"6571000703656E760C6574786E5F64657461696C73000403656E760D657478"
"6E5F6665655F62617365000403656E7604656D697400020303020101050301"
"0002062B077F0141C08C040B7F004180080B7F0041B40C0B7F004180080B7F"
"0041C08C040B7F0041000B7F0041010B070F02046362616B000D04686F6F6B"
"000E0AE1930002AC800001017F230041106B220124002001200036020C41F6"
"0B411A41B70A4119410010001A200141106A240042000BAE930002017F017C"
"230041B0056B22012400200120003602AC0541E40B411141840A4110410010"
"001A410110011A200120014190056A411441940A4123100237038805418C08"
"410320012903880510031A200141F0046A411410041A2001200141D0046A41"
"144181802010053E02CC0441E409411120013402CC0410031A20012802CC04"
"411448044041910C4123420110061A0B200141003602C804200141013602C8"
"04200141003602C4040340418180B48178411510071A4100210020012802C8"
"04047F20012802C4044114480520000B4101710440200120012802C4042001"
"41F0046A6A2D000020012802C404200141D0046A6A2D0000463602C8042001"
"20012802C40441016A3602C4040C010B0B20012802C804450440419B08411D"
"420210081A0B200120014190046A413041818018100537038804200142C084"
"3D370380040240200129038804420852044041D00A41CE0041D40841CD0041"
"0010001A0C010B419F0B41C40041A10941C300410010001A200120012D0090"
"04410776047E427E052001310097042001310090044291A2C480B001834238"
"862001310091044230867C2001310092044228867C2001310093044220867C"
"2001310094044218867C2001310095044210867C2001310096044208867C7C"
"0B3703F803419008410A20012903F80310031A20012903F80342A08D065504"
"402001027E20012903F803B94400000040E17A843FA2220299440000000000"
"00E0436304402002B00C010B428080808080808080807F0B370380040B0B41"
"F609410D20012903800410031A2001200141E0016A3602DC01200120012903"
"80043703B801200141003602B401200141003602B001200110093E02AC0120"
"0141C0016A411410041A200141003A00AB0120012802DC0141123A00002001"
"2802DC0120012D00AB014108763A000120012802DC0120012D00AB013A0002"
"200120012802DC0141036A3602DC0120014180808080783602A40120014102"
"3A00A30120012802DC0120012D00A301410F7141206A3A000020012802DC01"
"20012802A4014118763A000120012802DC0120012802A4014110763A000220"
"012802DC0120012802A4014108763A000320012802DC0120012802A4013A00"
"04200120012802DC0141056A3602DC01200120012802B00136029C01200141"
"033A009B0120012802DC0120012D009B01410F7141206A3A000020012802DC"
"01200128029C014118763A000120012802DC01200128029C014110763A0002"
"20012802DC01200128029C014108763A000320012802DC01200128029C013A"
"0004200120012802DC0141056A3602DC012001410036029401200141043A00"
"930120012802DC0120012D009301410F7141206A3A000020012802DC012001"
"280294014118763A000120012802DC012001280294014110763A0002200128"
"02DC012001280294014108763A000320012802DC012001280294013A000420"
"0120012802DC0141056A3602DC01200120012802B40136028C012001410E3A"
"008B0120012802DC0120012D008B01410F7141206A3A000020012802DC0120"
"0128028C014118763A000120012802DC01200128028C014110763A00022001"
"2802DC01200128028C014108763A000320012802DC01200128028C013A0004"
"200120012802DC0141056A3602DC01200120012802AC0141016A3602840120"
"01411A3A00830120012802DC0141203A000020012802DC0120012D0083013A"
"000120012802DC012001280284014118763A000220012802DC012001280284"
"014110763A000320012802DC012001280284014108763A000420012802DC01"
"2001280284013A0005200120012802DC0141066A3602DC01200120012802AC"
"0141056A36027C2001411B3A007B20012802DC0141203A000020012802DC01"
"20012D007B3A000120012802DC01200128027C4118763A000220012802DC01"
"200128027C4110763A000320012802DC01200128027C4108763A0004200128"
"02DC01200128027C3A0005200120012802DC0141066A3602DC01200141013A"
"007A200120012903B80137037020012802DC0120012D007A410F7141E0006A"
"3A000020012802DC012001290370423888423F8342407D3C000120012802DC"
"01200129037042308842FF01833C000220012802DC01200129037042288842"
"FF01833C000320012802DC01200129037042208842FF01833C000420012802"
"DC01200129037042188842FF01833C000520012802DC012001290370421088"
"42FF01833C000620012802DC01200129037042088842FF01833C0007200128"
"02DC01200129037042FF01833C0008200120012802DC0141096A3602DC0120"
"0120012802DC0136026C200141083A006B2001420037036020012802DC0120"
"012D006B410F7141E0006A3A000020012802DC012001290360423888423F83"
"42407D3C000120012802DC01200129036042308842FF01833C000220012802"
"DC01200129036042288842FF01833C000320012802DC012001290360422088"
"42FF01833C000420012802DC01200129036042188842FF01833C0005200128"
"02DC01200129036042108842FF01833C000620012802DC0120012903604208"
"8842FF01833C000720012802DC01200129036042FF01833C00082001200128"
"02DC0141096A3602DC0120012802DC0141F3003A000020012802DC0141213A"
"000120012802DC01420037030220012802DC01420037030A20012802DC0142"
"0037031220012802DC014200370319200120012802DC0141236A3602DC0120"
"0141013A005F20012802DC0120012D005F4180016A3A000020012802DC0141"
"143A000120012802DC0120012903C00137030220012802DC0120012903C801"
"37030A20012802DC0120012802D001360212200120012802DC0141166A3602"
"DC01200141033A005E20012802DC0120012D005E4180016A3A000020012802"
"DC0141143A000120012802DC0120012903900537030220012802DC01200129"
"03980537030A20012802DC0120012802A005360212200120012802DC014116"
"6A3602DC01200120012802DC01418E02100A3703502001200141E0016A418E"
"02100B370348200141083A004720012001290348370338200128026C20012D"
"0047410F7141E0006A3A0000200128026C2001290338423888423F8342407D"
"3C0001200128026C200129033842308842FF01833C0002200128026C200129"
"033842288842FF01833C0003200128026C200129033842208842FF01833C00"
"04200128026C200129033842188842FF01833C0005200128026C2001290338"
"42108842FF01833C0006200128026C200129033842088842FF01833C000720"
"0128026C200129033842FF01833C00082001200128026C41096A36026C2001"
"200141106A4120200141E0016A418E02100C370308418008410B2001290308"
"10031A41B808411C420010081A200141B0056A240042000B0BBB0401004180"
"080BB304656D69745F726573756C7400726574006F74786E5F64726F707300"
"436172626F6E3A20496E636F6D696E67207472616E73616374696F6E004361"
"72626F6E3A20456D6974746564207472616E73616374696F6E00436172626F"
"6E3A204E6F6E2D787270207472616E73616374696F6E206465746563746564"
"2C2073656E64696E672064656661756C7420313030302064726F707320746F"
"207266436172626F6E00436172626F6E3A20585250207472616E7361637469"
"6F6E2064657465637465642C20636F6D707574696E6720312520746F207365"
"6E6420746F207266436172626F6E006163636F756E745F6669656C645F6C65"
"6E0064726F70735F746F5F73656E6400436172626F6E3A2073746172746564"
"0072504D68375069396374363939695A5554576179744A556F48634A376367"
"797A694B00436172626F6E3A2063616C6C6261636B2063616C6C65642E0022"
"436172626F6E3A204E6F6E2D787270207472616E73616374696F6E20646574"
"65637465642C2073656E64696E672064656661756C7420313030302064726F"
"707320746F207266436172626F6E220022436172626F6E3A20585250207472"
"616E73616374696F6E2064657465637465642C20636F6D707574696E672031"
"2520746F2073656E6420746F207266436172626F6E220022436172626F6E3A"
"2073746172746564220022436172626F6E3A2063616C6C6261636B2063616C"
"6C65642E2200436172626F6E3A2073664163636F756E74206669656C64206D"
"697373696E67212121";
Json::Value jhv = hso(createCodeHex);
jhv[jss::HookOn] =
"fffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffbfff"
"ff";
Json::Value jv = ripple::test::jtx::hook(account, {{jhv}}, 0);
return jv;
};
env(setHook(account), HSFEE);
env.close();
// set emit hook
setCallbackHook(env, account, true);
// ttINVOKE
env(invoke::invoke(account), fee(XRP(1)), ter(tesSUCCESS));
env(invoke::invoke(account), fee(XRP(2)), ter(tesSUCCESS));
env.close();
Blob txBlob;
@@ -4546,6 +4749,188 @@ private:
BEAST_EXPECT(postDest1 == postDest + postValue1);
}
void
testEmittedFlags(FeatureBitset features)
{
testcase("emitted flags");
using namespace test::jtx;
using namespace std::literals;
// weak
{
test::jtx::Env env{
*this,
network::makeNetworkConfig(21337, "10", "1000000", "200000"),
features};
auto const account = Account("alice");
auto const issuer = Account{"gw"};
auto const USD = issuer["USD"];
env.fund(XRP(1000), account, issuer);
env.close();
addWeakTSH(env, issuer);
// set tsh hook
setTSHHook(env, issuer, false);
// trust set
env(trust(account, USD(1000)), fee(XRP(1)), ter(tesSUCCESS));
env.close();
// verify tsh hook triggered
Json::Value params;
params[jss::transaction] =
env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
auto const meta = jrr[jss::result][jss::meta];
validateTSHFlags(env, meta, 0);
}
// strong
{
test::jtx::Env env{
*this,
network::makeNetworkConfig(21337, "10", "1000000", "200000"),
features};
auto const account = Account("alice");
auto const issuer = Account{"gw"};
auto const USD = issuer["USD"];
env.fund(XRP(1000), account, issuer);
env.close();
// set tsh hook
setTSHHook(env, account, true);
// trust set
env(trust(account, USD(1000)), fee(XRP(1)), ter(tesSUCCESS));
env.close();
// verify tsh hook triggered
Json::Value params;
params[jss::transaction] =
env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
auto const meta = jrr[jss::result][jss::meta];
validateTSHFlags(env, meta, 1);
}
// callback
{
test::jtx::Env env{
*this,
network::makeNetworkConfig(21337, "10", "1000000", "200000"),
features};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// set tsh hook
setCallbackHook(env, account, true);
// invoke
env(invoke::invoke(account), fee(XRP(2)), ter(tesSUCCESS));
env.close();
// get the emitted txn id
Json::Value params;
params[jss::transaction] =
env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
auto const meta = jrr[jss::result][jss::meta];
auto const emissions = meta[sfHookEmissions.jsonName];
auto const emission = emissions[0u][sfHookEmission.jsonName];
auto const txId = emission[sfEmittedTxnID.jsonName];
env.close();
// verify tsh hook triggered
Json::Value params1;
params1[jss::transaction] = txId;
auto const jrr1 = env.rpc("json", "tx", to_string(params1));
auto const meta1 = jrr1[jss::result][jss::meta];
validateTSHFlags(env, meta1, 2);
}
// weak callback
{
test::jtx::Env env{
*this,
network::makeNetworkConfig(21337, "10", "1000000", "200000"),
features};
auto const account = Account("alice");
auto const issuer = Account{"gw"};
auto const USD = issuer["USD"];
env.fund(XRP(1000), account, issuer);
env.close();
addWeakTSH(env, issuer);
// set tsh hook
setCallbackHook(env, issuer, false);
// trust set
env(trust(account, USD(1000)), fee(XRP(1)), ter(tesSUCCESS));
env.close();
// get the emitted txn id
Json::Value params;
params[jss::transaction] =
env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
auto const meta = jrr[jss::result][jss::meta];
auto const emissions = meta[sfHookEmissions.jsonName];
auto const emission = emissions[0u][sfHookEmission.jsonName];
auto const txId = emission[sfEmittedTxnID.jsonName];
env.close();
// verify tsh hook triggered
Json::Value params1;
params1[jss::transaction] = txId;
auto const jrr1 = env.rpc("json", "tx", to_string(params1));
auto const meta1 = jrr1[jss::result][jss::meta];
validateTSHFlags(env, meta1, 2);
}
// again as weak
{
test::jtx::Env env{
*this,
network::makeNetworkConfig(21337, "10", "1000000", "200000"),
features};
auto const account = Account("alice");
env.fund(XRP(1000), account);
env.close();
// set tsh hook
setTSHHook(env, account, true);
// invoke
auto tx = invoke::invoke(account);
tx[jss::HookParameters] = Json::Value{Json::arrayValue};
tx[jss::HookParameters][0U] = Json::Value{};
tx[jss::HookParameters][0U][jss::HookParameter] = Json::Value{};
tx[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterName] = "414157";
tx[jss::HookParameters][0U][jss::HookParameter]
[jss::HookParameterValue] = "01";
env(tx, fee(XRP(2)), ter(tesSUCCESS));
env.close();
// verify tsh hook triggered
Json::Value params;
params[jss::transaction] =
env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
auto const meta = jrr[jss::result][jss::meta];
validateTSHFlags(env, meta, 5);
}
}
void
testTSH(FeatureBitset features)
{
@@ -4586,6 +4971,7 @@ private:
testEmittedTxn(FeatureBitset features)
{
testEmittedTxnReliability(features);
testEmittedFlags(features);
}
public:
@@ -4594,7 +4980,8 @@ public:
{
using namespace test::jtx;
auto const sa = supported_amendments();
testTSH(sa - fixXahauV1);
testTSH(sa - fixXahauV1 - fixXahauV2);
testTSH(sa - fixXahauV2);
testTSH(sa);
testEmittedTxn(sa - fixXahauV2);
testEmittedTxn(sa);

File diff suppressed because it is too large Load Diff