Compare commits

...

68 Commits

Author SHA1 Message Date
Rithvik Reddygari
2e48bb4b7f refactor: Rename sfield names, sfExtensionComputeLimit -> sfGasLimit, sfExtensionSizeLimit -> sfBytecodeSizeLimit (#7708) 2026-07-08 16:26:58 -04:00
Mayukha Vadari
4a01fe5aa6 Merge branch 'ripple/se/wasmi-tests' into ripple/se/fees 2026-06-09 17:11:35 -04:00
Mayukha Vadari
f60a9f1c64 Revert "remove wasm engine tests"
This reverts commit 5ee903befc.
2026-06-09 17:10:13 -04:00
Mayukha Vadari
68f0dcae53 feat: Add fee vote maxes (#7346)
This PR adds hard-cap maxes for the size and compute limits, currently set at twice the defaults.
2026-06-04 16:25:52 -04:00
Mayukha Vadari
1f9675d22f Merge pull request #7301 from XRPLF/ripple/se/fees-fix-tidy
chore: Update branch from `develop`
2026-05-20 16:36:42 -04:00
Mayukha Vadari
029fa435ee fix issues 2026-05-20 14:21:56 -04:00
Mayukha Vadari
c92ca426bf fix clang-tidy 2026-05-20 14:13:53 -04:00
Mayukha Vadari
ff896b226a fix more build issues 2026-05-20 14:10:38 -04:00
Mayukha Vadari
3c53c94e7a Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees-fix-tidy 2026-05-20 14:02:17 -04:00
Mayukha Vadari
36fb84926e Update src/test/app/FeeVote_test.cpp
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-14 13:00:18 -04:00
Mayukha Vadari
56decaf852 Update cfg/xrpld-example.cfg
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-13 17:08:07 -04:00
Mayukha Vadari
1d9fe9dbaf Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-04-13 17:01:20 -04:00
Mayukha Vadari
a4dfdaf77a Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-08 13:51:41 -04:00
Mayukha Vadari
34522bc668 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-08 09:58:24 -04:00
Mayukha Vadari
22054a573d Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-03 09:57:23 -04:00
Mayukha Vadari
63bd5fc4ee fix clang-tidy issues 2026-04-02 19:07:10 -04:00
Mayukha Vadari
82e7f7eeec Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-02 19:06:00 -04:00
Mayukha Vadari
63d09f9c51 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-02 19:04:34 -04:00
Mayukha Vadari
d606f88e84 Merge branch 'ripple/wasmi-host-functions' of https://github.com/XRPLF/rippled into ripple/se/fees 2026-04-02 18:12:30 -04:00
Mayukha Vadari
51458a92e2 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-03-24 08:49:18 -07:00
Mayukha Vadari
864d88a3c2 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-03-05 13:48:44 -04:00
Mayukha Vadari
7004d216ed Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-03-03 11:19:02 -04:00
Mayukha Vadari
00eeab6d44 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-27 16:50:13 -05:00
Mayukha Vadari
5148098079 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-18 13:21:53 -05:00
Mayukha Vadari
4fe508cb92 fix comments 2026-02-12 17:48:50 -05:00
Mayukha Vadari
eb2d44d442 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-10 17:44:52 -05:00
Mayukha Vadari
cd46b5d999 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-04 18:41:19 -05:00
Mayukha Vadari
13707dda05 Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-02-04 17:13:50 -05:00
Mayukha Vadari
f625fb993a Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-02-03 15:19:36 -05:00
Mayukha Vadari
69c61b2235 fix merge issues 2026-01-28 16:52:27 -05:00
Mayukha Vadari
6ae0e860ff Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-01-28 16:39:44 -05:00
Mayukha Vadari
c077e7f073 Merge commit '4eb34f3' into ripple/se/fees 2026-01-28 16:39:06 -05:00
Mayukha Vadari
4621e4eda3 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-26 09:29:34 -05:00
Mayukha Vadari
981ac7abf4 simplify fee code (#6249)
* simplify lambda

* clean up fee code

* fix tests, better error handling

* simplify source_location
2026-01-23 15:14:24 -05:00
Mayukha Vadari
43c80edaf4 Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-01-21 12:58:24 -05:00
Mayukha Vadari
384b3608d7 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-15 14:17:57 -05:00
Mayukha Vadari
e1513570df Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-13 13:46:50 -05:00
Mayukha Vadari
f0d0739528 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2026-01-12 13:28:07 -05:00
Mayukha Vadari
103379836a Merge branch 'wasmi-host-functions' into ripple/se/fees 2026-01-08 11:45:05 -05:00
Mayukha Vadari
397bc8781e fix more merge issues 2026-01-06 14:27:46 -05:00
Mayukha Vadari
8bb8c2e38b Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-01-06 13:40:53 -05:00
Mayukha Vadari
36ecd3b52b Merge remote-tracking branch 'upstream/ripple/wasmi-host-functions' into ripple/se/fees 2026-01-05 18:51:46 -05:00
Mayukha Vadari
9d1f51b01a Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-12-22 17:01:34 -08:00
Mayukha Vadari
827ecc6e3a Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-12-15 10:44:17 -08:00
Mayukha Vadari
27ac30208d Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-12-02 07:44:22 -05:00
Mayukha Vadari
e40a4df777 Merge branch 'ripple/wasmi-host-functions' into ripple/se/fees 2025-11-25 03:49:06 +05:30
Mayukha Vadari
95d78a8600 Merge branch 'wasmi-host-functions' into ripple/se/fees 2025-11-25 03:26:19 +05:30
Mayukha Vadari
578413859c Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-11-04 17:52:00 -05:00
Mayukha Vadari
3195eb16b2 Merge branch 'wamr-host-functions' into ripple/se/fees 2025-11-04 14:50:31 -05:00
Mayukha Vadari
eed280d169 Merge branch 'wamr-host-functions' into ripple/se/fees 2025-11-04 13:37:09 -05:00
Mayukha Vadari
aebec5378c Merge branch 'wamr-host-functions' into ripple/se/fees 2025-10-24 18:01:17 -04:00
Mayukha Vadari
67e2c1b563 Merge branch 'wamr-host-functions' into ripple/se/fees 2025-10-24 16:06:02 -04:00
Mayukha Vadari
209ee25c32 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-24 16:02:16 -04:00
Mayukha Vadari
af6beb1d7c fix ledger used for rules 2025-10-23 15:41:32 -04:00
Mayukha Vadari
ce19c13059 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-23 15:38:37 -04:00
Mayukha Vadari
43caa1ef29 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-20 11:53:56 -04:00
Mayukha Vadari
fe601308e7 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-13 13:58:09 -04:00
Mayukha Vadari
51f1be7f5b Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-09 17:10:52 -04:00
Mayukha Vadari
f57b855d74 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-06 17:01:17 -04:00
Mayukha Vadari
86525d8583 test: add tests for fee voting (#5747) 2025-10-06 16:32:04 -04:00
Mayukha Vadari
51ee06429b Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-10-02 14:35:36 -04:00
Mayukha Vadari
ca85d09f02 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-30 14:43:24 -04:00
Mayukha Vadari
e59f5f3b01 fix tests 2025-09-26 17:09:53 -04:00
Mayukha Vadari
c8b06e7de1 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-26 16:50:34 -04:00
Mayukha Vadari
c3fd52c177 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-26 15:51:56 -04:00
Mayukha Vadari
737fab5471 fix issues 2025-09-22 23:55:57 -04:00
Mayukha Vadari
5a6c4e8ae0 Merge branch 'ripple/wamr-host-functions' into ripple/se/fees 2025-09-22 18:23:54 -04:00
Mayukha Vadari
7420f47658 SmartEscrow fee voting changes 2025-09-22 18:22:44 -04:00
81 changed files with 10298 additions and 66 deletions

View File

@@ -1283,6 +1283,39 @@
# Example:
# owner_reserve = 200000 # 0.2 XRP
#
# gas_limit = <gas>
#
# The gas limit is the maximum amount of gas that can be
# consumed by a single transaction. The gas limit is used to prevent
# transactions from consuming too many resources.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_limit = 1000000 # 1 million gas
#
# bytecode_size_limit = <bytes>
#
# The bytecode size limit is the maximum size of a WASM extension in
# bytes. The size limit is used to prevent extensions from consuming
# too many resources.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# bytecode_size_limit = 100000 # 100 kb
#
# gas_price = <micro-drops>
#
# The gas price is the conversion between WASM gas and its price in drops.
#
# If this parameter is unspecified, xrpld will use an internal
# default. Don't change this without understanding the consequences.
#
# Example:
# gas_price = 1000000 # 1 drop per gas
#-------------------------------------------------------------------------------
#
# 9. Misc Settings

View File

@@ -7,6 +7,7 @@ ignorePaths:
- cmake/**
- LICENSE.md
- .clang-tidy
- src/test/app/wasm_fixtures/**/*.wat
- src/test/app/wasm_fixtures/*.c
language: en
allowCompoundWords: true # TODO (#6334)

View File

@@ -2,12 +2,21 @@
#include <xrpl/protocol/XRPAmount.h>
#include <cstdint>
namespace xrpl {
// Deprecated constant for backwards compatibility with pre-XRPFees amendment.
// This was the reference fee units used in the old fee calculation.
inline constexpr std::uint32_t kFeeUnitsDeprecated = 10;
// Number of micro-drops in one drop.
constexpr std::uint32_t microDropsPerDrop{1'000'000};
/** Maximum Feature Extension fee settings. */
inline constexpr std::uint32_t kMaxGasLimit{2'000'000};
inline constexpr std::uint32_t kMaxBytecodeSizeLimit{200'000};
/** Reflects the fee settings for a particular ledger.
The fees are always the same for any transactions applied
@@ -24,6 +33,15 @@ struct Fees
/** @brief Additional XRP reserve required per owned ledger object. */
XRPAmount increment{0};
/** @brief Gas limit for Feature Extensions (instructions). */
std::uint32_t gasLimit{0};
/** @brief Bytecode size limit for Feature Extensions (bytes). */
std::uint32_t bytecodeSizeLimit{0};
/** @brief Price of WASM gas (micro-drops). */
std::uint32_t gasPrice{0};
explicit Fees() = default;
Fees(Fees const&) = default;
Fees&

View File

@@ -15,6 +15,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FEATURE(SmartEscrow, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_2_0, Supported::No, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)

View File

@@ -304,6 +304,11 @@ LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
// Smart Escrow fields
{sfGasLimit, SoeOptional},
{sfBytecodeSizeLimit, SoeOptional},
{sfGasPrice, SoeOptional},
{sfPreviousTxnID, SoeOptional},
{sfPreviousTxnLgrSeq, SoeOptional},
}))

View File

@@ -113,6 +113,9 @@ TYPED_SFIELD(sfInterestRate, UINT32, 65) // 1/10 basis points (bi
TYPED_SFIELD(sfLateInterestRate, UINT32, 66) // 1/10 basis points (bips)
TYPED_SFIELD(sfCloseInterestRate, UINT32, 67) // 1/10 basis points (bips)
TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 68) // 1/10 basis points (bips)
TYPED_SFIELD(sfGasLimit, UINT32, 69)
TYPED_SFIELD(sfBytecodeSizeLimit, UINT32, 70)
TYPED_SFIELD(sfGasPrice, UINT32, 71)
// 64-bit integers (common)
TYPED_SFIELD(sfIndexNext, UINT64, 1)

View File

@@ -1110,6 +1110,10 @@ TRANSACTION(ttFEE, 101, SetFee,
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
// Smart Escrow fields
{sfGasLimit, SoeOptional},
{sfBytecodeSizeLimit, SoeOptional},
{sfGasPrice, SoeOptional},
}))
/** This system-generated transaction type is used to update the network's negative UNL

View File

@@ -248,6 +248,9 @@ JSS(expected_date); // out: any (warnings)
JSS(expected_date_UTC); // out: any (warnings)
JSS(expected_ledger_size); // out: TxQ
JSS(expiration); // out: AccountOffers, AccountChannels, ValidatorList, amm_info
JSS(gas_limit); // out: NetworkOPs
JSS(bytecode_size_limit); // out: NetworkOPs
JSS(gas_price); // out: NetworkOPs
JSS(fail_hard); // in: Sign, Submit
JSS(failed); // out: InboundLedger
JSS(feature); // in: Feature

View File

@@ -213,6 +213,78 @@ public:
return this->sle_->isFieldPresent(sfReserveIncrementDrops);
}
/**
* @brief Get sfGasLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasLimit() const
{
if (hasGasLimit())
return this->sle_->at(sfGasLimit);
return std::nullopt;
}
/**
* @brief Check if sfGasLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasLimit() const
{
return this->sle_->isFieldPresent(sfGasLimit);
}
/**
* @brief Get sfBytecodeSizeLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getBytecodeSizeLimit() const
{
if (hasBytecodeSizeLimit())
return this->sle_->at(sfBytecodeSizeLimit);
return std::nullopt;
}
/**
* @brief Check if sfBytecodeSizeLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasBytecodeSizeLimit() const
{
return this->sle_->isFieldPresent(sfBytecodeSizeLimit);
}
/**
* @brief Get sfGasPrice (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasPrice() const
{
if (hasGasPrice())
return this->sle_->at(sfGasPrice);
return std::nullopt;
}
/**
* @brief Check if sfGasPrice is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasPrice() const
{
return this->sle_->isFieldPresent(sfGasPrice);
}
/**
* @brief Get sfPreviousTxnID (SoeOptional)
* @return The field value, or std::nullopt if not present.
@@ -373,6 +445,39 @@ public:
return *this;
}
/**
* @brief Set sfGasLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
FeeSettingsBuilder&
setGasLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasLimit] = value;
return *this;
}
/**
* @brief Set sfBytecodeSizeLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
FeeSettingsBuilder&
setBytecodeSizeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfBytecodeSizeLimit] = value;
return *this;
}
/**
* @brief Set sfGasPrice (SoeOptional)
* @return Reference to this builder for method chaining.
*/
FeeSettingsBuilder&
setGasPrice(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasPrice] = value;
return *this;
}
/**
* @brief Set sfPreviousTxnID (SoeOptional)
* @return Reference to this builder for method chaining.

View File

@@ -254,6 +254,84 @@ public:
{
return this->tx_->isFieldPresent(sfReserveIncrementDrops);
}
/**
* @brief Get sfGasLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasLimit() const
{
if (hasGasLimit())
{
return this->tx_->at(sfGasLimit);
}
return std::nullopt;
}
/**
* @brief Check if sfGasLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasLimit() const
{
return this->tx_->isFieldPresent(sfGasLimit);
}
/**
* @brief Get sfBytecodeSizeLimit (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getBytecodeSizeLimit() const
{
if (hasBytecodeSizeLimit())
{
return this->tx_->at(sfBytecodeSizeLimit);
}
return std::nullopt;
}
/**
* @brief Check if sfBytecodeSizeLimit is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasBytecodeSizeLimit() const
{
return this->tx_->isFieldPresent(sfBytecodeSizeLimit);
}
/**
* @brief Get sfGasPrice (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getGasPrice() const
{
if (hasGasPrice())
{
return this->tx_->at(sfGasPrice);
}
return std::nullopt;
}
/**
* @brief Check if sfGasPrice is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasGasPrice() const
{
return this->tx_->isFieldPresent(sfGasPrice);
}
};
/**
@@ -384,6 +462,39 @@ public:
return *this;
}
/**
* @brief Set sfGasLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SetFeeBuilder&
setGasLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasLimit] = value;
return *this;
}
/**
* @brief Set sfBytecodeSizeLimit (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SetFeeBuilder&
setBytecodeSizeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfBytecodeSizeLimit] = value;
return *this;
}
/**
* @brief Set sfGasPrice (SoeOptional)
* @return Reference to this builder for method chaining.
*/
SetFeeBuilder&
setGasPrice(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfGasPrice] = value;
return *this;
}
/**
* @brief Build and return the SetFee wrapper.
* @param publicKey The public key for signing.

View File

@@ -198,6 +198,12 @@ Ledger::Ledger(
sle->at(sfReserveIncrement) = *f;
sle->at(sfReferenceFeeUnits) = kFeeUnitsDeprecated;
}
if (std::ranges::find(amendments, featureSmartEscrow) != amendments.end())
{
sle->at(sfGasLimit) = fees.gasLimit;
sle->at(sfBytecodeSizeLimit) = fees.bytecodeSizeLimit;
sle->at(sfGasPrice) = fees.gasPrice;
}
rawInsert(sle);
}
@@ -564,6 +570,7 @@ Ledger::setup()
{
bool oldFees = false;
bool newFees = false;
bool extensionFees = false;
{
auto const baseFee = sle->at(~sfBaseFee);
auto const reserveBase = sle->at(~sfReserveBase);
@@ -580,6 +587,7 @@ Ledger::setup()
auto const baseFeeXRP = sle->at(~sfBaseFeeDrops);
auto const reserveBaseXRP = sle->at(~sfReserveBaseDrops);
auto const reserveIncrementXRP = sle->at(~sfReserveIncrementDrops);
auto assign = [&ret](XRPAmount& dest, std::optional<STAmount> const& src) {
if (src)
{
@@ -598,6 +606,22 @@ Ledger::setup()
assign(fees_.increment, reserveIncrementXRP);
newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
}
{
auto const gasLimit = sle->at(~sfGasLimit);
auto const bytecodeSizeLimit = sle->at(~sfBytecodeSizeLimit);
auto const gasPrice = sle->at(~sfGasPrice);
auto assign = [](std::uint32_t& dest, std::optional<std::uint32_t> const& src) {
if (src)
{
dest = src.value();
}
};
assign(fees_.gasLimit, gasLimit);
assign(fees_.bytecodeSizeLimit, bytecodeSizeLimit);
assign(fees_.gasPrice, gasPrice);
extensionFees = gasLimit || bytecodeSizeLimit || gasPrice;
}
if (oldFees && newFees)
{
// Should be all of one or the other, but not both
@@ -608,6 +632,12 @@ Ledger::setup()
// Can't populate the new fees before the amendment is enabled
ret = false;
}
if (!rules_.enabled(featureSmartEscrow) && extensionFees)
{
// Can't populate the extension fees before the amendment is
// enabled
ret = false;
}
}
}
catch (SHAMapMissingNode const&)

View File

@@ -59,6 +59,10 @@ STValidation::validationFormat()
{sfBaseFeeDrops, SoeOptional},
{sfReserveBaseDrops, SoeOptional},
{sfReserveIncrementDrops, SoeOptional},
// featureSmartEscrow
{sfGasLimit, SoeOptional},
{sfBytecodeSizeLimit, SoeOptional},
{sfGasPrice, SoeOptional},
};
// clang-format on

View File

@@ -9,6 +9,7 @@
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/AmendmentTable.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/PublicKey.h>
@@ -123,6 +124,22 @@ Change::preclaim(PreclaimContext const& ctx)
ctx.tx.isFieldPresent(sfReserveIncrementDrops))
return temDISABLED;
}
if (ctx.view.rules().enabled(featureSmartEscrow))
{
if (!ctx.tx.isFieldPresent(sfGasLimit) ||
!ctx.tx.isFieldPresent(sfBytecodeSizeLimit) ||
!ctx.tx.isFieldPresent(sfGasPrice))
return temMALFORMED;
if (ctx.tx[sfGasLimit] > kMaxGasLimit ||
ctx.tx[sfBytecodeSizeLimit] > kMaxBytecodeSizeLimit)
return temBAD_FEE;
}
else
{
if (ctx.tx.isFieldPresent(sfGasLimit) ||
ctx.tx.isFieldPresent(sfBytecodeSizeLimit) || ctx.tx.isFieldPresent(sfGasPrice))
return temDISABLED;
}
return tesSUCCESS;
case ttAMENDMENT:
case ttUNL_MODIFY:
@@ -284,6 +301,12 @@ Change::applyFee()
set(feeObject, ctx_.tx, sfReserveBase);
set(feeObject, ctx_.tx, sfReserveIncrement);
}
if (view().rules().enabled(featureSmartEscrow))
{
set(feeObject, ctx_.tx, sfGasLimit);
set(feeObject, ctx_.tx, sfBytecodeSizeLimit);
set(feeObject, ctx_.tx, sfGasPrice);
}
view().update(feeObject);

View File

@@ -11,6 +11,7 @@
#include <xrpl/ledger/Ledger.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/KeyType.h>
#include <xrpl/protocol/PublicKey.h>
@@ -31,7 +32,9 @@
#include <limits>
#include <memory>
#include <optional>
#include <source_location>
#include <string>
#include <utility>
#include <vector>
namespace xrpl::test {
@@ -45,10 +48,17 @@ struct FeeSettingsFields
std::optional<XRPAmount> baseFeeDrops = std::nullopt;
std::optional<XRPAmount> reserveBaseDrops = std::nullopt;
std::optional<XRPAmount> reserveIncrementDrops = std::nullopt;
std::optional<std::uint32_t> gasLimit = std::nullopt;
std::optional<std::uint32_t> bytecodeSizeLimit = std::nullopt;
std::optional<std::uint32_t> gasPrice = std::nullopt;
};
STTx
createFeeTx(Rules const& rules, std::uint32_t seq, FeeSettingsFields const& fields)
createFeeTx(
Rules const& rules,
std::uint32_t seq,
FeeSettingsFields const& fields,
bool forceAllFields = false)
{
auto fill = [&](auto& obj) {
obj.setAccountID(sfAccount, AccountID());
@@ -76,6 +86,13 @@ createFeeTx(Rules const& rules, std::uint32_t seq, FeeSettingsFields const& fiel
obj.setFieldU32(
sfReferenceFeeUnits, fields.referenceFeeUnits ? *fields.referenceFeeUnits : 0);
}
if (rules.enabled(featureSmartEscrow) || forceAllFields)
{
obj.setFieldU32(sfGasLimit, fields.gasLimit ? *fields.gasLimit : 0);
obj.setFieldU32(
sfBytecodeSizeLimit, fields.bytecodeSizeLimit ? *fields.bytecodeSizeLimit : 0);
obj.setFieldU32(sfGasPrice, fields.gasPrice ? *fields.gasPrice : 0);
}
};
return STTx(ttFEE, fill);
}
@@ -124,6 +141,12 @@ createInvalidFeeTx(
obj.setFieldU32(sfReserveIncrement, 50000);
obj.setFieldU32(sfReferenceFeeUnits, 10);
}
if (rules.enabled(featureSmartEscrow))
{
obj.setFieldU32(sfGasLimit, 100 + uniqueValue);
obj.setFieldU32(sfBytecodeSizeLimit, 200 + uniqueValue);
obj.setFieldU32(sfGasPrice, 300 + uniqueValue);
}
}
// If missingRequiredFields is true, we don't add the required fields
// (default behavior)
@@ -131,11 +154,11 @@ createInvalidFeeTx(
return STTx(ttFEE, fill);
}
bool
TER
applyFeeAndTestResult(jtx::Env& env, OpenView& view, STTx const& tx)
{
auto const res = apply(env.app(), view, tx, ApplyFlags::TapNone, env.journal);
return isTesSuccess(res.ter);
return res.ter;
}
bool
@@ -186,6 +209,21 @@ verifyFeeObject(
if (!checkEquality(sfReferenceFeeUnits, expected.referenceFeeUnits))
return false;
}
if (rules.enabled(featureSmartEscrow))
{
if (!checkEquality(sfGasLimit, expected.gasLimit.value_or(0)))
return false;
if (!checkEquality(sfBytecodeSizeLimit, expected.bytecodeSizeLimit.value_or(0)))
return false;
if (!checkEquality(sfGasPrice, expected.gasPrice.value_or(0)))
return false;
}
else
{
if (feeObject->isFieldPresent(sfGasLimit) ||
feeObject->isFieldPresent(sfBytecodeSizeLimit) || feeObject->isFieldPresent(sfGasPrice))
return false;
}
return true;
}
@@ -208,6 +246,7 @@ class FeeVote_test : public beast::unit_test::Suite
void
testSetup()
{
testcase("FeeVote setup");
FeeSetup const defaultSetup;
{
// defaults
@@ -216,35 +255,63 @@ class FeeVote_test : public beast::unit_test::Suite
BEAST_EXPECT(setup.reference_fee == defaultSetup.reference_fee);
BEAST_EXPECT(setup.account_reserve == defaultSetup.account_reserve);
BEAST_EXPECT(setup.owner_reserve == defaultSetup.owner_reserve);
BEAST_EXPECT(setup.gas_limit == defaultSetup.gas_limit);
BEAST_EXPECT(setup.bytecode_size_limit == defaultSetup.bytecode_size_limit);
BEAST_EXPECT(setup.gas_price == defaultSetup.gas_price);
}
{
Section config;
config.append(
{"reference_fee = 50", "account_reserve = 1234567", "owner_reserve = 1234"});
{"reference_fee = 50",
"account_reserve = 1234567",
"owner_reserve = 1234",
"gas_limit = 100",
"bytecode_size_limit = 200",
"gas_price = 300"});
auto setup = setupFeeVote(config);
BEAST_EXPECT(setup.reference_fee == 50);
BEAST_EXPECT(setup.account_reserve == 1234567);
BEAST_EXPECT(setup.owner_reserve == 1234);
BEAST_EXPECT(setup.gas_limit == 100);
BEAST_EXPECT(setup.bytecode_size_limit == 200);
BEAST_EXPECT(setup.gas_price == 300);
}
{
Section config;
config.append(
{"reference_fee = blah", "account_reserve = yada", "owner_reserve = foo"});
{"reference_fee = blah",
"account_reserve = yada",
"owner_reserve = foo",
"gas_limit = bar",
"bytecode_size_limit = baz",
"gas_price = qux"});
// Illegal values are ignored, and the defaults left unchanged
auto setup = setupFeeVote(config);
BEAST_EXPECT(setup.reference_fee == defaultSetup.reference_fee);
BEAST_EXPECT(setup.account_reserve == defaultSetup.account_reserve);
BEAST_EXPECT(setup.owner_reserve == defaultSetup.owner_reserve);
BEAST_EXPECT(setup.gas_limit == defaultSetup.gas_limit);
BEAST_EXPECT(setup.bytecode_size_limit == defaultSetup.bytecode_size_limit);
BEAST_EXPECT(setup.gas_price == defaultSetup.gas_price);
}
{
Section config;
config.append(
{"reference_fee = -50", "account_reserve = -1234567", "owner_reserve = -1234"});
// Illegal values are ignored, and the defaults left unchanged
{"reference_fee = -50",
"account_reserve = -1234567",
"owner_reserve = -1234",
"gas_limit = -100",
"bytecode_size_limit = -200",
"gas_price = -300"});
// Negative gas/bytecode limit values wrap past their maximum and are
// ignored. Other uint32_t fields keep the existing behavior.
auto setup = setupFeeVote(config);
BEAST_EXPECT(setup.reference_fee == defaultSetup.reference_fee);
BEAST_EXPECT(setup.account_reserve == static_cast<std::uint32_t>(-1234567));
BEAST_EXPECT(setup.owner_reserve == static_cast<std::uint32_t>(-1234));
BEAST_EXPECT(setup.gas_limit == defaultSetup.gas_limit);
BEAST_EXPECT(setup.bytecode_size_limit == defaultSetup.bytecode_size_limit);
BEAST_EXPECT(setup.gas_price == static_cast<std::uint32_t>(-300));
}
{
auto const big64 = std::to_string(
@@ -253,12 +320,36 @@ class FeeVote_test : public beast::unit_test::Suite
config.append(
{"reference_fee = " + big64,
"account_reserve = " + big64,
"owner_reserve = " + big64});
"owner_reserve = " + big64,
"gas_limit = " + big64,
"bytecode_size_limit = " + big64,
"gas_price = " + big64});
// Illegal values are ignored, and the defaults left unchanged
auto setup = setupFeeVote(config);
BEAST_EXPECT(setup.reference_fee == defaultSetup.reference_fee);
BEAST_EXPECT(setup.account_reserve == defaultSetup.account_reserve);
BEAST_EXPECT(setup.owner_reserve == defaultSetup.owner_reserve);
BEAST_EXPECT(setup.gas_limit == defaultSetup.gas_limit);
BEAST_EXPECT(setup.bytecode_size_limit == defaultSetup.bytecode_size_limit);
BEAST_EXPECT(setup.gas_price == defaultSetup.gas_price);
}
{
Section config;
config.append(
{"gas_limit = " + std::to_string(kMaxGasLimit + 1),
"bytecode_size_limit = " + std::to_string(kMaxBytecodeSizeLimit + 1)});
auto const setup = setupFeeVote(config);
BEAST_EXPECT(setup.gas_limit == defaultSetup.gas_limit);
BEAST_EXPECT(setup.bytecode_size_limit == defaultSetup.bytecode_size_limit);
}
{
Section config;
config.append(
{"gas_limit = " + std::to_string(kMaxGasLimit),
"bytecode_size_limit = " + std::to_string(kMaxBytecodeSizeLimit)});
auto const setup = setupFeeVote(config);
BEAST_EXPECT(setup.gas_limit == kMaxGasLimit);
BEAST_EXPECT(setup.bytecode_size_limit == kMaxBytecodeSizeLimit);
}
}
@@ -269,7 +360,7 @@ class FeeVote_test : public beast::unit_test::Suite
// Test with XRPFees disabled (legacy format)
{
jtx::Env env(*this, jtx::testableAmendments() - featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureXRPFees - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -290,7 +381,7 @@ class FeeVote_test : public beast::unit_test::Suite
auto feeTx = createFeeTx(ledger->rules(), ledger->seq(), fields);
OpenView accum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
accum.apply(*ledger);
// Verify fee object was created/updated correctly
@@ -299,7 +390,7 @@ class FeeVote_test : public beast::unit_test::Suite
// Test with XRPFees enabled (new format)
{
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -318,12 +409,105 @@ class FeeVote_test : public beast::unit_test::Suite
auto feeTx = createFeeTx(ledger->rules(), ledger->seq(), fields);
OpenView accum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
accum.apply(*ledger);
// Verify fee object was created/updated correctly
BEAST_EXPECT(verifyFeeObject(ledger, ledger->rules(), fields));
}
// Test with both XRPFees and SmartEscrow enabled
{
jtx::Env env(*this, jtx::testableAmendments());
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().FEES.toFees(),
std::vector<uint256>{},
env.app().getNodeFamily());
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
FeeSettingsFields const fields{
.baseFeeDrops = XRPAmount{10},
.reserveBaseDrops = XRPAmount{200000},
.reserveIncrementDrops = XRPAmount{50000},
.gasLimit = 100,
.bytecodeSizeLimit = 200,
.gasPrice = 300};
// Test successful fee transaction with new fields
auto feeTx = createFeeTx(ledger->rules(), ledger->seq(), fields);
OpenView accum(ledger.get());
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
accum.apply(*ledger);
// Verify fee object was created/updated correctly
BEAST_EXPECT(verifyFeeObject(ledger, ledger->rules(), fields));
}
// Test that Smart Escrow limits reject values above their maximums.
{
jtx::Env env(*this, jtx::testableAmendments());
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().FEES.toFees(),
std::vector<uint256>{},
env.app().getNodeFamily());
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
auto testBadFields = [&](FeeSettingsFields const& fields) {
auto feeTx = createFeeTx(ledger->rules(), ledger->seq(), fields);
OpenView accum(ledger.get());
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
};
testBadFields(
{.baseFeeDrops = XRPAmount{10},
.reserveBaseDrops = XRPAmount{200000},
.reserveIncrementDrops = XRPAmount{50000},
.gasLimit = kMaxGasLimit + 1,
.bytecodeSizeLimit = kMaxBytecodeSizeLimit,
.gasPrice = 300});
testBadFields(
{.baseFeeDrops = XRPAmount{10},
.reserveBaseDrops = XRPAmount{200000},
.reserveIncrementDrops = XRPAmount{50000},
.gasLimit = kMaxGasLimit,
.bytecodeSizeLimit = kMaxBytecodeSizeLimit + 1,
.gasPrice = 300});
}
// Test that the Smart Escrow fields are rejected if the
// feature is disabled
{
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().FEES.toFees(),
std::vector<uint256>{},
env.app().getNodeFamily());
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
FeeSettingsFields const fields{
.baseFeeDrops = XRPAmount{10},
.reserveBaseDrops = XRPAmount{200000},
.reserveIncrementDrops = XRPAmount{50000},
.gasLimit = 100,
.bytecodeSizeLimit = 200,
.gasPrice = 300};
// Test successful fee transaction with new fields
auto feeTx = createFeeTx(ledger->rules(), ledger->seq(), fields, true);
OpenView accum(ledger.get());
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
}
}
void
@@ -332,7 +516,7 @@ class FeeVote_test : public beast::unit_test::Suite
testcase("Fee Transaction Validation");
{
jtx::Env env(*this, jtx::testableAmendments() - featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureXRPFees - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -346,15 +530,15 @@ class FeeVote_test : public beast::unit_test::Suite
// Test transaction with missing required legacy fields
auto invalidTx = createInvalidFeeTx(ledger->rules(), ledger->seq(), true, false, 1);
OpenView accum(ledger.get());
BEAST_EXPECT(!applyFeeAndTestResult(env, accum, invalidTx));
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
// Test transaction with new format fields when XRPFees is disabled
auto disallowedTx = createInvalidFeeTx(ledger->rules(), ledger->seq(), false, true, 2);
BEAST_EXPECT(!applyFeeAndTestResult(env, accum, disallowedTx));
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, disallowedTx)));
}
{
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -368,11 +552,33 @@ class FeeVote_test : public beast::unit_test::Suite
// Test transaction with missing required new fields
auto invalidTx = createInvalidFeeTx(ledger->rules(), ledger->seq(), true, false, 3);
OpenView accum(ledger.get());
BEAST_EXPECT(!applyFeeAndTestResult(env, accum, invalidTx));
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
// Test transaction with legacy fields when XRPFees is enabled
auto disallowedTx = createInvalidFeeTx(ledger->rules(), ledger->seq(), false, true, 4);
BEAST_EXPECT(!applyFeeAndTestResult(env, accum, disallowedTx));
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, disallowedTx)));
}
{
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees | featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().FEES.toFees(),
std::vector<uint256>{},
env.app().getNodeFamily());
// Create the next ledger to apply transaction to
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
// Test transaction with missing required new fields
auto invalidTx = createInvalidFeeTx(ledger->rules(), ledger->seq(), true, false, 5);
OpenView accum(ledger.get());
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
// Test transaction with legacy fields when XRPFees is enabled
auto disallowedTx = createInvalidFeeTx(ledger->rules(), ledger->seq(), false, true, 6);
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, disallowedTx)));
}
}
@@ -381,7 +587,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Pseudo Transaction Properties");
jtx::Env env(*this, jtx::testableAmendments());
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -411,7 +617,7 @@ class FeeVote_test : public beast::unit_test::Suite
// But can be applied to a closed ledger
{
OpenView closedAccum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, closedAccum, feeTx));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, closedAccum, feeTx)));
}
}
@@ -420,7 +626,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Multiple Fee Updates");
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -438,7 +644,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
OpenView accum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx1));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx1)));
accum.apply(*ledger);
}
@@ -455,7 +661,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
OpenView accum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx2));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx2)));
accum.apply(*ledger);
}
@@ -468,7 +674,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Wrong Ledger Sequence");
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -491,7 +697,7 @@ class FeeVote_test : public beast::unit_test::Suite
// The transaction should still succeed as long as other fields are
// valid
// The ledger sequence field is only used for informational purposes
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx)));
}
void
@@ -499,7 +705,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Partial Field Updates");
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -517,7 +723,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
OpenView accum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx1));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx1)));
accum.apply(*ledger);
}
@@ -532,7 +738,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
OpenView accum(ledger.get());
BEAST_EXPECT(applyFeeAndTestResult(env, accum, feeTx2));
BEAST_EXPECT(isTesSuccess(applyFeeAndTestResult(env, accum, feeTx2)));
accum.apply(*ledger);
}
@@ -545,7 +751,7 @@ class FeeVote_test : public beast::unit_test::Suite
{
testcase("Single Invalid Transaction");
jtx::Env env(*this, jtx::testableAmendments() | featureXRPFees);
jtx::Env env(*this, jtx::testableAmendments() - featureSmartEscrow);
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
@@ -567,7 +773,7 @@ class FeeVote_test : public beast::unit_test::Suite
});
OpenView accum(ledger.get());
BEAST_EXPECT(!applyFeeAndTestResult(env, accum, invalidTx));
BEAST_EXPECT(!isTesSuccess(applyFeeAndTestResult(env, accum, invalidTx)));
}
void
@@ -584,7 +790,7 @@ class FeeVote_test : public beast::unit_test::Suite
// Test with XRPFees enabled
{
Env env(*this, testableAmendments() | featureXRPFees);
Env env(*this, testableAmendments() - featureSmartEscrow);
auto feeVote = makeFeeVote(setup, env.app().getJournal("FeeVote"));
auto ledger = std::make_shared<Ledger>(
@@ -614,7 +820,7 @@ class FeeVote_test : public beast::unit_test::Suite
// Test with XRPFees disabled (legacy format)
{
Env env(*this, testableAmendments() - featureXRPFees);
Env env(*this, testableAmendments() - featureXRPFees - featureSmartEscrow);
auto feeVote = makeFeeVote(setup, env.app().getJournal("FeeVote"));
auto ledger = std::make_shared<Ledger>(
@@ -654,7 +860,7 @@ class FeeVote_test : public beast::unit_test::Suite
setup.account_reserve = 1234567;
setup.owner_reserve = 7654321;
Env env(*this, testableAmendments() | featureXRPFees);
Env env(*this, testableAmendments() - featureSmartEscrow);
// establish what the current fees are
BEAST_EXPECT(env.current()->fees().base == XRPAmount{UNIT_TEST_REFERENCE_FEE});
@@ -729,6 +935,157 @@ class FeeVote_test : public beast::unit_test::Suite
feeTx.getFieldAmount(sfReserveIncrementDrops) == XRPAmount{setup.owner_reserve});
}
void
testDoVotingSmartEscrow()
{
testcase("doVoting with Smart Escrow");
using namespace jtx;
Env env(*this, testableAmendments() | featureXRPFees | featureSmartEscrow);
// establish what the current fees are
BEAST_EXPECT(env.current()->fees().base == XRPAmount{UNIT_TEST_REFERENCE_FEE});
BEAST_EXPECT(env.current()->fees().reserve == XRPAmount{200'000'000});
BEAST_EXPECT(env.current()->fees().increment == XRPAmount{50'000'000});
BEAST_EXPECT(env.current()->fees().gasLimit == 0);
BEAST_EXPECT(env.current()->fees().bytecodeSizeLimit == 0);
BEAST_EXPECT(env.current()->fees().gasPrice == 0);
auto const createFeeTxFromVoting =
[&](FeeSetup const& setup) -> std::pair<STTx, std::shared_ptr<Ledger>> {
auto feeVote = makeFeeVote(setup, env.app().getJournal("FeeVote"));
auto ledger = std::make_shared<Ledger>(
kCreateGenesis,
Rules{env.app().config().features},
env.app().config().FEES.toFees(),
std::vector<uint256>{},
env.app().getNodeFamily());
// doVoting requires a flag ledger (every 256th ledger)
// We need to create a ledger at sequence 256 to make it a flag
// ledger
for (int i = 0; i < 256 - 1; ++i)
{
ledger = std::make_shared<Ledger>(*ledger, env.app().getTimeKeeper().closeTime());
}
BEAST_EXPECT(ledger->isFlagLedger());
// Create some mock validations with fee votes
std::vector<std::shared_ptr<STValidation>> validations;
for (int i = 0; i < 5; i++)
{
auto sec = randomSecretKey();
auto pub = derivePublicKey(KeyType::Secp256k1, sec);
auto val = std::make_shared<STValidation>(
env.app().getTimeKeeper().now(),
pub,
sec,
calcNodeID(pub),
[&](STValidation& v) {
v.setFieldU32(sfLedgerSequence, ledger->seq());
// Vote for different fees than current
v.setFieldAmount(sfBaseFeeDrops, XRPAmount{setup.reference_fee});
v.setFieldAmount(sfReserveBaseDrops, XRPAmount{setup.account_reserve});
v.setFieldAmount(sfReserveIncrementDrops, XRPAmount{setup.owner_reserve});
v.setFieldU32(sfGasLimit, setup.gas_limit);
v.setFieldU32(sfBytecodeSizeLimit, setup.bytecode_size_limit);
v.setFieldU32(sfGasPrice, setup.gas_price);
});
if (i % 2)
val->setTrusted();
validations.push_back(val);
}
auto txSet =
std::make_shared<SHAMap>(SHAMapType::TRANSACTION, env.app().getNodeFamily());
// This should not throw since we have a flag ledger
feeVote->doVoting(ledger, validations, txSet);
auto const txs = getTxs(txSet);
BEAST_EXPECT(txs.size() == 1);
return {txs[0], ledger};
};
auto checkFeeTx = [&](FeeSetup const& setup,
STTx const& feeTx,
std::shared_ptr<Ledger> const& ledger,
std::source_location const loc = std::source_location::current()) {
auto const line = " (" + std::to_string(loc.line()) + ")";
BEAST_EXPECTS(feeTx.getTxnType() == ttFEE, line);
BEAST_EXPECTS(feeTx.getAccountID(sfAccount) == AccountID(), line);
BEAST_EXPECTS(feeTx.getFieldU32(sfLedgerSequence) == ledger->seq() + 1, line);
BEAST_EXPECTS(feeTx.isFieldPresent(sfBaseFeeDrops), line);
BEAST_EXPECTS(feeTx.isFieldPresent(sfReserveBaseDrops), line);
BEAST_EXPECTS(feeTx.isFieldPresent(sfReserveIncrementDrops), line);
// The legacy fields should NOT be present
BEAST_EXPECTS(!feeTx.isFieldPresent(sfBaseFee), line);
BEAST_EXPECTS(!feeTx.isFieldPresent(sfReserveBase), line);
BEAST_EXPECTS(!feeTx.isFieldPresent(sfReserveIncrement), line);
BEAST_EXPECTS(!feeTx.isFieldPresent(sfReferenceFeeUnits), line);
// Check the values
BEAST_EXPECTS(
feeTx.getFieldAmount(sfBaseFeeDrops) == XRPAmount{setup.reference_fee}, line);
BEAST_EXPECTS(
feeTx.getFieldAmount(sfReserveBaseDrops) == XRPAmount{setup.account_reserve}, line);
BEAST_EXPECTS(
feeTx.getFieldAmount(sfReserveIncrementDrops) == XRPAmount{setup.owner_reserve},
line);
BEAST_EXPECTS(feeTx.getFieldU32(sfGasLimit) == setup.gas_limit, line);
BEAST_EXPECTS(
feeTx.getFieldU32(sfBytecodeSizeLimit) == setup.bytecode_size_limit, line);
BEAST_EXPECTS(feeTx.getFieldU32(sfGasPrice) == setup.gas_price, line);
};
{
FeeSetup setup;
setup.reference_fee = 42;
setup.account_reserve = 1234567;
setup.owner_reserve = 7654321;
setup.gas_limit = 100;
setup.bytecode_size_limit = 200;
setup.gas_price = 300;
auto const [feeTx, ledger] = createFeeTxFromVoting(setup);
checkFeeTx(setup, feeTx, ledger);
}
{
FeeSetup setup;
setup.reference_fee = 42;
setup.account_reserve = 1234567;
setup.owner_reserve = 7654321;
setup.gas_limit = 0;
setup.bytecode_size_limit = 0;
setup.gas_price = 300;
auto const [feeTx, ledger] = createFeeTxFromVoting(setup);
checkFeeTx(setup, feeTx, ledger);
}
{
FeeSetup setup;
setup.reference_fee = 42;
setup.account_reserve = 1234567;
setup.owner_reserve = 7654321;
setup.gas_limit = kMaxGasLimit + 1;
setup.bytecode_size_limit = kMaxBytecodeSizeLimit + 1;
setup.gas_price = 300;
auto const [feeTx, ledger] = createFeeTxFromVoting(setup);
setup.gas_limit = ledger->fees().gasLimit;
setup.bytecode_size_limit = ledger->fees().bytecodeSizeLimit;
checkFeeTx(setup, feeTx, ledger);
}
}
void
run() override
{
@@ -742,6 +1099,7 @@ class FeeVote_test : public beast::unit_test::Suite
testSingleInvalidTransaction();
testDoValidation();
testDoVoting();
testDoVotingSmartEscrow();
}
};

View File

@@ -43,6 +43,12 @@ struct PseudoTx_test : public beast::unit_test::Suite
obj[sfReserveIncrement] = 0;
obj[sfReferenceFeeUnits] = 0;
}
if (rules.enabled(featureSmartEscrow))
{
obj[sfGasLimit] = 0;
obj[sfBytecodeSizeLimit] = 0;
obj[sfGasPrice] = 0;
}
});
res.emplace_back(ttAMENDMENT, [&](auto& obj) {
@@ -107,7 +113,9 @@ struct PseudoTx_test : public beast::unit_test::Suite
FeatureBitset const all{testableAmendments()};
FeatureBitset const xrpFees{featureXRPFees};
testPrevented(all - featureXRPFees - featureSmartEscrow);
testPrevented(all - featureXRPFees);
testPrevented(all - featureSmartEscrow);
testPrevented(all);
testAllowed();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
(module
(type (;0;) (func))
(type (;1;) (func (result i32)))
(func (;0;) (type 0))
(func (;1;) (type 1) (result i32)
f32.const -2048
f32.const 2050
f32.sub
drop
i32.const 1)
(memory (;0;) 2)
(global (;0;) i32 (i32.const 1024))
(global (;1;) i32 (i32.const 1024))
(global (;2;) i32 (i32.const 2048))
(global (;3;) i32 (i32.const 2048))
(global (;4;) i32 (i32.const 67584))
(global (;5;) i32 (i32.const 1024))
(global (;6;) i32 (i32.const 67584))
(global (;7;) i32 (i32.const 131072))
(global (;8;) i32 (i32.const 0))
(global (;9;) i32 (i32.const 1))
(export "memory" (memory 0))
(export "__wasm_call_ctors" (func 0))
(export "finish" (func 1))
(export "buf" (global 0))
(export "__dso_handle" (global 1))
(export "__data_end" (global 2))
(export "__stack_low" (global 3))
(export "__stack_high" (global 4))
(export "__global_base" (global 5))
(export "__heap_base" (global 6))
(export "__heap_end" (global 7))
(export "__memory_base" (global 8))
(export "__table_base" (global 9)))

View File

@@ -0,0 +1,11 @@
// typedef long long mint;
typedef int mint;
mint fib(mint n)
{
if (!n)
return 0;
if (n <= 2)
return 1;
return fib(n - 1) + fib(n - 2);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,11 @@
#include <string>
extern std::string const kFibWasmHex =
"0061736d0100000001090260000060017f017f0303020001071b02115f5f7761736d5f63616c6c5f63746f72730000"
"0366696200010a440202000b3f01017f200045044041000f0b2000410348044041010f0b200041026a210003402000"
"41036b100120016a2101200041026b220041044a0d000b200141016a0b";
extern std::string const kLedgerSqnWasmHex =
"0061736d01000000010e0360027f7f017f6000006000017f02160103656e760e6765745f6c65646765725f73716e00"
"0003030201020503010002063f0a7f01418088040b7f004180080b7f004180080b7f004180080b7f00418088040b7f"
@@ -196,6 +201,10 @@ extern std::string const kAllHostFunctionsWasmHex =
"392e30202832393438333838336520323032352d30382d303429002c0f7461726765745f6665617475726573022b0f"
"6d757461626c652d676c6f62616c732b087369676e2d657874";
extern std::string const kDeepRecursionHex =
"0061736d010000000105016000017f030201000608017f0141c0843d0b070a010666696e69736800000a1601140023"
"0045044041010f0b230041016b240010000b";
extern std::string const kAllKeyletsWasmHex =
"0061736d0100000001480960067f7f7f7f7f7f017f60047f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f01"
"7f60037f7f7e017f60057f7f7f7f7f017f60057f7f7f7f7f006000017f60037f7f7f000284051808686f73745f6c69"
@@ -817,6 +826,485 @@ extern std::string const kCodecovTestsWasmHex =
"6976616c75652b0f6d757461626c652d676c6f62616c732b136e6f6e7472617070696e672d6670746f696e742b0f72"
"65666572656e63652d74797065732b087369676e2d657874";
extern std::string const kFloatTestsWasmHex =
"0061736d0100000001490960057f7f7f7f7f017f60077f7f7f7f7f7f7f017f60067f7f7f7f7f7f017f60047e7f7f7f"
"017f60057e7f7f7f7f017f60047f7f7f7f017f60037f7f7e017f60037f7f7f006000017f02fa021008686f73745f6c"
"6962057472616365000008686f73745f6c69620e666c6f61745f66726f6d5f696e74000308686f73745f6c69620f66"
"6c6f61745f66726f6d5f75696e74000003656e7613666c6f61745f66726f6d5f6d616e745f657870000408686f7374"
"5f6c69620d666c6f61745f636f6d70617265000508686f73745f6c696209666c6f61745f616464000108686f73745f"
"6c69620e666c6f61745f7375627472616374000108686f73745f6c69620e666c6f61745f6d756c7469706c79000108"
"686f73745f6c69620c666c6f61745f646976696465000108686f73745f6c696209666c6f61745f706f77000208686f"
"73745f6c69620974726163655f6e756d000608686f73745f6c69620a666c6f61745f726f6f74000203656e760c666c"
"6f61745f746f5f696e74000003656e7611666c6f61745f746f5f6d616e745f657870000203656e7613666c6f61745f"
"66726f6d5f7374616d6f756e74000003656e7613666c6f61745f66726f6d5f73746e756d6265720000030302070805"
"030100110619037f01418080c0000b7f0041b49ac0000b7f0041c09ac0000b072e04066d656d6f727902000666696e"
"69736800110a5f5f646174615f656e6403010b5f5f686561705f6261736503020ab621021f00200020014101410041"
"0010001a418080c00041022002410c410110001a0b9321020c7f017e230041f0006b22002400418280c000411d4101"
"4100410010001a200041e8006a4100360200200042003703600240428ce000200041e0006a2203410c410010012201"
"410c460440419f80c00041172003101041b680c000411e2003410c410110001a0c010b41d480c000411e4101410041"
"0010001a0b2000428ce0003703500240200041d0006a4108200041e0006a2203410c41001002410c4604402001410c"
"46210741f280c0004117200310100c010b418981c000411e41014100410010001a0b024042fb004102200041e0006a"
"2201410c41001003410c46044041a781c0004121200110100c010b41c881c000412641014100410010001a41002107"
"0b41ee81c0004115418382c0001010418f82c000411641a582c000101041b182c000411b41014100410010001a2000"
"41e8006a41003602002000420037036002404201200041e0006a2203410c410010012201410c46044041cc82c00041"
"0f200310100c010b41db82c000411641014100410010001a0b027f200041e0006a410c418382c000410c1004450440"
"41f182c000411b41014100410010001a2001410c460c010b418c83c000412341014100410010001a41000b21080240"
"200041e0006a410c41a582c000410c1004410146044041af83c000412341014100410010001a0c010b4100210841d2"
"83c000412c41014100410010001a0b024041a582c000410c200041e0006a410c1004410246044041fe83c000412341"
"014100410010001a0c010b4100210841a184c000412c41014100410010001a0b41cd84c00041204101410041001000"
"1a200041d8006a418b82c0002800003602002000418382c000290000370350410921040340200041d0006a2201410c"
"418382c000410c2001410c410010051a200441016b22040d000b200041e8006a410036020020004200370360420a20"
"0041e0006a410c41001001410c46220945044041ed84c000411741014100410010001a0b0240200041e0006a410c20"
"0041d0006a410c1004450440418485c000411441014100410010001a0c010b41002109419885c00041164101410041"
"0010001a0b410b21040340200041d0006a2201410c418382c000410c2001410c410010061a200441016b22040d000b"
"02402001410c41a582c000410c100445044041ae85c000411941014100410010001a0c010b4100210941c785c00041"
"1b41014100410010001a0b41e285c000412341014100410010001a200041106a410036020020004200370308420a20"
"0041086a410c410010011a200041206a418b82c0002800003602002000418382c00029000037031841062104034020"
"0041186a2201410c200041086a410c2001410c410010071a200441016b22040d000b200041d8006a41003602002000"
"420037035042c0843d200041d0006a2203410c410010011a02402003410c2001410c10042201450440418586c00041"
"1941014100410010001a0c010b419e86c000411b41014100410010001a0b200145210a410721040340200041186a22"
"01410c200041086a410c2001410c410010081a200441016b22040d000b200041e8006a410036020020004200370360"
"4201417f200041e0006a2203410c410010031a02402001410c2003410c100445044041b986c0004117410141004100"
"10001a0c010b41d086c000411941014100410010001a4100210a0b41e986c000411741014100410010001a20004120"
"6a2204410036020020004200370318418382c000410c4103200041186a2205410c410010091a418087c00041122005"
"101041a582c000410c41062005410c410010091a419287c000411820051010200041d8006a22014100360200200042"
"003703504209200041d0006a2202410c410010011a2002410c41022005410c410010091a41aa87c000411420051010"
"2002410c41002005410c410010091a41be87c000411720051010200041e8006a220341003602002000420037036042"
"00200041e0006a2206410c410010011a2006410c41022005410c410010091a41d587c00041142005101041e987c000"
"41382006410c41002005410c41001009ac100a1a41a188c000411841014100410010001a2004410036020020004200"
"37031842092005410c410010011a20014100360200200042003703502005410c41022002410c4100100b1a41b988c0"
"004112200210102005410c41032002410c4100100b1a41cb88c0004112200210102003410036020020004200370360"
"42c0843d2006410c410010011a2006410c41032002410c4100100b1a41dd88c0004118200210102006410c41062002"
"410c4100100b1a41f588c000411c20021010419189c000411a41014100410010001a20014100360200200042003703"
"502003410036020020004200370360420a2006410c410010011a418382c000410c2006410c2002410c410010081a41"
"ab89c000411920021010418382c000410c2002410c2002410c410010081a41c489c000410f2002101002402006410c"
"2002410c1004220b45044041d389c000411441014100410010001a0c010b41e789c000411641014100410010001a0b"
"4100210141fd89c000411a41014100410010001a200042003703080240418382c000410c200041086a41084100100c"
"220341084604402000290308220c42015104404101210141978ac000411741014100410010001a0c020b41ae8ac000"
"411941014100410010001a41c78ac0004108200c100a1a0c010b41cf8ac000412441014100410010001a41f38ac000"
"410f2003ac100a1a0b41002104024041a582c000410c200041086a41084100100c220341084604402000290308220c"
"427f51044041828bc000411841014100410010001a200121040c020b419a8bc000411a41014100410010001a41c78a"
"c0004108200c100a1a0c010b41b48bc000412541014100410010001a41f38ac000410f2003ac100a1a0b4100210120"
"0041206a41003602002000420037031842ffffffffffffffffff00200041186a2203410c410010011a02402003410c"
"200041086a41084100100c220341084604402000290308220c42ffffffffffffffffff0051044041d98bc000411e41"
"014100410010001a200421010c020b41f78bc000412041014100410010001a41978cc000410d42ffffffffffffffff"
"ff00100a1a41c78ac0004108200c100a1a0c010b41a48cc000412b41014100410010001a41f38ac000410f2003ac10"
"0a1a0b41002103200041d8006a4100360200200042003703504200200041d0006a2204410c410010011a0240200441"
"0c200041086a41084100100c220441084604402000290308220c50044041cf8cc000411741014100410010001a2001"
"21030c020b41e68cc000411941014100410010001a41c78ac0004108200c100a1a0c010b41ff8cc000412441014100"
"410010001a41f38ac000410f2004ac100a1a0b41002104200041e8006a4100360200200042003703604201417f2000"
"41e0006a2201410c410010031a02402001410c200041086a41084100100c220141084604402000290308220c500440"
"41a38dc000412541014100410010001a200321040c020b41c88dc000412741014100410010001a41c78ac000410820"
"0c100a1a0c010b41ef8dc000413241014100410010001a41f38ac000410f2001ac100a1a0b0240200041e0006a410c"
"200041086a41084101100c220141084604402000290308220c50044041a18ec000412741014100410010001a0c020b"
"4100210441c88ec000412941014100410010001a41c78ac0004108200c100a1a0c010b4100210441f18ec000413441"
"014100410010001a41f38ac000410f2001ac100a1a0b4100210141a58fc000412c41014100410010001a2000420037"
"0328200041003602340240418382c000410c200041286a4108200041346a4104100d2203410c460440200028023422"
"03416e462000290328220c42808090bbbad6adf00d517145044041fa8fc000412b41014100410010001a41a590c000"
"412f200c100a1a41d490c000411f2003ac100a1a0c020b4101210141d18fc000412941014100410010001a0c010b41"
"f390c000413641014100410010001a41f38ac000410f2003ac100a1a0b200042003703384100210320004100360244"
"024041a582c000410c200041386a4108200041c4006a4104100d2202410c46044020002802442202416e4620002903"
"38220c428080f0c4c5a9d28f72517145044041d391c000412c41014100410010001a41ff91c0004130200c100a1a41"
"d490c000411f2002ac100a1a0c020b41a991c000412a41014100410010001a200121030c010b41af92c00041374101"
"4100410010001a41f38ac000410f2002ac100a1a0b41002101200041d8006a410036020020004200370350420a2000"
"41d0006a2202410c410010011a200042003703082000410036024802402002410c200041086a4108200041c8006a41"
"04100d2202410c46044020002802482202416f462000290308220c42808090bbbad6adf00d5171450440419093c000"
"412c41014100410010001a41a590c000412f200c100a1a41bc93c000411f2002ac100a1a0c020b41e692c000412a41"
"014100410010001a200321010c010b41db93c000413741014100410010001a41f38ac000410f2002ac100a1a0b4100"
"2103200041e8006a4100360200200042003703604200200041e0006a2202410c410010011a20004200370318200041"
"0036024c02402002410c200041186a4108200041cc006a4104100d2202410c4604402000290318220c50200028024c"
"2202418080808078467145044041bb94c000412b41014100410010001a41e694c000411d200c100a1a418395c00041"
"272002ac100a1a0c020b419294c000412941014100410010001a200121030c010b41aa95c000413641014100410010"
"001a41f38ac000410f2002ac100a1a0b4100210141e095c000412141014100410010001a200042c0808080d0a0fdf0"
"00370018200041e8006a41003602002000420037036002400240200041186a4108200041e0006a2205410c4100100e"
"2202410c460440418196c000412220051010200042003703502005410c200041d0006a41084100100c22024108470d"
"012000290350220c4280c2d72f5104404101210141a396c000411d41014100410010001a0c030b41c096c000411f41"
"014100410010001a41df96c000411c200c100a1a0c020b41af97c000411f41014100410010001a41ce97c000411020"
"02ac100a1a0c010b41fb96c000413441014100410010001a41f38ac000410f2002ac100a1a0b4100210241de97c000"
"412141014100410010001a200041ffffff8f7f36005820004281eceedce494ccf9c000370050200041e8006a410036"
"02002000420037036002400240200041d0006a410c200041e0006a2206410c4100100f2205410c46044041ff97c000"
"411c20061010200042003703182006410c200041186a41084100100c22054108470d012000290318220c42fb005104"
"4041012102419b98c000411b41014100410010001a0c030b41b698c000411d41014100410010001a41d398c0004116"
"200c100a1a0c020b419b99c000411d41014100410010001a41ce97c00041102005ac100a1a0c010b41e998c0004132"
"41014100410010001a41f38ac000410f2005ac100a1a0b410021050240418382c000410c200041e0006a2206410c41"
"00100f410c46044041b899c000411a200610102006410c418382c000410c100445044041d299c00041204101410041"
"0010001a200221050c020b41f299c000412241014100410010001a0c010b41949ac000412041014100410010001a0b"
"200041f0006a2400200b452007200871200971200a71200471200371200171200571710b0bbe1a0100418080c0000b"
"b41a20200a24242420746573745f666c6f61745f66726f6d5f7761736d202424242020666c6f61742066726f6d2069"
"36342031323330303a2020666c6f61742066726f6d20693634203132333030206173204845583a2020666c6f617420"
"66726f6d206936342031323330303a206661696c65642020666c6f61742066726f6d207536342031323330303a2020"
"666c6f61742066726f6d207536342031323330303a206661696c65642020666c6f61742066726f6d2065787020322c"
"206d616e7469737361203132333a2020666c6f61742066726f6d2065787020322c206d616e746973736120333a2066"
"61696c65642020666c6f61742066726f6d20636f6e737420313a0de0b6b3a7640000ffffffee2020666c6f61742066"
"726f6d20636f6e7374202d313af21f494c589c0000ffffffee0a24242420746573745f666c6f61745f636f6d706172"
"65202424242020666c6f61742066726f6d20313a2020666c6f61742066726f6d20313a206661696c65642020666c6f"
"61742066726f6d2031203d3d20464c4f41545f4f4e452020666c6f61742066726f6d203120213d20464c4f41545f4f"
"4e452c206661696c65642020666c6f61742066726f6d2031203e20464c4f41545f4e454741544956455f4f4e452020"
"666c6f61742066726f6d203120213e20464c4f41545f4e454741544956455f4f4e452c206661696c65642020464c4f"
"41545f4e454741544956455f4f4e45203c20666c6f61742066726f6d20312020464c4f41545f4e454741544956455f"
"4f4e4520213c20666c6f61742066726f6d20312c206661696c65640a24242420746573745f666c6f61745f6164645f"
"7375627472616374202424242020666c6f61742066726f6d2031303a206661696c6564202072657065617465642061"
"64643a20676f6f6420207265706561746564206164643a206661696c65642020726570656174656420737562747261"
"63743a20676f6f64202072657065617465642073756274726163743a206661696c65640a24242420746573745f666c"
"6f61745f6d756c7469706c795f6469766964652024242420207265706561746564206d756c7469706c793a20676f6f"
"6420207265706561746564206d756c7469706c793a206661696c656420207265706561746564206469766964653a20"
"676f6f6420207265706561746564206469766964653a206661696c65640a24242420746573745f666c6f61745f706f"
"77202424242020666c6f61742063756265206f6620313a2020666c6f61742036746820706f776572206f66202d313a"
"2020666c6f617420737175617265206f6620393a2020666c6f61742030746820706f776572206f6620393a2020666c"
"6f617420737175617265206f6620303a2020666c6f61742030746820706f776572206f662030202865787065637469"
"6e6720494e56414c49445f504152414d53206572726f72293a0a24242420746573745f666c6f61745f726f6f742024"
"24242020666c6f61742073717274206f6620393a2020666c6f61742063627274206f6620393a2020666c6f61742063"
"627274206f6620313030303030303a2020666c6f61742036746820726f6f74206f6620313030303030303a0a242424"
"20746573745f666c6f61745f696e76657274202424242020696e76657274206120666c6f61742066726f6d2031303a"
"2020696e7665727420616761696e3a2020696e766572742074776963653a20676f6f642020696e7665727420747769"
"63653a206661696c65640a24242420746573745f666c6f61745f746f5f696e74202424242020666c6f61745f746f5f"
"696e742831293a20676f6f642020666c6f61745f746f5f696e742831293a206661696c656420202020676f743a2020"
"666c6f61745f746f5f696e742831293a206661696c65642077697468206572726f72202020206572726f7220636f64"
"653a2020666c6f61745f746f5f696e74282d31293a20676f6f642020666c6f61745f746f5f696e74282d31293a2066"
"61696c65642020666c6f61745f746f5f696e74282d31293a206661696c65642077697468206572726f722020666c6f"
"61745f746f5f696e74286936343a3a4d4158293a20676f6f642020666c6f61745f746f5f696e74286936343a3a4d41"
"58293a206661696c65642020202065787065637465643a2020666c6f61745f746f5f696e74286936343a3a4d415829"
"3a206661696c65642077697468206572726f722020666c6f61745f746f5f696e742830293a20676f6f642020666c6f"
"61745f746f5f696e742830293a206661696c65642020666c6f61745f746f5f696e742830293a206661696c65642077"
"697468206572726f722020666c6f61745f746f5f696e7428302e312c20746f5f6e656172657374293a20676f6f6420"
"20666c6f61745f746f5f696e7428302e312c20746f5f6e656172657374293a206661696c65642020666c6f61745f74"
"6f5f696e7428302e312c20746f5f6e656172657374293a206661696c65642077697468206572726f722020666c6f61"
"745f746f5f696e7428302e312c20746f77617264735f7a65726f293a20676f6f642020666c6f61745f746f5f696e74"
"28302e312c20746f77617264735f7a65726f293a206661696c65642020666c6f61745f746f5f696e7428302e312c20"
"746f77617264735f7a65726f293a206661696c65642077697468206572726f720a24242420746573745f666c6f6174"
"5f746f5f6d616e74697373615f616e645f6578706f6e656e74202424242020666c6f61745f746f5f6d616e74697373"
"615f616e645f6578706f6e656e742831293a20676f6f642020666c6f61745f746f5f6d616e74697373615f616e645f"
"6578706f6e656e742831293a206661696c6564202020206578706563746564206d616e746973736120313030303030"
"303030303030303030303030302c20676f743a202020206578706563746564206578706f6e656e74202d31382c2067"
"6f743a2020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e742831293a206661696c656420"
"77697468206572726f722020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74282d31293a"
"20676f6f642020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74282d31293a206661696c"
"6564202020206578706563746564206d616e7469737361202d313030303030303030303030303030303030302c2067"
"6f743a2020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74282d31293a206661696c6564"
"2077697468206572726f722020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e7428313029"
"3a20676f6f642020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e74283130293a20666169"
"6c6564202020206578706563746564206578706f6e656e74202d31372c20676f743a2020666c6f61745f746f5f6d61"
"6e74697373615f616e645f6578706f6e656e74283130293a206661696c65642077697468206572726f722020666c6f"
"61745f746f5f6d616e74697373615f616e645f6578706f6e656e742830293a20676f6f642020666c6f61745f746f5f"
"6d616e74697373615f616e645f6578706f6e656e742830293a206661696c6564202020206578706563746564206d61"
"6e746973736120302c20676f743a202020206578706563746564206578706f6e656e74202d32313437343833363438"
"2c20676f743a2020666c6f61745f746f5f6d616e74697373615f616e645f6578706f6e656e742830293a206661696c"
"65642077697468206572726f720a24242420746573745f666c6f61745f66726f6d5f7374616d6f756e742024242420"
"20666c6f61742066726f6d2058525020616d6f756e74202831303020585250293a202058525020616d6f756e742063"
"6f6e76657273696f6e3a20676f6f64202058525020616d6f756e7420636f6e76657273696f6e3a206661696c656420"
"2020206578706563746564203130303030303030302c20676f743a202058525020616d6f756e7420636f6e76657273"
"696f6e3a206661696c6564202d20666c6f61745f746f5f696e74206572726f722020666c6f61742066726f6d205852"
"5020616d6f756e743a206661696c656420202020726573756c745f73697a653a0a24242420746573745f666c6f6174"
"5f66726f6d5f73746e756d626572202424242020666c6f61742066726f6d2053544e756d6265722028313233293a20"
"2053544e756d62657220636f6e76657273696f6e3a20676f6f64202053544e756d62657220636f6e76657273696f6e"
"3a206661696c6564202020206578706563746564203132332c20676f743a202053544e756d62657220636f6e766572"
"73696f6e3a206661696c6564202d20666c6f61745f746f5f696e74206572726f722020666c6f61742066726f6d2053"
"544e756d6265723a206661696c65642020666c6f61742066726f6d2053544e756d626572202831293a202053544e75"
"6d626572283129203d3d20464c4f41545f4f4e453a20676f6f64202053544e756d626572283129203d3d20464c4f41"
"545f4f4e453a206661696c65642020666c6f61742066726f6d2053544e756d6265722831293a206661696c6564004d"
"0970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d627901057275737463"
"1d312e38392e30202832393438333838336520323032352d30382d303429002c0f7461726765745f66656174757265"
"73022b0f6d757461626c652d676c6f62616c732b087369676e2d657874";
extern std::string const kFloat0Hex =
"0061736d0100000001290560057f7f7f7f7f017f60047e7f7f7f017f60077f7f7f7f7f7f7f017f60047f7f7f7f017f"
"6000017f025f0408686f73745f6c6962057472616365000008686f73745f6c69620e666c6f61745f66726f6d5f696e"
"74000108686f73745f6c69620e666c6f61745f7375627472616374000208686f73745f6c69620d666c6f61745f636f"
"6d7061726500030302010405030100110619037f01418080c0000b7f0041e980c0000b7f0041f080c0000b072e0406"
"6d656d6f727902000666696e69736800040a5f5f646174615f656e6403010b5f5f686561705f6261736503020ad201"
"01cf0101027f230041206b22002400418080c000411541014100410010001a200041086a4100360200200042003703"
"00200041186a41003602002000420037031002400240420a2000410c41001001410c4604402000410c2000410c2000"
"41106a2201410c41001002410c470d012001410c419580c000410c100345044041a180c000411a4101410041001000"
"1a0c030b41bb80c000411941014100410010001a0c020b41d480c000411541014100410010001a0c010b41d480c000"
"411541014100410010001a0b200041206a240041010b0b720100418080c0000b690a24242420746573745f666c6f61"
"745f30202424240000000000000000800000002020464c4f41545f5a45524f20636f6d706172653a20676f6f642020"
"464c4f41545f5a45524f20636f6d706172653a206261642020666c6f61742031302d31303a206661696c6564004d09"
"70726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d6279010572757374631d"
"312e38392e30202832393438333838336520323032352d30382d303429002c0f7461726765745f6665617475726573"
"022b0f6d757461626c652d676c6f62616c732b087369676e2d657874";
extern std::string const kDisabledFloatHex =
"0061736d010000000108026000006000017f03030200010503010002063e0a7f004180080b7f004180080b7f004180"
"100b7f004180100b7f00418090040b7f004180080b7f00418090040b7f00418080080b7f0041000b7f0041010b07b0"
"010d066d656d6f72790200115f5f7761736d5f63616c6c5f63746f727300000666696e69736800010362756603000c"
"5f5f64736f5f68616e646c6503010a5f5f646174615f656e6403020b5f5f737461636b5f6c6f7703030c5f5f737461"
"636b5f6869676803040d5f5f676c6f62616c5f6261736503050b5f5f686561705f6261736503060a5f5f686561705f"
"656e6403070d5f5f6d656d6f72795f6261736503080c5f5f7461626c655f6261736503090a150202000b1000430000"
"00c54300200045921a41010b";
extern std::string const kMemoryPointerAtLimitHex =
"0061736d010000000105016000017f030201000503010001070a010666696e69736800000a0e010c0041ffff032d00"
"001a41010b";
extern std::string const kMemoryPointerOverLimitHex =
"0061736d010000000105016000017f030201000503010001070a010666696e69736800000a0e010c00418080042d00"
"001a41010b";
extern std::string const kMemoryOffsetOverLimitHex =
"0061736d010000000105016000017f030201000503010001071302066d656d6f727902000666696e69736800000a0e"
"010c00410028028080041a41010b";
extern std::string const kMemoryEndOfWordOverLimitHex =
"0061736d010000000105016000017f030201000503010001071302066d656d6f727902000666696e69736800000a0e"
"010c0041feff032802001a41010b";
extern std::string const kMemoryGrow0To1PageHex =
"0061736d010000000105016000017f030201000503010000071302066d656d6f727902000666696e69736800000a0b"
"010900410140001a41010b";
extern std::string const kMemoryGrow1To0PageHex =
"0061736d010000000105016000017f030201000503010001071302066d656d6f727902000666696e69736800000a13"
"011100417f4000417f460440417f0f0b41010b";
extern std::string const kMemoryLastByteOf8MbHex =
"0061736d010000000105016000017f030201000506010180018001071302066d656d6f727902000666696e69736800"
"000a0f010d0041ffffff032d00001a41010b";
extern std::string const kMemoryGrow1MoreThan8MbHex =
"0061736d010000000105016000017f03020100050401008001071302066d656d6f727902000666696e69736800000a"
"1301110041014000417f460440417f0f0b41010b";
extern std::string const kMemoryGrow0MoreThan8MbHex =
"0061736d010000000105016000017f03020100050401008001071302066d656d6f727902000666696e69736800000a"
"1301110041004000417f460440417f0f0b41010b";
extern std::string const kMemoryInit1MoreThan8MbHex =
"0061736d010000000105016000017f030201000506010181018101071302066d656d6f727902000666696e69736800"
"000a0f010d0041ffffff032d00001a41010b";
extern std::string const kMemoryNegativeAddressHex =
"0061736d010000000105016000017f030201000506010180018001071302066d656d6f727902000666696e69736800"
"000a0c010a00417f2d00001a41010b";
extern std::string const kTable64ElementsHex =
"0061736d010000000108026000006000017f0303020001040401700040070a010666696e6973680001094601004100"
"0b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000a090202000b040041010b";
extern std::string const kTable65ElementsHex =
"0061736d010000000108026000006000017f0303020001040401700041070a010666696e6973680001094701004100"
"0b41000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000a090202000b040041010b";
extern std::string const kTable2TablesHex =
"0061736d010000000108026000006000017f03030200010409027001010170010101070a010666696e697368000109"
"0f020041000b0100020141000b0001000a090202000b040041010b";
extern std::string const kTable0ElementsHex =
"0061736d010000000105016000017f03020100040401700000070a010666696e69736800000a0601040041010b";
extern std::string const kTableUintMaxHex =
"0061736d010000000105016000017f030201000408017000ffffffff0f070a010666696e69736800000a0601040041"
"010b";
extern std::string const kProposalMutableGlobalHex =
"0061736d010000000105016000017f030201000606017f0141000b07140207636f756e74657203000666696e697368"
"00000a0d010b00230041016a240041010b";
extern std::string const kProposalGcStructNewHex =
"0061736d01000000010b026000017f5f027f017f0103020100070a010666696e69736800000a0a010800fb01011a41"
"010b";
extern std::string const kProposalMultiValueHex =
"0061736d010000000110036000027f7f6000017f60027f7f017f0303020001070a010666696e69736800010a140206"
"00410a41140b0b00100002026a411e460b0b";
extern std::string const kProposalSignExtHex =
"0061736d010000000105016000017f03020100070a010666696e69736800000a0b01090041ff01c0417f460b";
extern std::string const kProposalFloatToIntHex =
"0061736d010000000105016000017f03020100070a010666696e69736800000a1201100043f9021550fc0041ffffff"
"ff07460b";
extern std::string const kProposalBulkMemoryHex =
"0061736d010000000105016000017f030201000503010001071302066d656d6f727902000666696e69736800000a1f"
"011d004100412a3a000041e40041004101fc0a000041e4002d0000412a460b";
extern std::string const kProposalRefTypesHex =
"0061736d010000000105016000017f020f0103656e76057461626c65016f000103020100070a010666696e69736800"
"000a0c010a004100d06f260041010b";
extern std::string const kProposalTailCallHex =
"0061736d010000000105016000017f0303020000070a010666696e69736800010a0b02040041010b040012000b";
extern std::string const kProposalExtendedConstHex =
"0061736d010000000105016000017f030201000609017f00410a41206a0b070a010666696e69736800000a09010700"
"2300412a460b";
extern std::string const kProposalMultiMemoryHex =
"0061736d010000000105016000017f0302010005050200000001070a010666696e69736800000a060104003f010b";
extern std::string const kProposalCustomPageSizesHex =
"0061736d010000000105016000017f0302010005040108010a070a010666696e69736800000a0601040041010b0010"
"046e616d65010901000666696e697368";
extern std::string const kProposalMemory64Hex =
"0061736d010000000105016000017f030201000503010401070a010666696e69736800000a10010e004200412a3a00"
"003f004201510b0010046e616d65010901000666696e697368";
extern std::string const kProposalWideArithmeticHex =
"0061736d010000000105016000017f03020100070a010666696e69736800000a0e010c0042014202fc161a1a41010b"
"0010046e616d65010901000666696e697368";
extern std::string const kTrapDivideBy0Hex =
"0061736d010000000105016000017f03020100070a010666696e69736800000a0c010a00412a41006d1a41010b";
extern std::string const kTrapIntOverflowHex =
"0061736d010000000105016000017f03020100070a010666696e69736800000a0d010b00418080808078417f6d0b";
extern std::string const kTrapUnreachableHex =
"0061736d010000000105016000017f03020100070a010666696e69736800000a070105000041010b";
extern std::string const kTrapNullCallHex =
"0061736d010000000105016000017f03020100040401700001070a010666696e69736800000a090107004100110000"
"0b";
extern std::string const kTrapFuncSigMismatchHex =
"0061736d010000000108026000006000017f0303020001040401700001070a010666696e6973680001090701004100"
"0b01000a0d020300010b070041001101000b";
extern std::string const kWasiGetTimeHex =
"0061736d01000000010c0260037f7e7f017f6000017f02290116776173695f736e617073686f745f70726576696577"
"310e636c6f636b5f74696d655f6765740000030201010503010001071302066d656d6f727902000666696e69736800"
"010a16011400410042e8074100100045047f410105417f0b0b";
extern std::string const kWasiPrintHex =
"0061736d01000000010d0260047f7f7f7f017f6000017f02230116776173695f736e617073686f745f707265766965"
"77310866645f77726974650000030201010503010001071302066d656d6f727902000666696e69736800010a1d011b"
"01017f411821004101410041012000100045047f410105417f0b0b0b1e030041100b0648656c6c6f0a0041000b0410"
"0000000041040b0406000000";
// The following several wasm hex strings are for testing wasm section
// corruption cases. They are illegal hence do not have corresponding
// rust or wat sources.
// Wasm code magic number is "0061736d", and the only valid version is 1.
extern std::string const kBadMagicNumberHex = "1061736d01000000";
extern std::string const kBadVersionNumberHex = "0061736d02000000";
// Corruption Test: lyingHeader
// Scenario: A section declares it is 2GB long, but the file ends immediately.
// Attack: Buffer pre-allocation DoS (OOM).
// # Magic (00 61 73 6d) + Version (01 00 00 00)
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Type Section (ID 1)
// # Size: LEB128 encoded 2GB (0x80 0x80 0x80 0x80 0x08)
// data += b'\x01\x80\x80\x80\x80\x08'
extern std::string const kLyingHeaderHex = "0061736d01000000018080808008";
// Corruption Test: neverEndingNumber
// Scenario: An LEB128 integer that never has a stop bit (byte < 0x80).
// Attack: Infinite loop in parser or read out of bounds.
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Type Section (ID 1), Size 5
// data += b'\x01\x05'
// # Vector count: Infinite stream of 0x80 (100 bytes)
// data += b'\x80' * 100
extern std::string const kNeverEndingNumberHex =
"0061736d01000000010580808080808080808080808080808080808080808080808080808080808080808080808080"
"8080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080"
"80808080808080808080808080808080";
// Corruption Test: vectorLie
// Scenario: A vector declares it has 4 billion items, but provides none.
// Attack: Vector pre-allocation DoS (OOM).
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Type Section (ID 1)
// # Size 5 (just enough for the count bytes)
// data += b'\x01\x05'
// # Vector Count: 0xFF 0xFF 0xFF 0xFF 0x0F (4,294,967,295 items)
// data += b'\xff\xff\xff\xff\x0f'
// # No actual items follow...
extern std::string const kVectorLieHex = "0061736d010000000105ffffffff0f";
// Corruption Test: sectionOrdering
// Scenario: Sections appear out of order
// (Code section before Function section).
// Attack: Parser state confusion / potential null pointer deref.
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Code Section (ID 10) - usually last
// # Size 2, Count 0
// data += b'\x0a\x02\x00\x0b'
// # Function Section (ID 3) - usually 3rd
// data += b'\x03\x02\x00\x00'
extern std::string const kSectionOrderingHex = "0061736d010000000a02000b03020000";
// Corruption Test: ghostPayload
// Scenario: Valid headers, but file is truncated in the middle of a payload.
// Attack: Read out of bounds panic.
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Type Section (ID 1), Size 10
// data += b'\x01\x0a'
// # Content: Count 1
// data += b'\x01'
// # Start of a type definition (0x60 = func)
// data += b'\x60'
// # File ends abruptly here (missing params/results)
extern std::string const kGhostPayloadHex = "0061736d01000000010a0160";
// Corruption Test: junkAfterSection
// Scenario: Section declares size X, but logical content finishes at X-5.
// Attack: Validation bypass if parser stops early,
// or panic if strict check missing.
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Type Section (ID 1), Size 10 bytes
// data += b'\x01\x0a'
// # Real content: Count 1, (func -> void) = 4 bytes
// # \x01 (count) \x60 (func) \x00 (0 params) \x00 (0 results)
// data += b'\x01\x60\x00\x00'
// # Remaining 6 bytes are junk padding within the section size
// data += b'\x00' * 6
extern std::string const kJunkAfterSectionHex = "0061736d01000000010a01600000000000000000";
// Corruption Test: invalidSectionId
// Scenario: A section ID that doesn't exist (0xFF).
// Attack: Default case handling / unhandled enum variant.
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # Section ID 0xFF, Size 1
// data += b'\xff\x01\x00'
extern std::string const kInvalidSectionIdHex = "0061736d01000000ff0100";
// Corruption Test: localVariableBomb
// Scenario: A function declares 4 billion local variables.
// Attack: Stack Overflow / OOM during function init (memset).
// data = b'\x00\x61\x73\x6d\x01\x00\x00\x00'
// # 1. Type Section: (func) -> ()
// data += b'\x01\x04\x01\x60\x00\x00'
// # 3. Function Section: 1 function of type 0
// data += b'\x03\x02\x01\x00'
// # 10. Code Section
// # ID 10, Size 15 (estimated), Count 1
// data += b'\x0a\x0f\x01'
// # Function Body Size: 13 bytes
// data += b'\x0d'
// # Local Declarations Count: 1 entry
// data += b'\x01'
// # The Bomb: 4,294,967,295 locals of type i32
// # Count: 0xFF 0xFF 0xFF 0xFF 0x0F
// # Type: 0x7F (i32)
// data += b'\xff\xff\xff\xff\x0f\x7f'
// # Instruction: end (0x0b)
// data += b'\x0b'
extern std::string const kLocalVariableBombHex =
"0061736d01000000010401600000030201000a0f010d01ffffffff0f7f0b";
extern std::string const kInfiniteLoopWasmHex =
"0061736d010000000108026000006000017f030302000105030100020638097f004180080b7f004180080b7f004180"
"080b7f00418088040b7f004180080b7f00418088040b7f00418080080b7f0041000b7f0041010b07a8010c066d656d"
"6f72790200115f5f7761736d5f63616c6c5f63746f72730000046c6f6f7000010c5f5f64736f5f68616e646c650300"
"0a5f5f646174615f656e6403010b5f5f737461636b5f6c6f7703020c5f5f737461636b5f6869676803030d5f5f676c"
"6f62616c5f6261736503040b5f5f686561705f6261736503050a5f5f686561705f656e6403060d5f5f6d656d6f7279"
"5f6261736503070c5f5f7461626c655f6261736503080a270202000b220041fc87044100360200034041fc870441fc"
"870428020041016a3602000c000b000b007f0970726f647563657273010c70726f6365737365642d62790105636c61"
"6e675f31392e312e352d776173692d73646b202868747470733a2f2f6769746875622e636f6d2f6c6c766d2f6c6c76"
"6d2d70726f6a6563742061623462356132646235383239353861663165653330386137393063666462343262643234"
"3732302900490f7461726765745f6665617475726573042b0f6d757461626c652d676c6f62616c732b087369676e2d"
"6578742b0f7265666572656e63652d74797065732b0a6d756c746976616c7565";
extern std::string const kStartLoopHex =
"0061736d010000000108026000006000017f030302000107120205737461727400000666696e69736800010801000a"
"0e02070003400c000b0b040041010b";
extern std::string const kBadAlignWasmHex =
"0061736d01000000011b046000017f60057f7f7f7f7f017f60067f7f7f7f7f7f017f600000022a0203656e760f666c"
"6f61745f66726f6d5f75696e74000103656e760c636865636b5f6b65796c6574000203050403000000050301000306"
@@ -837,3 +1325,247 @@ extern std::string const kBadAlignWasmHex =
"6462353832393538616631656533303861373930636664623432626432343732302900490f7461726765745f666561"
"7475726573042b0f6d757461626c652d676c6f62616c732b087369676e2d6578742b0f7265666572656e63652d7479"
"7065732b0a6d756c746976616c7565";
extern std::string const kThousandParamsHex =
"0061736d0100000001f1070260000060e8077f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f017f030302000105030100020638097f"
"004180080b7f004180080b7f004180080b7f00418088040b7f004180080b7f00418088040b7f00418080080b7f0041"
"000b7f0041010b07a8010c066d656d6f72790200115f5f7761736d5f63616c6c5f63746f7273000004746573740001"
"0c5f5f64736f5f68616e646c6503000a5f5f646174615f656e6403010b5f5f737461636b5f6c6f7703020c5f5f7374"
"61636b5f6869676803030d5f5f676c6f62616c5f6261736503040b5f5f686561705f6261736503050a5f5f68656170"
"5f656e6403060d5f5f6d656d6f72795f6261736503070c5f5f7461626c655f6261736503080aa71e0202000ba11e00"
"200020016a20026a20036a20046a20056a20066a20076a20086a20096a200a6a200b6a200c6a200d6a200e6a200f6a"
"20106a20116a20126a20136a20146a20156a20166a20176a20186a20196a201a6a201b6a201c6a201d6a201e6a201f"
"6a20206a20216a20226a20236a20246a20256a20266a20276a20286a20296a202a6a202b6a202c6a202d6a202e6a20"
"2f6a20306a20316a20326a20336a20346a20356a20366a20376a20386a20396a203a6a203b6a203c6a203d6a203e6a"
"203f6a20406a20416a20426a20436a20446a20456a20466a20476a20486a20496a204a6a204b6a204c6a204d6a204e"
"6a204f6a20506a20516a20526a20536a20546a20556a20566a20576a20586a20596a205a6a205b6a205c6a205d6a20"
"5e6a205f6a20606a20616a20626a20636a20646a20656a20666a20676a20686a20696a206a6a206b6a206c6a206d6a"
"206e6a206f6a20706a20716a20726a20736a20746a20756a20766a20776a20786a20796a207a6a207b6a207c6a207d"
"6a207e6a207f6a2080016a2081016a2082016a2083016a2084016a2085016a2086016a2087016a2088016a2089016a"
"208a016a208b016a208c016a208d016a208e016a208f016a2090016a2091016a2092016a2093016a2094016a209501"
"6a2096016a2097016a2098016a2099016a209a016a209b016a209c016a209d016a209e016a209f016a20a0016a20a1"
"016a20a2016a20a3016a20a4016a20a5016a20a6016a20a7016a20a8016a20a9016a20aa016a20ab016a20ac016a20"
"ad016a20ae016a20af016a20b0016a20b1016a20b2016a20b3016a20b4016a20b5016a20b6016a20b7016a20b8016a"
"20b9016a20ba016a20bb016a20bc016a20bd016a20be016a20bf016a20c0016a20c1016a20c2016a20c3016a20c401"
"6a20c5016a20c6016a20c7016a20c8016a20c9016a20ca016a20cb016a20cc016a20cd016a20ce016a20cf016a20d0"
"016a20d1016a20d2016a20d3016a20d4016a20d5016a20d6016a20d7016a20d8016a20d9016a20da016a20db016a20"
"dc016a20dd016a20de016a20df016a20e0016a20e1016a20e2016a20e3016a20e4016a20e5016a20e6016a20e7016a"
"20e8016a20e9016a20ea016a20eb016a20ec016a20ed016a20ee016a20ef016a20f0016a20f1016a20f2016a20f301"
"6a20f4016a20f5016a20f6016a20f7016a20f8016a20f9016a20fa016a20fb016a20fc016a20fd016a20fe016a20ff"
"016a2080026a2081026a2082026a2083026a2084026a2085026a2086026a2087026a2088026a2089026a208a026a20"
"8b026a208c026a208d026a208e026a208f026a2090026a2091026a2092026a2093026a2094026a2095026a2096026a"
"2097026a2098026a2099026a209a026a209b026a209c026a209d026a209e026a209f026a20a0026a20a1026a20a202"
"6a20a3026a20a4026a20a5026a20a6026a20a7026a20a8026a20a9026a20aa026a20ab026a20ac026a20ad026a20ae"
"026a20af026a20b0026a20b1026a20b2026a20b3026a20b4026a20b5026a20b6026a20b7026a20b8026a20b9026a20"
"ba026a20bb026a20bc026a20bd026a20be026a20bf026a20c0026a20c1026a20c2026a20c3026a20c4026a20c5026a"
"20c6026a20c7026a20c8026a20c9026a20ca026a20cb026a20cc026a20cd026a20ce026a20cf026a20d0026a20d102"
"6a20d2026a20d3026a20d4026a20d5026a20d6026a20d7026a20d8026a20d9026a20da026a20db026a20dc026a20dd"
"026a20de026a20df026a20e0026a20e1026a20e2026a20e3026a20e4026a20e5026a20e6026a20e7026a20e8026a20"
"e9026a20ea026a20eb026a20ec026a20ed026a20ee026a20ef026a20f0026a20f1026a20f2026a20f3026a20f4026a"
"20f5026a20f6026a20f7026a20f8026a20f9026a20fa026a20fb026a20fc026a20fd026a20fe026a20ff026a208003"
"6a2081036a2082036a2083036a2084036a2085036a2086036a2087036a2088036a2089036a208a036a208b036a208c"
"036a208d036a208e036a208f036a2090036a2091036a2092036a2093036a2094036a2095036a2096036a2097036a20"
"98036a2099036a209a036a209b036a209c036a209d036a209e036a209f036a20a0036a20a1036a20a2036a20a3036a"
"20a4036a20a5036a20a6036a20a7036a20a8036a20a9036a20aa036a20ab036a20ac036a20ad036a20ae036a20af03"
"6a20b0036a20b1036a20b2036a20b3036a20b4036a20b5036a20b6036a20b7036a20b8036a20b9036a20ba036a20bb"
"036a20bc036a20bd036a20be036a20bf036a20c0036a20c1036a20c2036a20c3036a20c4036a20c5036a20c6036a20"
"c7036a20c8036a20c9036a20ca036a20cb036a20cc036a20cd036a20ce036a20cf036a20d0036a20d1036a20d2036a"
"20d3036a20d4036a20d5036a20d6036a20d7036a20d8036a20d9036a20da036a20db036a20dc036a20dd036a20de03"
"6a20df036a20e0036a20e1036a20e2036a20e3036a20e4036a20e5036a20e6036a20e7036a20e8036a20e9036a20ea"
"036a20eb036a20ec036a20ed036a20ee036a20ef036a20f0036a20f1036a20f2036a20f3036a20f4036a20f5036a20"
"f6036a20f7036a20f8036a20f9036a20fa036a20fb036a20fc036a20fd036a20fe036a20ff036a2080046a2081046a"
"2082046a2083046a2084046a2085046a2086046a2087046a2088046a2089046a208a046a208b046a208c046a208d04"
"6a208e046a208f046a2090046a2091046a2092046a2093046a2094046a2095046a2096046a2097046a2098046a2099"
"046a209a046a209b046a209c046a209d046a209e046a209f046a20a0046a20a1046a20a2046a20a3046a20a4046a20"
"a5046a20a6046a20a7046a20a8046a20a9046a20aa046a20ab046a20ac046a20ad046a20ae046a20af046a20b0046a"
"20b1046a20b2046a20b3046a20b4046a20b5046a20b6046a20b7046a20b8046a20b9046a20ba046a20bb046a20bc04"
"6a20bd046a20be046a20bf046a20c0046a20c1046a20c2046a20c3046a20c4046a20c5046a20c6046a20c7046a20c8"
"046a20c9046a20ca046a20cb046a20cc046a20cd046a20ce046a20cf046a20d0046a20d1046a20d2046a20d3046a20"
"d4046a20d5046a20d6046a20d7046a20d8046a20d9046a20da046a20db046a20dc046a20dd046a20de046a20df046a"
"20e0046a20e1046a20e2046a20e3046a20e4046a20e5046a20e6046a20e7046a20e8046a20e9046a20ea046a20eb04"
"6a20ec046a20ed046a20ee046a20ef046a20f0046a20f1046a20f2046a20f3046a20f4046a20f5046a20f6046a20f7"
"046a20f8046a20f9046a20fa046a20fb046a20fc046a20fd046a20fe046a20ff046a2080056a2081056a2082056a20"
"83056a2084056a2085056a2086056a2087056a2088056a2089056a208a056a208b056a208c056a208d056a208e056a"
"208f056a2090056a2091056a2092056a2093056a2094056a2095056a2096056a2097056a2098056a2099056a209a05"
"6a209b056a209c056a209d056a209e056a209f056a20a0056a20a1056a20a2056a20a3056a20a4056a20a5056a20a6"
"056a20a7056a20a8056a20a9056a20aa056a20ab056a20ac056a20ad056a20ae056a20af056a20b0056a20b1056a20"
"b2056a20b3056a20b4056a20b5056a20b6056a20b7056a20b8056a20b9056a20ba056a20bb056a20bc056a20bd056a"
"20be056a20bf056a20c0056a20c1056a20c2056a20c3056a20c4056a20c5056a20c6056a20c7056a20c8056a20c905"
"6a20ca056a20cb056a20cc056a20cd056a20ce056a20cf056a20d0056a20d1056a20d2056a20d3056a20d4056a20d5"
"056a20d6056a20d7056a20d8056a20d9056a20da056a20db056a20dc056a20dd056a20de056a20df056a20e0056a20"
"e1056a20e2056a20e3056a20e4056a20e5056a20e6056a20e7056a20e8056a20e9056a20ea056a20eb056a20ec056a"
"20ed056a20ee056a20ef056a20f0056a20f1056a20f2056a20f3056a20f4056a20f5056a20f6056a20f7056a20f805"
"6a20f9056a20fa056a20fb056a20fc056a20fd056a20fe056a20ff056a2080066a2081066a2082066a2083066a2084"
"066a2085066a2086066a2087066a2088066a2089066a208a066a208b066a208c066a208d066a208e066a208f066a20"
"90066a2091066a2092066a2093066a2094066a2095066a2096066a2097066a2098066a2099066a209a066a209b066a"
"209c066a209d066a209e066a209f066a20a0066a20a1066a20a2066a20a3066a20a4066a20a5066a20a6066a20a706"
"6a20a8066a20a9066a20aa066a20ab066a20ac066a20ad066a20ae066a20af066a20b0066a20b1066a20b2066a20b3"
"066a20b4066a20b5066a20b6066a20b7066a20b8066a20b9066a20ba066a20bb066a20bc066a20bd066a20be066a20"
"bf066a20c0066a20c1066a20c2066a20c3066a20c4066a20c5066a20c6066a20c7066a20c8066a20c9066a20ca066a"
"20cb066a20cc066a20cd066a20ce066a20cf066a20d0066a20d1066a20d2066a20d3066a20d4066a20d5066a20d606"
"6a20d7066a20d8066a20d9066a20da066a20db066a20dc066a20dd066a20de066a20df066a20e0066a20e1066a20e2"
"066a20e3066a20e4066a20e5066a20e6066a20e7066a20e8066a20e9066a20ea066a20eb066a20ec066a20ed066a20"
"ee066a20ef066a20f0066a20f1066a20f2066a20f3066a20f4066a20f5066a20f6066a20f7066a20f8066a20f9066a"
"20fa066a20fb066a20fc066a20fd066a20fe066a20ff066a2080076a2081076a2082076a2083076a2084076a208507"
"6a2086076a2087076a2088076a2089076a208a076a208b076a208c076a208d076a208e076a208f076a2090076a2091"
"076a2092076a2093076a2094076a2095076a2096076a2097076a2098076a2099076a209a076a209b076a209c076a20"
"9d076a209e076a209f076a20a0076a20a1076a20a2076a20a3076a20a4076a20a5076a20a6076a20a7076a20a8076a"
"20a9076a20aa076a20ab076a20ac076a20ad076a20ae076a20af076a20b0076a20b1076a20b2076a20b3076a20b407"
"6a20b5076a20b6076a20b7076a20b8076a20b9076a20ba076a20bb076a20bc076a20bd076a20be076a20bf076a20c0"
"076a20c1076a20c2076a20c3076a20c4076a20c5076a20c6076a20c7076a20c8076a20c9076a20ca076a20cb076a20"
"cc076a20cd076a20ce076a20cf076a20d0076a20d1076a20d2076a20d3076a20d4076a20d5076a20d6076a20d7076a"
"20d8076a20d9076a20da076a20db076a20dc076a20dd076a20de076a20df076a20e0076a20e1076a20e2076a20e307"
"6a20e4076a20e5076a20e6076a20e7076a0b007f0970726f647563657273010c70726f6365737365642d6279010563"
"6c616e675f31392e312e352d776173692d73646b202868747470733a2f2f6769746875622e636f6d2f6c6c766d2f6c"
"6c766d2d70726f6a656374206162346235613264623538323935386166316565333038613739306366646234326264"
"32343732302900490f7461726765745f6665617475726573042b0f6d757461626c652d676c6f62616c732b08736967"
"6e2d6578742b0f7265666572656e63652d74797065732b0a6d756c746976616c7565";
extern std::string const kThousand1ParamsHex =
"0061736d0100000001f2070260000060e9077f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f"
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f017f03030200010503010002063809"
"7f004180080b7f004180080b7f004180080b7f00418088040b7f004180080b7f00418088040b7f00418080080b7f00"
"41000b7f0041010b07a8010c066d656d6f72790200115f5f7761736d5f63616c6c5f63746f72730000047465737400"
"010c5f5f64736f5f68616e646c6503000a5f5f646174615f656e6403010b5f5f737461636b5f6c6f7703020c5f5f73"
"7461636b5f6869676803030d5f5f676c6f62616c5f6261736503040b5f5f686561705f6261736503050a5f5f686561"
"705f656e6403060d5f5f6d656d6f72795f6261736503070c5f5f7461626c655f6261736503080aab1e0202000ba51e"
"00200020016a20026a20036a20046a20056a20066a20076a20086a20096a200a6a200b6a200c6a200d6a200e6a200f"
"6a20106a20116a20126a20136a20146a20156a20166a20176a20186a20196a201a6a201b6a201c6a201d6a201e6a20"
"1f6a20206a20216a20226a20236a20246a20256a20266a20276a20286a20296a202a6a202b6a202c6a202d6a202e6a"
"202f6a20306a20316a20326a20336a20346a20356a20366a20376a20386a20396a203a6a203b6a203c6a203d6a203e"
"6a203f6a20406a20416a20426a20436a20446a20456a20466a20476a20486a20496a204a6a204b6a204c6a204d6a20"
"4e6a204f6a20506a20516a20526a20536a20546a20556a20566a20576a20586a20596a205a6a205b6a205c6a205d6a"
"205e6a205f6a20606a20616a20626a20636a20646a20656a20666a20676a20686a20696a206a6a206b6a206c6a206d"
"6a206e6a206f6a20706a20716a20726a20736a20746a20756a20766a20776a20786a20796a207a6a207b6a207c6a20"
"7d6a207e6a207f6a2080016a2081016a2082016a2083016a2084016a2085016a2086016a2087016a2088016a208901"
"6a208a016a208b016a208c016a208d016a208e016a208f016a2090016a2091016a2092016a2093016a2094016a2095"
"016a2096016a2097016a2098016a2099016a209a016a209b016a209c016a209d016a209e016a209f016a20a0016a20"
"a1016a20a2016a20a3016a20a4016a20a5016a20a6016a20a7016a20a8016a20a9016a20aa016a20ab016a20ac016a"
"20ad016a20ae016a20af016a20b0016a20b1016a20b2016a20b3016a20b4016a20b5016a20b6016a20b7016a20b801"
"6a20b9016a20ba016a20bb016a20bc016a20bd016a20be016a20bf016a20c0016a20c1016a20c2016a20c3016a20c4"
"016a20c5016a20c6016a20c7016a20c8016a20c9016a20ca016a20cb016a20cc016a20cd016a20ce016a20cf016a20"
"d0016a20d1016a20d2016a20d3016a20d4016a20d5016a20d6016a20d7016a20d8016a20d9016a20da016a20db016a"
"20dc016a20dd016a20de016a20df016a20e0016a20e1016a20e2016a20e3016a20e4016a20e5016a20e6016a20e701"
"6a20e8016a20e9016a20ea016a20eb016a20ec016a20ed016a20ee016a20ef016a20f0016a20f1016a20f2016a20f3"
"016a20f4016a20f5016a20f6016a20f7016a20f8016a20f9016a20fa016a20fb016a20fc016a20fd016a20fe016a20"
"ff016a2080026a2081026a2082026a2083026a2084026a2085026a2086026a2087026a2088026a2089026a208a026a"
"208b026a208c026a208d026a208e026a208f026a2090026a2091026a2092026a2093026a2094026a2095026a209602"
"6a2097026a2098026a2099026a209a026a209b026a209c026a209d026a209e026a209f026a20a0026a20a1026a20a2"
"026a20a3026a20a4026a20a5026a20a6026a20a7026a20a8026a20a9026a20aa026a20ab026a20ac026a20ad026a20"
"ae026a20af026a20b0026a20b1026a20b2026a20b3026a20b4026a20b5026a20b6026a20b7026a20b8026a20b9026a"
"20ba026a20bb026a20bc026a20bd026a20be026a20bf026a20c0026a20c1026a20c2026a20c3026a20c4026a20c502"
"6a20c6026a20c7026a20c8026a20c9026a20ca026a20cb026a20cc026a20cd026a20ce026a20cf026a20d0026a20d1"
"026a20d2026a20d3026a20d4026a20d5026a20d6026a20d7026a20d8026a20d9026a20da026a20db026a20dc026a20"
"dd026a20de026a20df026a20e0026a20e1026a20e2026a20e3026a20e4026a20e5026a20e6026a20e7026a20e8026a"
"20e9026a20ea026a20eb026a20ec026a20ed026a20ee026a20ef026a20f0026a20f1026a20f2026a20f3026a20f402"
"6a20f5026a20f6026a20f7026a20f8026a20f9026a20fa026a20fb026a20fc026a20fd026a20fe026a20ff026a2080"
"036a2081036a2082036a2083036a2084036a2085036a2086036a2087036a2088036a2089036a208a036a208b036a20"
"8c036a208d036a208e036a208f036a2090036a2091036a2092036a2093036a2094036a2095036a2096036a2097036a"
"2098036a2099036a209a036a209b036a209c036a209d036a209e036a209f036a20a0036a20a1036a20a2036a20a303"
"6a20a4036a20a5036a20a6036a20a7036a20a8036a20a9036a20aa036a20ab036a20ac036a20ad036a20ae036a20af"
"036a20b0036a20b1036a20b2036a20b3036a20b4036a20b5036a20b6036a20b7036a20b8036a20b9036a20ba036a20"
"bb036a20bc036a20bd036a20be036a20bf036a20c0036a20c1036a20c2036a20c3036a20c4036a20c5036a20c6036a"
"20c7036a20c8036a20c9036a20ca036a20cb036a20cc036a20cd036a20ce036a20cf036a20d0036a20d1036a20d203"
"6a20d3036a20d4036a20d5036a20d6036a20d7036a20d8036a20d9036a20da036a20db036a20dc036a20dd036a20de"
"036a20df036a20e0036a20e1036a20e2036a20e3036a20e4036a20e5036a20e6036a20e7036a20e8036a20e9036a20"
"ea036a20eb036a20ec036a20ed036a20ee036a20ef036a20f0036a20f1036a20f2036a20f3036a20f4036a20f5036a"
"20f6036a20f7036a20f8036a20f9036a20fa036a20fb036a20fc036a20fd036a20fe036a20ff036a2080046a208104"
"6a2082046a2083046a2084046a2085046a2086046a2087046a2088046a2089046a208a046a208b046a208c046a208d"
"046a208e046a208f046a2090046a2091046a2092046a2093046a2094046a2095046a2096046a2097046a2098046a20"
"99046a209a046a209b046a209c046a209d046a209e046a209f046a20a0046a20a1046a20a2046a20a3046a20a4046a"
"20a5046a20a6046a20a7046a20a8046a20a9046a20aa046a20ab046a20ac046a20ad046a20ae046a20af046a20b004"
"6a20b1046a20b2046a20b3046a20b4046a20b5046a20b6046a20b7046a20b8046a20b9046a20ba046a20bb046a20bc"
"046a20bd046a20be046a20bf046a20c0046a20c1046a20c2046a20c3046a20c4046a20c5046a20c6046a20c7046a20"
"c8046a20c9046a20ca046a20cb046a20cc046a20cd046a20ce046a20cf046a20d0046a20d1046a20d2046a20d3046a"
"20d4046a20d5046a20d6046a20d7046a20d8046a20d9046a20da046a20db046a20dc046a20dd046a20de046a20df04"
"6a20e0046a20e1046a20e2046a20e3046a20e4046a20e5046a20e6046a20e7046a20e8046a20e9046a20ea046a20eb"
"046a20ec046a20ed046a20ee046a20ef046a20f0046a20f1046a20f2046a20f3046a20f4046a20f5046a20f6046a20"
"f7046a20f8046a20f9046a20fa046a20fb046a20fc046a20fd046a20fe046a20ff046a2080056a2081056a2082056a"
"2083056a2084056a2085056a2086056a2087056a2088056a2089056a208a056a208b056a208c056a208d056a208e05"
"6a208f056a2090056a2091056a2092056a2093056a2094056a2095056a2096056a2097056a2098056a2099056a209a"
"056a209b056a209c056a209d056a209e056a209f056a20a0056a20a1056a20a2056a20a3056a20a4056a20a5056a20"
"a6056a20a7056a20a8056a20a9056a20aa056a20ab056a20ac056a20ad056a20ae056a20af056a20b0056a20b1056a"
"20b2056a20b3056a20b4056a20b5056a20b6056a20b7056a20b8056a20b9056a20ba056a20bb056a20bc056a20bd05"
"6a20be056a20bf056a20c0056a20c1056a20c2056a20c3056a20c4056a20c5056a20c6056a20c7056a20c8056a20c9"
"056a20ca056a20cb056a20cc056a20cd056a20ce056a20cf056a20d0056a20d1056a20d2056a20d3056a20d4056a20"
"d5056a20d6056a20d7056a20d8056a20d9056a20da056a20db056a20dc056a20dd056a20de056a20df056a20e0056a"
"20e1056a20e2056a20e3056a20e4056a20e5056a20e6056a20e7056a20e8056a20e9056a20ea056a20eb056a20ec05"
"6a20ed056a20ee056a20ef056a20f0056a20f1056a20f2056a20f3056a20f4056a20f5056a20f6056a20f7056a20f8"
"056a20f9056a20fa056a20fb056a20fc056a20fd056a20fe056a20ff056a2080066a2081066a2082066a2083066a20"
"84066a2085066a2086066a2087066a2088066a2089066a208a066a208b066a208c066a208d066a208e066a208f066a"
"2090066a2091066a2092066a2093066a2094066a2095066a2096066a2097066a2098066a2099066a209a066a209b06"
"6a209c066a209d066a209e066a209f066a20a0066a20a1066a20a2066a20a3066a20a4066a20a5066a20a6066a20a7"
"066a20a8066a20a9066a20aa066a20ab066a20ac066a20ad066a20ae066a20af066a20b0066a20b1066a20b2066a20"
"b3066a20b4066a20b5066a20b6066a20b7066a20b8066a20b9066a20ba066a20bb066a20bc066a20bd066a20be066a"
"20bf066a20c0066a20c1066a20c2066a20c3066a20c4066a20c5066a20c6066a20c7066a20c8066a20c9066a20ca06"
"6a20cb066a20cc066a20cd066a20ce066a20cf066a20d0066a20d1066a20d2066a20d3066a20d4066a20d5066a20d6"
"066a20d7066a20d8066a20d9066a20da066a20db066a20dc066a20dd066a20de066a20df066a20e0066a20e1066a20"
"e2066a20e3066a20e4066a20e5066a20e6066a20e7066a20e8066a20e9066a20ea066a20eb066a20ec066a20ed066a"
"20ee066a20ef066a20f0066a20f1066a20f2066a20f3066a20f4066a20f5066a20f6066a20f7066a20f8066a20f906"
"6a20fa066a20fb066a20fc066a20fd066a20fe066a20ff066a2080076a2081076a2082076a2083076a2084076a2085"
"076a2086076a2087076a2088076a2089076a208a076a208b076a208c076a208d076a208e076a208f076a2090076a20"
"91076a2092076a2093076a2094076a2095076a2096076a2097076a2098076a2099076a209a076a209b076a209c076a"
"209d076a209e076a209f076a20a0076a20a1076a20a2076a20a3076a20a4076a20a5076a20a6076a20a7076a20a807"
"6a20a9076a20aa076a20ab076a20ac076a20ad076a20ae076a20af076a20b0076a20b1076a20b2076a20b3076a20b4"
"076a20b5076a20b6076a20b7076a20b8076a20b9076a20ba076a20bb076a20bc076a20bd076a20be076a20bf076a20"
"c0076a20c1076a20c2076a20c3076a20c4076a20c5076a20c6076a20c7076a20c8076a20c9076a20ca076a20cb076a"
"20cc076a20cd076a20ce076a20cf076a20d0076a20d1076a20d2076a20d3076a20d4076a20d5076a20d6076a20d707"
"6a20d8076a20d9076a20da076a20db076a20dc076a20dd076a20de076a20df076a20e0076a20e1076a20e2076a20e3"
"076a20e4076a20e5076a20e6076a20e7076a20e8076a0b007f0970726f647563657273010c70726f6365737365642d"
"62790105636c616e675f31392e312e352d776173692d73646b202868747470733a2f2f6769746875622e636f6d2f6c"
"6c766d2f6c6c766d2d70726f6a65637420616234623561326462353832393538616631656533303861373930636664"
"623432626432343732302900490f7461726765745f6665617475726573042b0f6d757461626c652d676c6f62616c73"
"2b087369676e2d6578742b0f7265666572656e63652d74797065732b0a6d756c746976616c7565";
extern std::string const kOpcReservedHex =
"0061736d010000000105016000017f03030200000404017000010503010001060b027f0141000b7e0142000b071401"
"10616c6c5f696e737472756374696f6e7300010907010041000b01000a53020400412a0b4c02017f017e0101010101"
"0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101"
"01010101010101010101010101010101410b0b0b0a010041000b0474657374";
extern std::string const kImpExpHex =
"0061736d0100000001100360027f7f017f6000017f60017f017f02330203656e760e6765745f6c65646765725f7371"
"6e000003656e76166765745f706172656e745f6c65646765725f686173680000030403010201050301000107310406"
"6d656d6f72790200096578705f66756e63310002096578705f66756e633200030c746573745f696d706f7274730004"
"0a2b03040041010b0700200041026c0b1c01027f4120410410001a41202802002100410041201001210120000b";

View File

@@ -9,4 +9,75 @@ extern std::string const kAllHostFunctionsWasmHex;
extern std::string const kAllKeyletsWasmHex;
extern std::string const kCodecovTestsWasmHex;
extern std::string const kFibWasmHex;
extern std::string const kFloatTestsWasmHex;
extern std::string const kFloat0Hex;
extern std::string const kDisabledFloatHex;
extern std::string const kMemoryPointerAtLimitHex;
extern std::string const kMemoryPointerOverLimitHex;
extern std::string const kMemoryOffsetOverLimitHex;
extern std::string const kMemoryEndOfWordOverLimitHex;
extern std::string const kMemoryGrow0To1PageHex;
extern std::string const kMemoryGrow1To0PageHex;
extern std::string const kMemoryLastByteOf8MbHex;
extern std::string const kMemoryGrow1MoreThan8MbHex;
extern std::string const kMemoryGrow0MoreThan8MbHex;
extern std::string const kMemoryInit1MoreThan8MbHex;
extern std::string const kMemoryNegativeAddressHex;
extern std::string const kTable64ElementsHex;
extern std::string const kTable65ElementsHex;
extern std::string const kTable2TablesHex;
extern std::string const kTable0ElementsHex;
extern std::string const kTableUintMaxHex;
extern std::string const kProposalMutableGlobalHex;
extern std::string const kProposalGcStructNewHex;
extern std::string const kProposalMultiValueHex;
extern std::string const kProposalSignExtHex;
extern std::string const kProposalFloatToIntHex;
extern std::string const kProposalBulkMemoryHex;
extern std::string const kProposalRefTypesHex;
extern std::string const kProposalTailCallHex;
extern std::string const kProposalExtendedConstHex;
extern std::string const kProposalMultiMemoryHex;
extern std::string const kProposalCustomPageSizesHex;
extern std::string const kProposalMemory64Hex;
extern std::string const kProposalWideArithmeticHex;
extern std::string const kTrapDivideBy0Hex;
extern std::string const kTrapIntOverflowHex;
extern std::string const kTrapUnreachableHex;
extern std::string const kTrapNullCallHex;
extern std::string const kTrapFuncSigMismatchHex;
extern std::string const kWasiGetTimeHex;
extern std::string const kWasiPrintHex;
extern std::string const kBadMagicNumberHex;
extern std::string const kBadVersionNumberHex;
extern std::string const kLyingHeaderHex;
extern std::string const kNeverEndingNumberHex;
extern std::string const kVectorLieHex;
extern std::string const kSectionOrderingHex;
extern std::string const kGhostPayloadHex;
extern std::string const kJunkAfterSectionHex;
extern std::string const kInvalidSectionIdHex;
extern std::string const kLocalVariableBombHex;
extern std::string const kDeepRecursionHex;
extern std::string const kInfiniteLoopWasmHex;
extern std::string const kStartLoopHex;
extern std::string const kBadAlignWasmHex;
extern std::string const kThousandParamsHex;
extern std::string const kThousand1ParamsHex;
extern std::string const kLocals10kHex;
extern std::string const kFunctions5kHex;
extern std::string const kOpcReservedHex;
extern std::string const kImpExpHex;

View File

@@ -0,0 +1,171 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
dependencies = [
"tinyvec",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "float_0"
version = "0.0.1"
dependencies = [
"xrpl-wasm-stdlib",
]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xrpl-address-macro"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?rev=1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8#1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8"
dependencies = [
"bs58",
"quote",
"sha2",
"syn",
]
[[package]]
name = "xrpl-wasm-stdlib"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?rev=1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8#1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8"
dependencies = [
"xrpl-address-macro",
]

View File

@@ -0,0 +1,21 @@
[package]
name = "float_0"
version = "0.0.1"
edition = "2024"
# This empty workspace definition keeps this project independent of the parent workspace
[workspace]
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = true
opt-level = 's'
panic = "abort"
[dependencies]
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib", rev = "1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8" }
[profile.dev]
panic = "abort"

View File

@@ -0,0 +1,50 @@
#![cfg_attr(target_arch = "wasm32", no_std)]
use xrpl_std::host::trace::trace;
use xrpl_std::host::{float_compare, float_from_int, float_subtract, FLOAT_ROUNDING_MODES_TO_NEAREST};
// Float size constant (8 bytes mantissa + 4 bytes exponent)
const FLOAT_SIZE: usize = 12;
// FLOAT_ZERO constant
const FLOAT_ZERO: [u8; FLOAT_SIZE] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00];
#[unsafe(no_mangle)]
pub extern "C" fn finish() -> i32 {
let _ = trace("\n$$$ test_float_0 $$$");
// Test: 10 - 10 should equal 0
let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
// Create float from 10
if FLOAT_SIZE as i32 != unsafe { float_from_int(10, f10.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace(" float 10-10: failed");
return 1;
}
// Subtract: 10 - 10 = 0
if FLOAT_SIZE as i32 != unsafe {
float_subtract(
f10.as_ptr(),
FLOAT_SIZE,
f10.as_ptr(),
FLOAT_SIZE,
f_result.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
} {
let _ = trace(" float 10-10: failed");
return 1;
}
// Compare result with FLOAT_ZERO constant
if 0 == unsafe { float_compare(f_result.as_ptr(), FLOAT_SIZE, FLOAT_ZERO.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" FLOAT_ZERO compare: good");
} else {
let _ = trace(" FLOAT_ZERO compare: bad");
}
1
}

View File

@@ -0,0 +1,171 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
dependencies = [
"tinyvec",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "float_tests"
version = "0.0.1"
dependencies = [
"xrpl-wasm-stdlib",
]
[[package]]
name = "generic-array"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xrpl-address-macro"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=u32-buffer#1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8"
dependencies = [
"bs58",
"quote",
"sha2",
"syn",
]
[[package]]
name = "xrpl-wasm-stdlib"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=u32-buffer#1e5d096f46742ef7fcf1cb6f28a2526a72ed59d8"
dependencies = [
"xrpl-address-macro",
]

View File

@@ -0,0 +1,21 @@
[package]
name = "float_tests"
version = "0.0.1"
edition = "2024"
# This empty workspace definition keeps this project independent of the parent workspace
[workspace]
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = true
opt-level = 's'
panic = "abort"
[dependencies]
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib", branch = "u32-buffer" }
[profile.dev]
panic = "abort"

View File

@@ -0,0 +1,954 @@
#![allow(unused_imports)]
#![allow(unused_variables)]
#![cfg_attr(target_arch = "wasm32", no_std)]
#[cfg(not(target_arch = "wasm32"))]
extern crate std;
use xrpl_std::core::locator::Locator;
use xrpl_std::decode_hex_32;
use xrpl_std::host::trace::DataRepr::AsHex;
use xrpl_std::host::trace::{trace, trace_data, trace_num, DataRepr};
use xrpl_std::host::{
cache_ledger_obj, float_add, float_compare, float_divide, float_from_int, float_from_uint,
float_multiply, float_pow, float_root, float_subtract,
get_ledger_obj_array_len, get_ledger_obj_field, get_ledger_obj_nested_field,
FLOAT_ROUNDING_MODES_TO_NEAREST,
};
use xrpl_std::sfield;
use xrpl_std::sfield::{
Account, AccountTxnID, Balance, Domain, EmailHash, Flags, LedgerEntryType, MessageKey,
OwnerCount, PreviousTxnID, PreviousTxnLgrSeq, RegularKey, Sequence, TicketCount, TransferRate,
};
// External host functions not yet in xrpl_std
unsafe extern "C" {
#[link_name = "float_from_stamount"]
fn float_from_stamount(
amount_ptr: *const u8,
amount_len: i32,
out_ptr: *mut u8,
out_len: i32,
rounding: i32,
) -> i32;
#[link_name = "float_from_stnumber"]
fn float_from_stnumber(
number_ptr: *const u8,
number_len: i32,
out_ptr: *mut u8,
out_len: i32,
rounding: i32,
) -> i32;
#[link_name = "float_to_int"]
fn float_to_int(
float_ptr: *const u8,
float_len: i32,
out_ptr: *mut u8,
out_len: i32,
rounding: i32,
) -> i32;
#[link_name = "float_to_mant_exp"]
fn float_to_mant_exp(
float_ptr: *const u8,
float_len: i32,
mantissa_ptr: *mut u8,
mantissa_len: i32,
exponent_ptr: *mut u8,
exponent_len: i32,
) -> i32;
#[link_name = "float_from_mant_exp"]
fn float_from_mant_exp(
mantissa: i64,
exponent: i32,
out_ptr: *mut u8,
out_len: i32,
rounding: i32,
) -> i32;
}
// Float size constant (8 bytes mantissa + 4 bytes exponent)
const FLOAT_SIZE: usize = 12;
// Float constants (8 bytes mantissa + 4 bytes exponent, big-endian)
// FLOAT_ONE: mantissa=0x0DE0B6B3A7640000 (10^18), exponent=0xFFFFFFEE (-18)
const FLOAT_ONE: [u8; FLOAT_SIZE] = [0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE];
// FLOAT_NEGATIVE_ONE: mantissa=0xF21F494C589C0000 (-10^18), exponent=0xFFFFFFEE (-18)
const FLOAT_NEGATIVE_ONE: [u8; FLOAT_SIZE] = [0xF2, 0x1F, 0x49, 0x4C, 0x58, 0x9C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE];
// Helper function to trace floats
fn trace_float(msg: &str, f: &[u8; FLOAT_SIZE]) {
let _ = trace(msg);
let _ = trace_data(" ", f, AsHex);
}
fn test_float_from_wasm() -> bool {
let _ = trace("\n$$$ test_float_from_wasm $$$");
let mut all_pass = true;
let mut f: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
if FLOAT_SIZE as i32 == unsafe { float_from_int(12300, f.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace_float(" float from i64 12300:", &f);
let _ = trace_data(" float from i64 12300 as HEX:", &f, AsHex);
} else {
let _ = trace(" float from i64 12300: failed");
all_pass = false;
}
let u64_value: u64 = 12300;
if FLOAT_SIZE as i32 == unsafe {
float_from_uint(
&u64_value as *const u64 as *const u8,
8,
f.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
} {
let _ = trace_float(" float from u64 12300:", &f);
} else {
let _ = trace(" float from u64 12300: failed");
all_pass = false;
}
if FLOAT_SIZE as i32 == unsafe { float_from_mant_exp(123, 2, f.as_mut_ptr(), FLOAT_SIZE as i32, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace_float(" float from exp 2, mantissa 123:", &f);
} else {
let _ = trace(" float from exp 2, mantissa 123: failed");
all_pass = false;
}
let _ = trace_float(" float from const 1:", &FLOAT_ONE);
let _ = trace_float(" float from const -1:", &FLOAT_NEGATIVE_ONE);
all_pass
}
fn test_float_compare() -> bool {
let _ = trace("\n$$$ test_float_compare $$$");
let mut all_pass = true;
let mut f1: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
if FLOAT_SIZE as i32 != unsafe { float_from_int(1, f1.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace(" float from 1: failed");
all_pass = false;
} else {
let _ = trace_float(" float from 1:", &f1);
}
if 0 == unsafe { float_compare(f1.as_ptr(), FLOAT_SIZE, FLOAT_ONE.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" float from 1 == FLOAT_ONE");
} else {
let _ = trace(" float from 1 != FLOAT_ONE, failed");
all_pass = false;
}
if 1 == unsafe { float_compare(f1.as_ptr(), FLOAT_SIZE, FLOAT_NEGATIVE_ONE.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" float from 1 > FLOAT_NEGATIVE_ONE");
} else {
let _ = trace(" float from 1 !> FLOAT_NEGATIVE_ONE, failed");
all_pass = false;
}
if 2 == unsafe { float_compare(FLOAT_NEGATIVE_ONE.as_ptr(), FLOAT_SIZE, f1.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" FLOAT_NEGATIVE_ONE < float from 1");
} else {
let _ = trace(" FLOAT_NEGATIVE_ONE !< float from 1, failed");
all_pass = false;
}
all_pass
}
fn test_float_add_subtract() -> bool {
let _ = trace("\n$$$ test_float_add_subtract $$$");
let mut all_pass = true;
let mut f_compute: [u8; FLOAT_SIZE] = FLOAT_ONE;
for i in 0..9 {
unsafe {
float_add(
f_compute.as_ptr(),
FLOAT_SIZE,
FLOAT_ONE.as_ptr(),
FLOAT_SIZE,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
// let _ = trace_float(" float:", &f_compute);
}
let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
if FLOAT_SIZE as i32 != unsafe { float_from_int(10, f10.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace(" float from 10: failed");
all_pass = false;
}
if 0 == unsafe { float_compare(f10.as_ptr(), FLOAT_SIZE, f_compute.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" repeated add: good");
} else {
let _ = trace(" repeated add: failed");
all_pass = false;
}
for i in 0..11 {
unsafe {
float_subtract(
f_compute.as_ptr(),
FLOAT_SIZE,
FLOAT_ONE.as_ptr(),
FLOAT_SIZE,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
}
if 0 == unsafe { float_compare(f_compute.as_ptr(), FLOAT_SIZE, FLOAT_NEGATIVE_ONE.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" repeated subtract: good");
} else {
let _ = trace(" repeated subtract: failed");
all_pass = false;
}
all_pass
}
fn test_float_multiply_divide() -> bool {
let _ = trace("\n$$$ test_float_multiply_divide $$$");
let mut all_pass = true;
let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(10, f10.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let mut f_compute: [u8; FLOAT_SIZE] = FLOAT_ONE;
for i in 0..6 {
unsafe {
float_multiply(
f_compute.as_ptr(),
FLOAT_SIZE,
f10.as_ptr(),
FLOAT_SIZE,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
// let _ = trace_float(" float:", &f_compute);
}
let mut f1000000: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe {
float_from_int(
1000000,
f1000000.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
if 0 == unsafe { float_compare(f1000000.as_ptr(), FLOAT_SIZE, f_compute.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" repeated multiply: good");
} else {
let _ = trace(" repeated multiply: failed");
all_pass = false;
}
for i in 0..7 {
unsafe {
float_divide(
f_compute.as_ptr(),
FLOAT_SIZE,
f10.as_ptr(),
FLOAT_SIZE,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
}
let mut f01: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_mant_exp(1, -1, f01.as_mut_ptr(), FLOAT_SIZE as i32, FLOAT_ROUNDING_MODES_TO_NEAREST) };
if 0 == unsafe { float_compare(f_compute.as_ptr(), FLOAT_SIZE, f01.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" repeated divide: good");
} else {
let _ = trace(" repeated divide: failed");
all_pass = false;
}
all_pass
}
fn test_float_pow() -> bool {
let _ = trace("\n$$$ test_float_pow $$$");
let mut all_pass = true;
let mut f_compute: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe {
float_pow(
FLOAT_ONE.as_ptr(),
FLOAT_SIZE,
3,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float cube of 1:", &f_compute);
unsafe {
float_pow(
FLOAT_NEGATIVE_ONE.as_ptr(),
FLOAT_SIZE,
6,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float 6th power of -1:", &f_compute);
let mut f9: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(9, f9.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
unsafe {
float_pow(
f9.as_ptr(),
FLOAT_SIZE,
2,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float square of 9:", &f_compute);
unsafe {
float_pow(
f9.as_ptr(),
FLOAT_SIZE,
0,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float 0th power of 9:", &f_compute);
let mut f0: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(0, f0.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
unsafe {
float_pow(
f0.as_ptr(),
FLOAT_SIZE,
2,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float square of 0:", &f_compute);
let r = unsafe {
float_pow(
f0.as_ptr(),
FLOAT_SIZE,
0,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_num(
" float 0th power of 0 (expecting INVALID_PARAMS error):",
r as i64,
);
all_pass
}
fn test_float_root() -> bool {
let _ = trace("\n$$$ test_float_root $$$");
let mut all_pass = true;
let mut f9: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(9, f9.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let mut f_compute: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe {
float_root(
f9.as_ptr(),
FLOAT_SIZE,
2,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float sqrt of 9:", &f_compute);
unsafe {
float_root(
f9.as_ptr(),
FLOAT_SIZE,
3,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float cbrt of 9:", &f_compute);
let mut f1000000: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe {
float_from_int(
1000000,
f1000000.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
unsafe {
float_root(
f1000000.as_ptr(),
FLOAT_SIZE,
3,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float cbrt of 1000000:", &f_compute);
unsafe {
float_root(
f1000000.as_ptr(),
FLOAT_SIZE,
6,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float 6th root of 1000000:", &f_compute);
all_pass
}
fn test_float_invert() -> bool {
let _ = trace("\n$$$ test_float_invert $$$");
let mut all_pass = true;
let mut f_compute: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(10, f10.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
unsafe {
float_divide(
FLOAT_ONE.as_ptr(),
FLOAT_SIZE,
f10.as_ptr(),
FLOAT_SIZE,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" invert a float from 10:", &f_compute);
unsafe {
float_divide(
FLOAT_ONE.as_ptr(),
FLOAT_SIZE,
f_compute.as_ptr(),
FLOAT_SIZE,
f_compute.as_mut_ptr(),
FLOAT_SIZE,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" invert again:", &f_compute);
// if f10's value is 7, then invert twice won't match the original value
if 0 == unsafe { float_compare(f10.as_ptr(), FLOAT_SIZE, f_compute.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" invert twice: good");
} else {
let _ = trace(" invert twice: failed");
all_pass = false;
}
all_pass
}
fn test_float_to_int() -> bool {
let _ = trace("\n$$$ test_float_to_int $$$");
let mut all_pass = true;
let mut result: [u8; 8] = [0u8; 8];
// Test converting FLOAT_ONE (value 1) to int
let ret = unsafe {
float_to_int(
FLOAT_ONE.as_ptr(),
FLOAT_SIZE as i32,
result.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 {
let number = i64::from_le_bytes(result);
if number == 1 {
let _ = trace(" float_to_int(1): good");
} else {
let _ = trace(" float_to_int(1): failed");
let _ = trace_num(" got:", number);
all_pass = false;
}
} else {
let _ = trace(" float_to_int(1): failed with error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
// Test converting FLOAT_NEGATIVE_ONE (value -1) to int
let ret = unsafe {
float_to_int(
FLOAT_NEGATIVE_ONE.as_ptr(),
FLOAT_SIZE as i32,
result.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 {
let number = i64::from_le_bytes(result);
if number == -1 {
let _ = trace(" float_to_int(-1): good");
} else {
let _ = trace(" float_to_int(-1): failed");
let _ = trace_num(" got:", number);
all_pass = false;
}
} else {
let _ = trace(" float_to_int(-1): failed with error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
// Test converting a larger number (i64::MAX)
let test_val: i64 = i64::MAX;
let mut f_max: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(test_val, f_max.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let ret = unsafe {
float_to_int(
f_max.as_ptr(),
FLOAT_SIZE as i32,
result.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 {
let number = i64::from_le_bytes(result);
if number == test_val {
let _ = trace(" float_to_int(i64::MAX): good");
} else {
let _ = trace(" float_to_int(i64::MAX): failed");
let _ = trace_num(" expected:", test_val);
let _ = trace_num(" got:", number);
all_pass = false;
}
} else {
let _ = trace(" float_to_int(i64::MAX): failed with error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
// Test converting zero
let mut f0: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(0, f0.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let ret = unsafe {
float_to_int(
f0.as_ptr(),
FLOAT_SIZE as i32,
result.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 {
let number = i64::from_le_bytes(result);
if number == 0 {
let _ = trace(" float_to_int(0): good");
} else {
let _ = trace(" float_to_int(0): failed");
let _ = trace_num(" got:", number);
all_pass = false;
}
} else {
let _ = trace(" float_to_int(0): failed with error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
// Test rounding with fractional value (0.1)
let mut f01: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_mant_exp(1, -1, f01.as_mut_ptr(), FLOAT_SIZE as i32, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let ret = unsafe {
float_to_int(
f01.as_ptr(),
FLOAT_SIZE as i32,
result.as_mut_ptr(),
8 as i32,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 as i32 {
let number = i64::from_le_bytes(result);
if number == 0 {
let _ = trace(" float_to_int(0.1, to_nearest): good");
} else {
let _ = trace(" float_to_int(0.1, to_nearest): failed");
let _ = trace_num(" got:", number);
all_pass = false;
}
} else {
let _ = trace(" float_to_int(0.1, to_nearest): failed with error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
// Test rounding mode 1 (towards_zero)
let ret = unsafe {
float_to_int(
f01.as_ptr(),
FLOAT_SIZE as i32,
result.as_mut_ptr(),
8 as i32,
1
)
};
if ret == 8 as i32 {
let number = i64::from_le_bytes(result);
if number == 0 {
let _ = trace(" float_to_int(0.1, towards_zero): good");
} else {
let _ = trace(" float_to_int(0.1, towards_zero): failed");
let _ = trace_num(" got:", number);
all_pass = false;
}
} else {
let _ = trace(" float_to_int(0.1, towards_zero): failed with error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
all_pass
}
fn test_float_to_mant_exp() -> bool {
let _ = trace("\n$$$ test_float_to_mant_exp $$$");
let mut all_pass = true;
// Test with FLOAT_ONE (value 1)
let mut mantissa_bytes: [u8; 8] = [0u8; 8];
let mut exponent_bytes: [u8; 4] = [0u8; 4];
let result = unsafe {
float_to_mant_exp(
FLOAT_ONE.as_ptr(),
FLOAT_SIZE as i32,
mantissa_bytes.as_mut_ptr(),
8,
exponent_bytes.as_mut_ptr(),
4,
)
};
if result == FLOAT_SIZE as i32 {
let mantissa = i64::from_le_bytes(mantissa_bytes);
let exponent = i32::from_le_bytes(exponent_bytes);
if mantissa == 1000000000000000000 && exponent == -18 {
let _ = trace(" float_to_mant_exp(1): good");
} else {
let _ = trace(" float_to_mant_exp(1): failed");
let _ = trace_num(" expected mantissa 1000000000000000000, got:", mantissa);
let _ = trace_num(" expected exponent -18, got:", exponent as i64);
all_pass = false;
}
} else {
let _ = trace(" float_to_mant_exp(1): failed with error");
let _ = trace_num(" error code:", result as i64);
all_pass = false;
}
// Test with FLOAT_NEGATIVE_ONE (value -1)
let mut mantissa_bytes: [u8; 8] = [0u8; 8];
let mut exponent_bytes: [u8; 4] = [0u8; 4];
let result = unsafe {
float_to_mant_exp(
FLOAT_NEGATIVE_ONE.as_ptr(),
FLOAT_SIZE as i32,
mantissa_bytes.as_mut_ptr(),
8,
exponent_bytes.as_mut_ptr(),
4,
)
};
if result == FLOAT_SIZE as i32 {
let mantissa = i64::from_le_bytes(mantissa_bytes);
let exponent = i32::from_le_bytes(exponent_bytes);
if mantissa == -1000000000000000000 && exponent == -18 {
let _ = trace(" float_to_mant_exp(-1): good");
} else {
let _ = trace(" float_to_mant_exp(-1): failed");
let _ = trace_num(" expected mantissa -1000000000000000000, got:", mantissa);
let _ = trace_num(" expected exponent -18, got:", exponent as i64);
all_pass = false;
}
} else {
let _ = trace(" float_to_mant_exp(-1): failed with error");
let _ = trace_num(" error code:", result as i64);
all_pass = false;
}
// Test with a float created from int (10)
let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(10, f10.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let mut mantissa_bytes: [u8; 8] = [0u8; 8];
let mut exponent_bytes: [u8; 4] = [0u8; 4];
let result = unsafe {
float_to_mant_exp(
f10.as_ptr(),
FLOAT_SIZE as i32,
mantissa_bytes.as_mut_ptr(),
8,
exponent_bytes.as_mut_ptr(),
4,
)
};
if result == FLOAT_SIZE as i32 {
let mantissa = i64::from_le_bytes(mantissa_bytes);
let exponent = i32::from_le_bytes(exponent_bytes);
if mantissa == 1000000000000000000 && exponent == -17 {
let _ = trace(" float_to_mant_exp(10): good");
} else {
let _ = trace(" float_to_mant_exp(10): failed");
let _ = trace_num(" expected mantissa 1000000000000000000, got:", mantissa);
let _ = trace_num(" expected exponent -17, got:", exponent as i64);
all_pass = false;
}
} else {
let _ = trace(" float_to_mant_exp(10): failed with error");
let _ = trace_num(" error code:", result as i64);
all_pass = false;
}
// Test with zero
let mut f0: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
unsafe { float_from_int(0, f0.as_mut_ptr(), FLOAT_SIZE, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let mut mantissa_bytes: [u8; 8] = [0u8; 8];
let mut exponent_bytes: [u8; 4] = [0u8; 4];
let result = unsafe {
float_to_mant_exp(
f0.as_ptr(),
FLOAT_SIZE as i32,
mantissa_bytes.as_mut_ptr(),
8,
exponent_bytes.as_mut_ptr(),
4,
)
};
if result == FLOAT_SIZE as i32 {
let mantissa = i64::from_le_bytes(mantissa_bytes);
let exponent = i32::from_le_bytes(exponent_bytes);
if mantissa == 0 && exponent == -2147483648 {
let _ = trace(" float_to_mant_exp(0): good");
} else {
let _ = trace(" float_to_mant_exp(0): failed");
let _ = trace_num(" expected mantissa 0, got:", mantissa);
let _ = trace_num(" expected exponent -2147483648, got:", exponent as i64);
all_pass = false;
}
} else {
let _ = trace(" float_to_mant_exp(0): failed with error");
let _ = trace_num(" error code:", result as i64);
all_pass = false;
}
all_pass
}
fn test_float_from_stamount() -> bool {
let _ = trace("\n$$$ test_float_from_stamount $$$");
let mut all_pass = true;
// STAmount is serialized as:
// - 1 byte: type/flags
// - 8 bytes: amount (for XRP) or mantissa (for IOU)
// - For IOU: additional currency and issuer fields
// Create an XRP amount: 100 XRP = 100,000,000 drops
// XRP format: bit 62 clear (not IOU), bit 63 clear (not negative)
// Amount in drops: 100,000,000 = 0x05F5E100
let xrp_amount: [u8; 8] = [
0x40, 0x00, 0x00, 0x00, 0x05, 0xF5, 0xE1, 0x00
];
let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
let result_size = unsafe {
float_from_stamount(
xrp_amount.as_ptr(),
8,
f_result.as_mut_ptr(),
FLOAT_SIZE as i32,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
if result_size == FLOAT_SIZE as i32 {
let _ = trace_float(" float from XRP amount (100 XRP):", &f_result);
// Convert back to int to verify
let mut int_bytes: [u8; 8] = [0u8; 8];
let ret = unsafe {
float_to_int(
f_result.as_ptr(),
FLOAT_SIZE as i32,
int_bytes.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 {
let int_val = i64::from_le_bytes(int_bytes);
if int_val == 100000000 {
let _ = trace(" XRP amount conversion: good");
} else {
let _ = trace(" XRP amount conversion: failed");
let _ = trace_num(" expected 100000000, got:", int_val);
all_pass = false;
}
} else {
let _ = trace(" XRP amount conversion: failed - float_to_int error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
} else {
let _ = trace(" float from XRP amount: failed");
let _ = trace_num(" result_size:", result_size as i64);
all_pass = false;
}
all_pass
}
fn test_float_from_stnumber() -> bool {
let _ = trace("\n$$$ test_float_from_stnumber $$$");
let mut all_pass = true;
// STNumber is serialized as:
// - 8 bytes: mantissa (big-endian signed int64)
// - 4 bytes: exponent (big-endian signed int32)
// Create STNumber for value 123 (mantissa=123*10^18, exponent=-18)
// mantissa = 123000000000000000000 = 0x6ADF37F675EF6B28000
// But we need to fit in int64, so use mantissa=123*10^15, exponent=-15
// 123*10^15 = 123000000000000000 = 0x01B69B4BA630F34000
let stnumber_123: [u8; 12] = [
0x01, 0xB6, 0x9B, 0x4B, 0xA6, 0x30, 0xF3, 0x40, // mantissa
0xFF, 0xFF, 0xFF, 0xF1, // exponent = -15
];
let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE];
let result_size = unsafe {
float_from_stnumber(
stnumber_123.as_ptr(),
12,
f_result.as_mut_ptr(),
FLOAT_SIZE as i32,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
if result_size == FLOAT_SIZE as i32 {
let _ = trace_float(" float from STNumber (123):", &f_result);
// Convert back to int to verify
let mut int_bytes: [u8; 8] = [0u8; 8];
let ret = unsafe {
float_to_int(
f_result.as_ptr(),
FLOAT_SIZE as i32,
int_bytes.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST
)
};
if ret == 8 {
let int_val = i64::from_le_bytes(int_bytes);
if int_val == 123 {
let _ = trace(" STNumber conversion: good");
} else {
let _ = trace(" STNumber conversion: failed");
let _ = trace_num(" expected 123, got:", int_val);
all_pass = false;
}
} else {
let _ = trace(" STNumber conversion: failed - float_to_int error");
let _ = trace_num(" error code:", ret as i64);
all_pass = false;
}
} else {
let _ = trace(" float from STNumber: failed");
let _ = trace_num(" result_size:", result_size as i64);
all_pass = false;
}
// Test with FLOAT_ONE constant (which is already in STNumber format)
let result_size = unsafe {
float_from_stnumber(
FLOAT_ONE.as_ptr(),
FLOAT_SIZE as i32,
f_result.as_mut_ptr(),
FLOAT_SIZE as i32,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
if result_size == FLOAT_SIZE as i32 {
let _ = trace_float(" float from STNumber (1):", &f_result);
// Should match FLOAT_ONE
if 0 == unsafe { float_compare(f_result.as_ptr(), FLOAT_SIZE, FLOAT_ONE.as_ptr(), FLOAT_SIZE) } {
let _ = trace(" STNumber(1) == FLOAT_ONE: good");
} else {
let _ = trace(" STNumber(1) == FLOAT_ONE: failed");
all_pass = false;
}
} else {
let _ = trace(" float from STNumber(1): failed");
all_pass = false;
}
all_pass
}
#[unsafe(no_mangle)]
pub extern "C" fn finish() -> i32 {
let mut all_pass = true;
all_pass &= test_float_from_wasm();
all_pass &= test_float_compare();
all_pass &= test_float_add_subtract();
all_pass &= test_float_multiply_divide();
all_pass &= test_float_pow();
all_pass &= test_float_root();
all_pass &= test_float_invert();
all_pass &= test_float_to_int();
all_pass &= test_float_to_mant_exp();
all_pass &= test_float_from_stamount();
all_pass &= test_float_from_stnumber();
if all_pass { 1 } else { 0 }
}

View File

@@ -0,0 +1,7 @@
int loop()
{
int volatile x = 0;
while (1)
x++;
return x;
}

View File

@@ -0,0 +1,264 @@
// clang-format off
#include <stdint.h>
int32_t test(
int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5, int32_t p6, int32_t p7
, int32_t p8, int32_t p9, int32_t p10, int32_t p11, int32_t p12, int32_t p13, int32_t p14, int32_t p15
, int32_t p16, int32_t p17, int32_t p18, int32_t p19, int32_t p20, int32_t p21, int32_t p22, int32_t p23
, int32_t p24, int32_t p25, int32_t p26, int32_t p27, int32_t p28, int32_t p29, int32_t p30, int32_t p31
, int32_t p32, int32_t p33, int32_t p34, int32_t p35, int32_t p36, int32_t p37, int32_t p38, int32_t p39
, int32_t p40, int32_t p41, int32_t p42, int32_t p43, int32_t p44, int32_t p45, int32_t p46, int32_t p47
, int32_t p48, int32_t p49, int32_t p50, int32_t p51, int32_t p52, int32_t p53, int32_t p54, int32_t p55
, int32_t p56, int32_t p57, int32_t p58, int32_t p59, int32_t p60, int32_t p61, int32_t p62, int32_t p63
, int32_t p64, int32_t p65, int32_t p66, int32_t p67, int32_t p68, int32_t p69, int32_t p70, int32_t p71
, int32_t p72, int32_t p73, int32_t p74, int32_t p75, int32_t p76, int32_t p77, int32_t p78, int32_t p79
, int32_t p80, int32_t p81, int32_t p82, int32_t p83, int32_t p84, int32_t p85, int32_t p86, int32_t p87
, int32_t p88, int32_t p89, int32_t p90, int32_t p91, int32_t p92, int32_t p93, int32_t p94, int32_t p95
, int32_t p96, int32_t p97, int32_t p98, int32_t p99, int32_t p100, int32_t p101, int32_t p102, int32_t p103
, int32_t p104, int32_t p105, int32_t p106, int32_t p107, int32_t p108, int32_t p109, int32_t p110, int32_t p111
, int32_t p112, int32_t p113, int32_t p114, int32_t p115, int32_t p116, int32_t p117, int32_t p118, int32_t p119
, int32_t p120, int32_t p121, int32_t p122, int32_t p123, int32_t p124, int32_t p125, int32_t p126, int32_t p127
, int32_t p128, int32_t p129, int32_t p130, int32_t p131, int32_t p132, int32_t p133, int32_t p134, int32_t p135
, int32_t p136, int32_t p137, int32_t p138, int32_t p139, int32_t p140, int32_t p141, int32_t p142, int32_t p143
, int32_t p144, int32_t p145, int32_t p146, int32_t p147, int32_t p148, int32_t p149, int32_t p150, int32_t p151
, int32_t p152, int32_t p153, int32_t p154, int32_t p155, int32_t p156, int32_t p157, int32_t p158, int32_t p159
, int32_t p160, int32_t p161, int32_t p162, int32_t p163, int32_t p164, int32_t p165, int32_t p166, int32_t p167
, int32_t p168, int32_t p169, int32_t p170, int32_t p171, int32_t p172, int32_t p173, int32_t p174, int32_t p175
, int32_t p176, int32_t p177, int32_t p178, int32_t p179, int32_t p180, int32_t p181, int32_t p182, int32_t p183
, int32_t p184, int32_t p185, int32_t p186, int32_t p187, int32_t p188, int32_t p189, int32_t p190, int32_t p191
, int32_t p192, int32_t p193, int32_t p194, int32_t p195, int32_t p196, int32_t p197, int32_t p198, int32_t p199
, int32_t p200, int32_t p201, int32_t p202, int32_t p203, int32_t p204, int32_t p205, int32_t p206, int32_t p207
, int32_t p208, int32_t p209, int32_t p210, int32_t p211, int32_t p212, int32_t p213, int32_t p214, int32_t p215
, int32_t p216, int32_t p217, int32_t p218, int32_t p219, int32_t p220, int32_t p221, int32_t p222, int32_t p223
, int32_t p224, int32_t p225, int32_t p226, int32_t p227, int32_t p228, int32_t p229, int32_t p230, int32_t p231
, int32_t p232, int32_t p233, int32_t p234, int32_t p235, int32_t p236, int32_t p237, int32_t p238, int32_t p239
, int32_t p240, int32_t p241, int32_t p242, int32_t p243, int32_t p244, int32_t p245, int32_t p246, int32_t p247
, int32_t p248, int32_t p249, int32_t p250, int32_t p251, int32_t p252, int32_t p253, int32_t p254, int32_t p255
, int32_t p256, int32_t p257, int32_t p258, int32_t p259, int32_t p260, int32_t p261, int32_t p262, int32_t p263
, int32_t p264, int32_t p265, int32_t p266, int32_t p267, int32_t p268, int32_t p269, int32_t p270, int32_t p271
, int32_t p272, int32_t p273, int32_t p274, int32_t p275, int32_t p276, int32_t p277, int32_t p278, int32_t p279
, int32_t p280, int32_t p281, int32_t p282, int32_t p283, int32_t p284, int32_t p285, int32_t p286, int32_t p287
, int32_t p288, int32_t p289, int32_t p290, int32_t p291, int32_t p292, int32_t p293, int32_t p294, int32_t p295
, int32_t p296, int32_t p297, int32_t p298, int32_t p299, int32_t p300, int32_t p301, int32_t p302, int32_t p303
, int32_t p304, int32_t p305, int32_t p306, int32_t p307, int32_t p308, int32_t p309, int32_t p310, int32_t p311
, int32_t p312, int32_t p313, int32_t p314, int32_t p315, int32_t p316, int32_t p317, int32_t p318, int32_t p319
, int32_t p320, int32_t p321, int32_t p322, int32_t p323, int32_t p324, int32_t p325, int32_t p326, int32_t p327
, int32_t p328, int32_t p329, int32_t p330, int32_t p331, int32_t p332, int32_t p333, int32_t p334, int32_t p335
, int32_t p336, int32_t p337, int32_t p338, int32_t p339, int32_t p340, int32_t p341, int32_t p342, int32_t p343
, int32_t p344, int32_t p345, int32_t p346, int32_t p347, int32_t p348, int32_t p349, int32_t p350, int32_t p351
, int32_t p352, int32_t p353, int32_t p354, int32_t p355, int32_t p356, int32_t p357, int32_t p358, int32_t p359
, int32_t p360, int32_t p361, int32_t p362, int32_t p363, int32_t p364, int32_t p365, int32_t p366, int32_t p367
, int32_t p368, int32_t p369, int32_t p370, int32_t p371, int32_t p372, int32_t p373, int32_t p374, int32_t p375
, int32_t p376, int32_t p377, int32_t p378, int32_t p379, int32_t p380, int32_t p381, int32_t p382, int32_t p383
, int32_t p384, int32_t p385, int32_t p386, int32_t p387, int32_t p388, int32_t p389, int32_t p390, int32_t p391
, int32_t p392, int32_t p393, int32_t p394, int32_t p395, int32_t p396, int32_t p397, int32_t p398, int32_t p399
, int32_t p400, int32_t p401, int32_t p402, int32_t p403, int32_t p404, int32_t p405, int32_t p406, int32_t p407
, int32_t p408, int32_t p409, int32_t p410, int32_t p411, int32_t p412, int32_t p413, int32_t p414, int32_t p415
, int32_t p416, int32_t p417, int32_t p418, int32_t p419, int32_t p420, int32_t p421, int32_t p422, int32_t p423
, int32_t p424, int32_t p425, int32_t p426, int32_t p427, int32_t p428, int32_t p429, int32_t p430, int32_t p431
, int32_t p432, int32_t p433, int32_t p434, int32_t p435, int32_t p436, int32_t p437, int32_t p438, int32_t p439
, int32_t p440, int32_t p441, int32_t p442, int32_t p443, int32_t p444, int32_t p445, int32_t p446, int32_t p447
, int32_t p448, int32_t p449, int32_t p450, int32_t p451, int32_t p452, int32_t p453, int32_t p454, int32_t p455
, int32_t p456, int32_t p457, int32_t p458, int32_t p459, int32_t p460, int32_t p461, int32_t p462, int32_t p463
, int32_t p464, int32_t p465, int32_t p466, int32_t p467, int32_t p468, int32_t p469, int32_t p470, int32_t p471
, int32_t p472, int32_t p473, int32_t p474, int32_t p475, int32_t p476, int32_t p477, int32_t p478, int32_t p479
, int32_t p480, int32_t p481, int32_t p482, int32_t p483, int32_t p484, int32_t p485, int32_t p486, int32_t p487
, int32_t p488, int32_t p489, int32_t p490, int32_t p491, int32_t p492, int32_t p493, int32_t p494, int32_t p495
, int32_t p496, int32_t p497, int32_t p498, int32_t p499, int32_t p500, int32_t p501, int32_t p502, int32_t p503
, int32_t p504, int32_t p505, int32_t p506, int32_t p507, int32_t p508, int32_t p509, int32_t p510, int32_t p511
, int32_t p512, int32_t p513, int32_t p514, int32_t p515, int32_t p516, int32_t p517, int32_t p518, int32_t p519
, int32_t p520, int32_t p521, int32_t p522, int32_t p523, int32_t p524, int32_t p525, int32_t p526, int32_t p527
, int32_t p528, int32_t p529, int32_t p530, int32_t p531, int32_t p532, int32_t p533, int32_t p534, int32_t p535
, int32_t p536, int32_t p537, int32_t p538, int32_t p539, int32_t p540, int32_t p541, int32_t p542, int32_t p543
, int32_t p544, int32_t p545, int32_t p546, int32_t p547, int32_t p548, int32_t p549, int32_t p550, int32_t p551
, int32_t p552, int32_t p553, int32_t p554, int32_t p555, int32_t p556, int32_t p557, int32_t p558, int32_t p559
, int32_t p560, int32_t p561, int32_t p562, int32_t p563, int32_t p564, int32_t p565, int32_t p566, int32_t p567
, int32_t p568, int32_t p569, int32_t p570, int32_t p571, int32_t p572, int32_t p573, int32_t p574, int32_t p575
, int32_t p576, int32_t p577, int32_t p578, int32_t p579, int32_t p580, int32_t p581, int32_t p582, int32_t p583
, int32_t p584, int32_t p585, int32_t p586, int32_t p587, int32_t p588, int32_t p589, int32_t p590, int32_t p591
, int32_t p592, int32_t p593, int32_t p594, int32_t p595, int32_t p596, int32_t p597, int32_t p598, int32_t p599
, int32_t p600, int32_t p601, int32_t p602, int32_t p603, int32_t p604, int32_t p605, int32_t p606, int32_t p607
, int32_t p608, int32_t p609, int32_t p610, int32_t p611, int32_t p612, int32_t p613, int32_t p614, int32_t p615
, int32_t p616, int32_t p617, int32_t p618, int32_t p619, int32_t p620, int32_t p621, int32_t p622, int32_t p623
, int32_t p624, int32_t p625, int32_t p626, int32_t p627, int32_t p628, int32_t p629, int32_t p630, int32_t p631
, int32_t p632, int32_t p633, int32_t p634, int32_t p635, int32_t p636, int32_t p637, int32_t p638, int32_t p639
, int32_t p640, int32_t p641, int32_t p642, int32_t p643, int32_t p644, int32_t p645, int32_t p646, int32_t p647
, int32_t p648, int32_t p649, int32_t p650, int32_t p651, int32_t p652, int32_t p653, int32_t p654, int32_t p655
, int32_t p656, int32_t p657, int32_t p658, int32_t p659, int32_t p660, int32_t p661, int32_t p662, int32_t p663
, int32_t p664, int32_t p665, int32_t p666, int32_t p667, int32_t p668, int32_t p669, int32_t p670, int32_t p671
, int32_t p672, int32_t p673, int32_t p674, int32_t p675, int32_t p676, int32_t p677, int32_t p678, int32_t p679
, int32_t p680, int32_t p681, int32_t p682, int32_t p683, int32_t p684, int32_t p685, int32_t p686, int32_t p687
, int32_t p688, int32_t p689, int32_t p690, int32_t p691, int32_t p692, int32_t p693, int32_t p694, int32_t p695
, int32_t p696, int32_t p697, int32_t p698, int32_t p699, int32_t p700, int32_t p701, int32_t p702, int32_t p703
, int32_t p704, int32_t p705, int32_t p706, int32_t p707, int32_t p708, int32_t p709, int32_t p710, int32_t p711
, int32_t p712, int32_t p713, int32_t p714, int32_t p715, int32_t p716, int32_t p717, int32_t p718, int32_t p719
, int32_t p720, int32_t p721, int32_t p722, int32_t p723, int32_t p724, int32_t p725, int32_t p726, int32_t p727
, int32_t p728, int32_t p729, int32_t p730, int32_t p731, int32_t p732, int32_t p733, int32_t p734, int32_t p735
, int32_t p736, int32_t p737, int32_t p738, int32_t p739, int32_t p740, int32_t p741, int32_t p742, int32_t p743
, int32_t p744, int32_t p745, int32_t p746, int32_t p747, int32_t p748, int32_t p749, int32_t p750, int32_t p751
, int32_t p752, int32_t p753, int32_t p754, int32_t p755, int32_t p756, int32_t p757, int32_t p758, int32_t p759
, int32_t p760, int32_t p761, int32_t p762, int32_t p763, int32_t p764, int32_t p765, int32_t p766, int32_t p767
, int32_t p768, int32_t p769, int32_t p770, int32_t p771, int32_t p772, int32_t p773, int32_t p774, int32_t p775
, int32_t p776, int32_t p777, int32_t p778, int32_t p779, int32_t p780, int32_t p781, int32_t p782, int32_t p783
, int32_t p784, int32_t p785, int32_t p786, int32_t p787, int32_t p788, int32_t p789, int32_t p790, int32_t p791
, int32_t p792, int32_t p793, int32_t p794, int32_t p795, int32_t p796, int32_t p797, int32_t p798, int32_t p799
, int32_t p800, int32_t p801, int32_t p802, int32_t p803, int32_t p804, int32_t p805, int32_t p806, int32_t p807
, int32_t p808, int32_t p809, int32_t p810, int32_t p811, int32_t p812, int32_t p813, int32_t p814, int32_t p815
, int32_t p816, int32_t p817, int32_t p818, int32_t p819, int32_t p820, int32_t p821, int32_t p822, int32_t p823
, int32_t p824, int32_t p825, int32_t p826, int32_t p827, int32_t p828, int32_t p829, int32_t p830, int32_t p831
, int32_t p832, int32_t p833, int32_t p834, int32_t p835, int32_t p836, int32_t p837, int32_t p838, int32_t p839
, int32_t p840, int32_t p841, int32_t p842, int32_t p843, int32_t p844, int32_t p845, int32_t p846, int32_t p847
, int32_t p848, int32_t p849, int32_t p850, int32_t p851, int32_t p852, int32_t p853, int32_t p854, int32_t p855
, int32_t p856, int32_t p857, int32_t p858, int32_t p859, int32_t p860, int32_t p861, int32_t p862, int32_t p863
, int32_t p864, int32_t p865, int32_t p866, int32_t p867, int32_t p868, int32_t p869, int32_t p870, int32_t p871
, int32_t p872, int32_t p873, int32_t p874, int32_t p875, int32_t p876, int32_t p877, int32_t p878, int32_t p879
, int32_t p880, int32_t p881, int32_t p882, int32_t p883, int32_t p884, int32_t p885, int32_t p886, int32_t p887
, int32_t p888, int32_t p889, int32_t p890, int32_t p891, int32_t p892, int32_t p893, int32_t p894, int32_t p895
, int32_t p896, int32_t p897, int32_t p898, int32_t p899, int32_t p900, int32_t p901, int32_t p902, int32_t p903
, int32_t p904, int32_t p905, int32_t p906, int32_t p907, int32_t p908, int32_t p909, int32_t p910, int32_t p911
, int32_t p912, int32_t p913, int32_t p914, int32_t p915, int32_t p916, int32_t p917, int32_t p918, int32_t p919
, int32_t p920, int32_t p921, int32_t p922, int32_t p923, int32_t p924, int32_t p925, int32_t p926, int32_t p927
, int32_t p928, int32_t p929, int32_t p930, int32_t p931, int32_t p932, int32_t p933, int32_t p934, int32_t p935
, int32_t p936, int32_t p937, int32_t p938, int32_t p939, int32_t p940, int32_t p941, int32_t p942, int32_t p943
, int32_t p944, int32_t p945, int32_t p946, int32_t p947, int32_t p948, int32_t p949, int32_t p950, int32_t p951
, int32_t p952, int32_t p953, int32_t p954, int32_t p955, int32_t p956, int32_t p957, int32_t p958, int32_t p959
, int32_t p960, int32_t p961, int32_t p962, int32_t p963, int32_t p964, int32_t p965, int32_t p966, int32_t p967
, int32_t p968, int32_t p969, int32_t p970, int32_t p971, int32_t p972, int32_t p973, int32_t p974, int32_t p975
, int32_t p976, int32_t p977, int32_t p978, int32_t p979, int32_t p980, int32_t p981, int32_t p982, int32_t p983
, int32_t p984, int32_t p985, int32_t p986, int32_t p987, int32_t p988, int32_t p989, int32_t p990, int32_t p991
, int32_t p992, int32_t p993, int32_t p994, int32_t p995, int32_t p996, int32_t p997, int32_t p998, int32_t p999
, int32_t p1000
)
{
int32_t x;
x = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7
+ p8 + p9 + p10 + p11 + p12 + p13 + p14 + p15
+ p16 + p17 + p18 + p19 + p20 + p21 + p22 + p23
+ p24 + p25 + p26 + p27 + p28 + p29 + p30 + p31
+ p32 + p33 + p34 + p35 + p36 + p37 + p38 + p39
+ p40 + p41 + p42 + p43 + p44 + p45 + p46 + p47
+ p48 + p49 + p50 + p51 + p52 + p53 + p54 + p55
+ p56 + p57 + p58 + p59 + p60 + p61 + p62 + p63
+ p64 + p65 + p66 + p67 + p68 + p69 + p70 + p71
+ p72 + p73 + p74 + p75 + p76 + p77 + p78 + p79
+ p80 + p81 + p82 + p83 + p84 + p85 + p86 + p87
+ p88 + p89 + p90 + p91 + p92 + p93 + p94 + p95
+ p96 + p97 + p98 + p99 + p100 + p101 + p102 + p103
+ p104 + p105 + p106 + p107 + p108 + p109 + p110 + p111
+ p112 + p113 + p114 + p115 + p116 + p117 + p118 + p119
+ p120 + p121 + p122 + p123 + p124 + p125 + p126 + p127
+ p128 + p129 + p130 + p131 + p132 + p133 + p134 + p135
+ p136 + p137 + p138 + p139 + p140 + p141 + p142 + p143
+ p144 + p145 + p146 + p147 + p148 + p149 + p150 + p151
+ p152 + p153 + p154 + p155 + p156 + p157 + p158 + p159
+ p160 + p161 + p162 + p163 + p164 + p165 + p166 + p167
+ p168 + p169 + p170 + p171 + p172 + p173 + p174 + p175
+ p176 + p177 + p178 + p179 + p180 + p181 + p182 + p183
+ p184 + p185 + p186 + p187 + p188 + p189 + p190 + p191
+ p192 + p193 + p194 + p195 + p196 + p197 + p198 + p199
+ p200 + p201 + p202 + p203 + p204 + p205 + p206 + p207
+ p208 + p209 + p210 + p211 + p212 + p213 + p214 + p215
+ p216 + p217 + p218 + p219 + p220 + p221 + p222 + p223
+ p224 + p225 + p226 + p227 + p228 + p229 + p230 + p231
+ p232 + p233 + p234 + p235 + p236 + p237 + p238 + p239
+ p240 + p241 + p242 + p243 + p244 + p245 + p246 + p247
+ p248 + p249 + p250 + p251 + p252 + p253 + p254 + p255
+ p256 + p257 + p258 + p259 + p260 + p261 + p262 + p263
+ p264 + p265 + p266 + p267 + p268 + p269 + p270 + p271
+ p272 + p273 + p274 + p275 + p276 + p277 + p278 + p279
+ p280 + p281 + p282 + p283 + p284 + p285 + p286 + p287
+ p288 + p289 + p290 + p291 + p292 + p293 + p294 + p295
+ p296 + p297 + p298 + p299 + p300 + p301 + p302 + p303
+ p304 + p305 + p306 + p307 + p308 + p309 + p310 + p311
+ p312 + p313 + p314 + p315 + p316 + p317 + p318 + p319
+ p320 + p321 + p322 + p323 + p324 + p325 + p326 + p327
+ p328 + p329 + p330 + p331 + p332 + p333 + p334 + p335
+ p336 + p337 + p338 + p339 + p340 + p341 + p342 + p343
+ p344 + p345 + p346 + p347 + p348 + p349 + p350 + p351
+ p352 + p353 + p354 + p355 + p356 + p357 + p358 + p359
+ p360 + p361 + p362 + p363 + p364 + p365 + p366 + p367
+ p368 + p369 + p370 + p371 + p372 + p373 + p374 + p375
+ p376 + p377 + p378 + p379 + p380 + p381 + p382 + p383
+ p384 + p385 + p386 + p387 + p388 + p389 + p390 + p391
+ p392 + p393 + p394 + p395 + p396 + p397 + p398 + p399
+ p400 + p401 + p402 + p403 + p404 + p405 + p406 + p407
+ p408 + p409 + p410 + p411 + p412 + p413 + p414 + p415
+ p416 + p417 + p418 + p419 + p420 + p421 + p422 + p423
+ p424 + p425 + p426 + p427 + p428 + p429 + p430 + p431
+ p432 + p433 + p434 + p435 + p436 + p437 + p438 + p439
+ p440 + p441 + p442 + p443 + p444 + p445 + p446 + p447
+ p448 + p449 + p450 + p451 + p452 + p453 + p454 + p455
+ p456 + p457 + p458 + p459 + p460 + p461 + p462 + p463
+ p464 + p465 + p466 + p467 + p468 + p469 + p470 + p471
+ p472 + p473 + p474 + p475 + p476 + p477 + p478 + p479
+ p480 + p481 + p482 + p483 + p484 + p485 + p486 + p487
+ p488 + p489 + p490 + p491 + p492 + p493 + p494 + p495
+ p496 + p497 + p498 + p499 + p500 + p501 + p502 + p503
+ p504 + p505 + p506 + p507 + p508 + p509 + p510 + p511
+ p512 + p513 + p514 + p515 + p516 + p517 + p518 + p519
+ p520 + p521 + p522 + p523 + p524 + p525 + p526 + p527
+ p528 + p529 + p530 + p531 + p532 + p533 + p534 + p535
+ p536 + p537 + p538 + p539 + p540 + p541 + p542 + p543
+ p544 + p545 + p546 + p547 + p548 + p549 + p550 + p551
+ p552 + p553 + p554 + p555 + p556 + p557 + p558 + p559
+ p560 + p561 + p562 + p563 + p564 + p565 + p566 + p567
+ p568 + p569 + p570 + p571 + p572 + p573 + p574 + p575
+ p576 + p577 + p578 + p579 + p580 + p581 + p582 + p583
+ p584 + p585 + p586 + p587 + p588 + p589 + p590 + p591
+ p592 + p593 + p594 + p595 + p596 + p597 + p598 + p599
+ p600 + p601 + p602 + p603 + p604 + p605 + p606 + p607
+ p608 + p609 + p610 + p611 + p612 + p613 + p614 + p615
+ p616 + p617 + p618 + p619 + p620 + p621 + p622 + p623
+ p624 + p625 + p626 + p627 + p628 + p629 + p630 + p631
+ p632 + p633 + p634 + p635 + p636 + p637 + p638 + p639
+ p640 + p641 + p642 + p643 + p644 + p645 + p646 + p647
+ p648 + p649 + p650 + p651 + p652 + p653 + p654 + p655
+ p656 + p657 + p658 + p659 + p660 + p661 + p662 + p663
+ p664 + p665 + p666 + p667 + p668 + p669 + p670 + p671
+ p672 + p673 + p674 + p675 + p676 + p677 + p678 + p679
+ p680 + p681 + p682 + p683 + p684 + p685 + p686 + p687
+ p688 + p689 + p690 + p691 + p692 + p693 + p694 + p695
+ p696 + p697 + p698 + p699 + p700 + p701 + p702 + p703
+ p704 + p705 + p706 + p707 + p708 + p709 + p710 + p711
+ p712 + p713 + p714 + p715 + p716 + p717 + p718 + p719
+ p720 + p721 + p722 + p723 + p724 + p725 + p726 + p727
+ p728 + p729 + p730 + p731 + p732 + p733 + p734 + p735
+ p736 + p737 + p738 + p739 + p740 + p741 + p742 + p743
+ p744 + p745 + p746 + p747 + p748 + p749 + p750 + p751
+ p752 + p753 + p754 + p755 + p756 + p757 + p758 + p759
+ p760 + p761 + p762 + p763 + p764 + p765 + p766 + p767
+ p768 + p769 + p770 + p771 + p772 + p773 + p774 + p775
+ p776 + p777 + p778 + p779 + p780 + p781 + p782 + p783
+ p784 + p785 + p786 + p787 + p788 + p789 + p790 + p791
+ p792 + p793 + p794 + p795 + p796 + p797 + p798 + p799
+ p800 + p801 + p802 + p803 + p804 + p805 + p806 + p807
+ p808 + p809 + p810 + p811 + p812 + p813 + p814 + p815
+ p816 + p817 + p818 + p819 + p820 + p821 + p822 + p823
+ p824 + p825 + p826 + p827 + p828 + p829 + p830 + p831
+ p832 + p833 + p834 + p835 + p836 + p837 + p838 + p839
+ p840 + p841 + p842 + p843 + p844 + p845 + p846 + p847
+ p848 + p849 + p850 + p851 + p852 + p853 + p854 + p855
+ p856 + p857 + p858 + p859 + p860 + p861 + p862 + p863
+ p864 + p865 + p866 + p867 + p868 + p869 + p870 + p871
+ p872 + p873 + p874 + p875 + p876 + p877 + p878 + p879
+ p880 + p881 + p882 + p883 + p884 + p885 + p886 + p887
+ p888 + p889 + p890 + p891 + p892 + p893 + p894 + p895
+ p896 + p897 + p898 + p899 + p900 + p901 + p902 + p903
+ p904 + p905 + p906 + p907 + p908 + p909 + p910 + p911
+ p912 + p913 + p914 + p915 + p916 + p917 + p918 + p919
+ p920 + p921 + p922 + p923 + p924 + p925 + p926 + p927
+ p928 + p929 + p930 + p931 + p932 + p933 + p934 + p935
+ p936 + p937 + p938 + p939 + p940 + p941 + p942 + p943
+ p944 + p945 + p946 + p947 + p948 + p949 + p950 + p951
+ p952 + p953 + p954 + p955 + p956 + p957 + p958 + p959
+ p960 + p961 + p962 + p963 + p964 + p965 + p966 + p967
+ p968 + p969 + p970 + p971 + p972 + p973 + p974 + p975
+ p976 + p977 + p978 + p979 + p980 + p981 + p982 + p983
+ p984 + p985 + p986 + p987 + p988 + p989 + p990 + p991
+ p992 + p993 + p994 + p995 + p996 + p997 + p998 + p999
+ p1000;
return x;
}
// clang-format on

View File

@@ -0,0 +1,262 @@
// clang-format off
#include <stdint.h>
int32_t test(
int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5, int32_t p6, int32_t p7
, int32_t p8, int32_t p9, int32_t p10, int32_t p11, int32_t p12, int32_t p13, int32_t p14, int32_t p15
, int32_t p16, int32_t p17, int32_t p18, int32_t p19, int32_t p20, int32_t p21, int32_t p22, int32_t p23
, int32_t p24, int32_t p25, int32_t p26, int32_t p27, int32_t p28, int32_t p29, int32_t p30, int32_t p31
, int32_t p32, int32_t p33, int32_t p34, int32_t p35, int32_t p36, int32_t p37, int32_t p38, int32_t p39
, int32_t p40, int32_t p41, int32_t p42, int32_t p43, int32_t p44, int32_t p45, int32_t p46, int32_t p47
, int32_t p48, int32_t p49, int32_t p50, int32_t p51, int32_t p52, int32_t p53, int32_t p54, int32_t p55
, int32_t p56, int32_t p57, int32_t p58, int32_t p59, int32_t p60, int32_t p61, int32_t p62, int32_t p63
, int32_t p64, int32_t p65, int32_t p66, int32_t p67, int32_t p68, int32_t p69, int32_t p70, int32_t p71
, int32_t p72, int32_t p73, int32_t p74, int32_t p75, int32_t p76, int32_t p77, int32_t p78, int32_t p79
, int32_t p80, int32_t p81, int32_t p82, int32_t p83, int32_t p84, int32_t p85, int32_t p86, int32_t p87
, int32_t p88, int32_t p89, int32_t p90, int32_t p91, int32_t p92, int32_t p93, int32_t p94, int32_t p95
, int32_t p96, int32_t p97, int32_t p98, int32_t p99, int32_t p100, int32_t p101, int32_t p102, int32_t p103
, int32_t p104, int32_t p105, int32_t p106, int32_t p107, int32_t p108, int32_t p109, int32_t p110, int32_t p111
, int32_t p112, int32_t p113, int32_t p114, int32_t p115, int32_t p116, int32_t p117, int32_t p118, int32_t p119
, int32_t p120, int32_t p121, int32_t p122, int32_t p123, int32_t p124, int32_t p125, int32_t p126, int32_t p127
, int32_t p128, int32_t p129, int32_t p130, int32_t p131, int32_t p132, int32_t p133, int32_t p134, int32_t p135
, int32_t p136, int32_t p137, int32_t p138, int32_t p139, int32_t p140, int32_t p141, int32_t p142, int32_t p143
, int32_t p144, int32_t p145, int32_t p146, int32_t p147, int32_t p148, int32_t p149, int32_t p150, int32_t p151
, int32_t p152, int32_t p153, int32_t p154, int32_t p155, int32_t p156, int32_t p157, int32_t p158, int32_t p159
, int32_t p160, int32_t p161, int32_t p162, int32_t p163, int32_t p164, int32_t p165, int32_t p166, int32_t p167
, int32_t p168, int32_t p169, int32_t p170, int32_t p171, int32_t p172, int32_t p173, int32_t p174, int32_t p175
, int32_t p176, int32_t p177, int32_t p178, int32_t p179, int32_t p180, int32_t p181, int32_t p182, int32_t p183
, int32_t p184, int32_t p185, int32_t p186, int32_t p187, int32_t p188, int32_t p189, int32_t p190, int32_t p191
, int32_t p192, int32_t p193, int32_t p194, int32_t p195, int32_t p196, int32_t p197, int32_t p198, int32_t p199
, int32_t p200, int32_t p201, int32_t p202, int32_t p203, int32_t p204, int32_t p205, int32_t p206, int32_t p207
, int32_t p208, int32_t p209, int32_t p210, int32_t p211, int32_t p212, int32_t p213, int32_t p214, int32_t p215
, int32_t p216, int32_t p217, int32_t p218, int32_t p219, int32_t p220, int32_t p221, int32_t p222, int32_t p223
, int32_t p224, int32_t p225, int32_t p226, int32_t p227, int32_t p228, int32_t p229, int32_t p230, int32_t p231
, int32_t p232, int32_t p233, int32_t p234, int32_t p235, int32_t p236, int32_t p237, int32_t p238, int32_t p239
, int32_t p240, int32_t p241, int32_t p242, int32_t p243, int32_t p244, int32_t p245, int32_t p246, int32_t p247
, int32_t p248, int32_t p249, int32_t p250, int32_t p251, int32_t p252, int32_t p253, int32_t p254, int32_t p255
, int32_t p256, int32_t p257, int32_t p258, int32_t p259, int32_t p260, int32_t p261, int32_t p262, int32_t p263
, int32_t p264, int32_t p265, int32_t p266, int32_t p267, int32_t p268, int32_t p269, int32_t p270, int32_t p271
, int32_t p272, int32_t p273, int32_t p274, int32_t p275, int32_t p276, int32_t p277, int32_t p278, int32_t p279
, int32_t p280, int32_t p281, int32_t p282, int32_t p283, int32_t p284, int32_t p285, int32_t p286, int32_t p287
, int32_t p288, int32_t p289, int32_t p290, int32_t p291, int32_t p292, int32_t p293, int32_t p294, int32_t p295
, int32_t p296, int32_t p297, int32_t p298, int32_t p299, int32_t p300, int32_t p301, int32_t p302, int32_t p303
, int32_t p304, int32_t p305, int32_t p306, int32_t p307, int32_t p308, int32_t p309, int32_t p310, int32_t p311
, int32_t p312, int32_t p313, int32_t p314, int32_t p315, int32_t p316, int32_t p317, int32_t p318, int32_t p319
, int32_t p320, int32_t p321, int32_t p322, int32_t p323, int32_t p324, int32_t p325, int32_t p326, int32_t p327
, int32_t p328, int32_t p329, int32_t p330, int32_t p331, int32_t p332, int32_t p333, int32_t p334, int32_t p335
, int32_t p336, int32_t p337, int32_t p338, int32_t p339, int32_t p340, int32_t p341, int32_t p342, int32_t p343
, int32_t p344, int32_t p345, int32_t p346, int32_t p347, int32_t p348, int32_t p349, int32_t p350, int32_t p351
, int32_t p352, int32_t p353, int32_t p354, int32_t p355, int32_t p356, int32_t p357, int32_t p358, int32_t p359
, int32_t p360, int32_t p361, int32_t p362, int32_t p363, int32_t p364, int32_t p365, int32_t p366, int32_t p367
, int32_t p368, int32_t p369, int32_t p370, int32_t p371, int32_t p372, int32_t p373, int32_t p374, int32_t p375
, int32_t p376, int32_t p377, int32_t p378, int32_t p379, int32_t p380, int32_t p381, int32_t p382, int32_t p383
, int32_t p384, int32_t p385, int32_t p386, int32_t p387, int32_t p388, int32_t p389, int32_t p390, int32_t p391
, int32_t p392, int32_t p393, int32_t p394, int32_t p395, int32_t p396, int32_t p397, int32_t p398, int32_t p399
, int32_t p400, int32_t p401, int32_t p402, int32_t p403, int32_t p404, int32_t p405, int32_t p406, int32_t p407
, int32_t p408, int32_t p409, int32_t p410, int32_t p411, int32_t p412, int32_t p413, int32_t p414, int32_t p415
, int32_t p416, int32_t p417, int32_t p418, int32_t p419, int32_t p420, int32_t p421, int32_t p422, int32_t p423
, int32_t p424, int32_t p425, int32_t p426, int32_t p427, int32_t p428, int32_t p429, int32_t p430, int32_t p431
, int32_t p432, int32_t p433, int32_t p434, int32_t p435, int32_t p436, int32_t p437, int32_t p438, int32_t p439
, int32_t p440, int32_t p441, int32_t p442, int32_t p443, int32_t p444, int32_t p445, int32_t p446, int32_t p447
, int32_t p448, int32_t p449, int32_t p450, int32_t p451, int32_t p452, int32_t p453, int32_t p454, int32_t p455
, int32_t p456, int32_t p457, int32_t p458, int32_t p459, int32_t p460, int32_t p461, int32_t p462, int32_t p463
, int32_t p464, int32_t p465, int32_t p466, int32_t p467, int32_t p468, int32_t p469, int32_t p470, int32_t p471
, int32_t p472, int32_t p473, int32_t p474, int32_t p475, int32_t p476, int32_t p477, int32_t p478, int32_t p479
, int32_t p480, int32_t p481, int32_t p482, int32_t p483, int32_t p484, int32_t p485, int32_t p486, int32_t p487
, int32_t p488, int32_t p489, int32_t p490, int32_t p491, int32_t p492, int32_t p493, int32_t p494, int32_t p495
, int32_t p496, int32_t p497, int32_t p498, int32_t p499, int32_t p500, int32_t p501, int32_t p502, int32_t p503
, int32_t p504, int32_t p505, int32_t p506, int32_t p507, int32_t p508, int32_t p509, int32_t p510, int32_t p511
, int32_t p512, int32_t p513, int32_t p514, int32_t p515, int32_t p516, int32_t p517, int32_t p518, int32_t p519
, int32_t p520, int32_t p521, int32_t p522, int32_t p523, int32_t p524, int32_t p525, int32_t p526, int32_t p527
, int32_t p528, int32_t p529, int32_t p530, int32_t p531, int32_t p532, int32_t p533, int32_t p534, int32_t p535
, int32_t p536, int32_t p537, int32_t p538, int32_t p539, int32_t p540, int32_t p541, int32_t p542, int32_t p543
, int32_t p544, int32_t p545, int32_t p546, int32_t p547, int32_t p548, int32_t p549, int32_t p550, int32_t p551
, int32_t p552, int32_t p553, int32_t p554, int32_t p555, int32_t p556, int32_t p557, int32_t p558, int32_t p559
, int32_t p560, int32_t p561, int32_t p562, int32_t p563, int32_t p564, int32_t p565, int32_t p566, int32_t p567
, int32_t p568, int32_t p569, int32_t p570, int32_t p571, int32_t p572, int32_t p573, int32_t p574, int32_t p575
, int32_t p576, int32_t p577, int32_t p578, int32_t p579, int32_t p580, int32_t p581, int32_t p582, int32_t p583
, int32_t p584, int32_t p585, int32_t p586, int32_t p587, int32_t p588, int32_t p589, int32_t p590, int32_t p591
, int32_t p592, int32_t p593, int32_t p594, int32_t p595, int32_t p596, int32_t p597, int32_t p598, int32_t p599
, int32_t p600, int32_t p601, int32_t p602, int32_t p603, int32_t p604, int32_t p605, int32_t p606, int32_t p607
, int32_t p608, int32_t p609, int32_t p610, int32_t p611, int32_t p612, int32_t p613, int32_t p614, int32_t p615
, int32_t p616, int32_t p617, int32_t p618, int32_t p619, int32_t p620, int32_t p621, int32_t p622, int32_t p623
, int32_t p624, int32_t p625, int32_t p626, int32_t p627, int32_t p628, int32_t p629, int32_t p630, int32_t p631
, int32_t p632, int32_t p633, int32_t p634, int32_t p635, int32_t p636, int32_t p637, int32_t p638, int32_t p639
, int32_t p640, int32_t p641, int32_t p642, int32_t p643, int32_t p644, int32_t p645, int32_t p646, int32_t p647
, int32_t p648, int32_t p649, int32_t p650, int32_t p651, int32_t p652, int32_t p653, int32_t p654, int32_t p655
, int32_t p656, int32_t p657, int32_t p658, int32_t p659, int32_t p660, int32_t p661, int32_t p662, int32_t p663
, int32_t p664, int32_t p665, int32_t p666, int32_t p667, int32_t p668, int32_t p669, int32_t p670, int32_t p671
, int32_t p672, int32_t p673, int32_t p674, int32_t p675, int32_t p676, int32_t p677, int32_t p678, int32_t p679
, int32_t p680, int32_t p681, int32_t p682, int32_t p683, int32_t p684, int32_t p685, int32_t p686, int32_t p687
, int32_t p688, int32_t p689, int32_t p690, int32_t p691, int32_t p692, int32_t p693, int32_t p694, int32_t p695
, int32_t p696, int32_t p697, int32_t p698, int32_t p699, int32_t p700, int32_t p701, int32_t p702, int32_t p703
, int32_t p704, int32_t p705, int32_t p706, int32_t p707, int32_t p708, int32_t p709, int32_t p710, int32_t p711
, int32_t p712, int32_t p713, int32_t p714, int32_t p715, int32_t p716, int32_t p717, int32_t p718, int32_t p719
, int32_t p720, int32_t p721, int32_t p722, int32_t p723, int32_t p724, int32_t p725, int32_t p726, int32_t p727
, int32_t p728, int32_t p729, int32_t p730, int32_t p731, int32_t p732, int32_t p733, int32_t p734, int32_t p735
, int32_t p736, int32_t p737, int32_t p738, int32_t p739, int32_t p740, int32_t p741, int32_t p742, int32_t p743
, int32_t p744, int32_t p745, int32_t p746, int32_t p747, int32_t p748, int32_t p749, int32_t p750, int32_t p751
, int32_t p752, int32_t p753, int32_t p754, int32_t p755, int32_t p756, int32_t p757, int32_t p758, int32_t p759
, int32_t p760, int32_t p761, int32_t p762, int32_t p763, int32_t p764, int32_t p765, int32_t p766, int32_t p767
, int32_t p768, int32_t p769, int32_t p770, int32_t p771, int32_t p772, int32_t p773, int32_t p774, int32_t p775
, int32_t p776, int32_t p777, int32_t p778, int32_t p779, int32_t p780, int32_t p781, int32_t p782, int32_t p783
, int32_t p784, int32_t p785, int32_t p786, int32_t p787, int32_t p788, int32_t p789, int32_t p790, int32_t p791
, int32_t p792, int32_t p793, int32_t p794, int32_t p795, int32_t p796, int32_t p797, int32_t p798, int32_t p799
, int32_t p800, int32_t p801, int32_t p802, int32_t p803, int32_t p804, int32_t p805, int32_t p806, int32_t p807
, int32_t p808, int32_t p809, int32_t p810, int32_t p811, int32_t p812, int32_t p813, int32_t p814, int32_t p815
, int32_t p816, int32_t p817, int32_t p818, int32_t p819, int32_t p820, int32_t p821, int32_t p822, int32_t p823
, int32_t p824, int32_t p825, int32_t p826, int32_t p827, int32_t p828, int32_t p829, int32_t p830, int32_t p831
, int32_t p832, int32_t p833, int32_t p834, int32_t p835, int32_t p836, int32_t p837, int32_t p838, int32_t p839
, int32_t p840, int32_t p841, int32_t p842, int32_t p843, int32_t p844, int32_t p845, int32_t p846, int32_t p847
, int32_t p848, int32_t p849, int32_t p850, int32_t p851, int32_t p852, int32_t p853, int32_t p854, int32_t p855
, int32_t p856, int32_t p857, int32_t p858, int32_t p859, int32_t p860, int32_t p861, int32_t p862, int32_t p863
, int32_t p864, int32_t p865, int32_t p866, int32_t p867, int32_t p868, int32_t p869, int32_t p870, int32_t p871
, int32_t p872, int32_t p873, int32_t p874, int32_t p875, int32_t p876, int32_t p877, int32_t p878, int32_t p879
, int32_t p880, int32_t p881, int32_t p882, int32_t p883, int32_t p884, int32_t p885, int32_t p886, int32_t p887
, int32_t p888, int32_t p889, int32_t p890, int32_t p891, int32_t p892, int32_t p893, int32_t p894, int32_t p895
, int32_t p896, int32_t p897, int32_t p898, int32_t p899, int32_t p900, int32_t p901, int32_t p902, int32_t p903
, int32_t p904, int32_t p905, int32_t p906, int32_t p907, int32_t p908, int32_t p909, int32_t p910, int32_t p911
, int32_t p912, int32_t p913, int32_t p914, int32_t p915, int32_t p916, int32_t p917, int32_t p918, int32_t p919
, int32_t p920, int32_t p921, int32_t p922, int32_t p923, int32_t p924, int32_t p925, int32_t p926, int32_t p927
, int32_t p928, int32_t p929, int32_t p930, int32_t p931, int32_t p932, int32_t p933, int32_t p934, int32_t p935
, int32_t p936, int32_t p937, int32_t p938, int32_t p939, int32_t p940, int32_t p941, int32_t p942, int32_t p943
, int32_t p944, int32_t p945, int32_t p946, int32_t p947, int32_t p948, int32_t p949, int32_t p950, int32_t p951
, int32_t p952, int32_t p953, int32_t p954, int32_t p955, int32_t p956, int32_t p957, int32_t p958, int32_t p959
, int32_t p960, int32_t p961, int32_t p962, int32_t p963, int32_t p964, int32_t p965, int32_t p966, int32_t p967
, int32_t p968, int32_t p969, int32_t p970, int32_t p971, int32_t p972, int32_t p973, int32_t p974, int32_t p975
, int32_t p976, int32_t p977, int32_t p978, int32_t p979, int32_t p980, int32_t p981, int32_t p982, int32_t p983
, int32_t p984, int32_t p985, int32_t p986, int32_t p987, int32_t p988, int32_t p989, int32_t p990, int32_t p991
, int32_t p992, int32_t p993, int32_t p994, int32_t p995, int32_t p996, int32_t p997, int32_t p998, int32_t p999
)
{
int32_t x;
x = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7
+ p8 + p9 + p10 + p11 + p12 + p13 + p14 + p15
+ p16 + p17 + p18 + p19 + p20 + p21 + p22 + p23
+ p24 + p25 + p26 + p27 + p28 + p29 + p30 + p31
+ p32 + p33 + p34 + p35 + p36 + p37 + p38 + p39
+ p40 + p41 + p42 + p43 + p44 + p45 + p46 + p47
+ p48 + p49 + p50 + p51 + p52 + p53 + p54 + p55
+ p56 + p57 + p58 + p59 + p60 + p61 + p62 + p63
+ p64 + p65 + p66 + p67 + p68 + p69 + p70 + p71
+ p72 + p73 + p74 + p75 + p76 + p77 + p78 + p79
+ p80 + p81 + p82 + p83 + p84 + p85 + p86 + p87
+ p88 + p89 + p90 + p91 + p92 + p93 + p94 + p95
+ p96 + p97 + p98 + p99 + p100 + p101 + p102 + p103
+ p104 + p105 + p106 + p107 + p108 + p109 + p110 + p111
+ p112 + p113 + p114 + p115 + p116 + p117 + p118 + p119
+ p120 + p121 + p122 + p123 + p124 + p125 + p126 + p127
+ p128 + p129 + p130 + p131 + p132 + p133 + p134 + p135
+ p136 + p137 + p138 + p139 + p140 + p141 + p142 + p143
+ p144 + p145 + p146 + p147 + p148 + p149 + p150 + p151
+ p152 + p153 + p154 + p155 + p156 + p157 + p158 + p159
+ p160 + p161 + p162 + p163 + p164 + p165 + p166 + p167
+ p168 + p169 + p170 + p171 + p172 + p173 + p174 + p175
+ p176 + p177 + p178 + p179 + p180 + p181 + p182 + p183
+ p184 + p185 + p186 + p187 + p188 + p189 + p190 + p191
+ p192 + p193 + p194 + p195 + p196 + p197 + p198 + p199
+ p200 + p201 + p202 + p203 + p204 + p205 + p206 + p207
+ p208 + p209 + p210 + p211 + p212 + p213 + p214 + p215
+ p216 + p217 + p218 + p219 + p220 + p221 + p222 + p223
+ p224 + p225 + p226 + p227 + p228 + p229 + p230 + p231
+ p232 + p233 + p234 + p235 + p236 + p237 + p238 + p239
+ p240 + p241 + p242 + p243 + p244 + p245 + p246 + p247
+ p248 + p249 + p250 + p251 + p252 + p253 + p254 + p255
+ p256 + p257 + p258 + p259 + p260 + p261 + p262 + p263
+ p264 + p265 + p266 + p267 + p268 + p269 + p270 + p271
+ p272 + p273 + p274 + p275 + p276 + p277 + p278 + p279
+ p280 + p281 + p282 + p283 + p284 + p285 + p286 + p287
+ p288 + p289 + p290 + p291 + p292 + p293 + p294 + p295
+ p296 + p297 + p298 + p299 + p300 + p301 + p302 + p303
+ p304 + p305 + p306 + p307 + p308 + p309 + p310 + p311
+ p312 + p313 + p314 + p315 + p316 + p317 + p318 + p319
+ p320 + p321 + p322 + p323 + p324 + p325 + p326 + p327
+ p328 + p329 + p330 + p331 + p332 + p333 + p334 + p335
+ p336 + p337 + p338 + p339 + p340 + p341 + p342 + p343
+ p344 + p345 + p346 + p347 + p348 + p349 + p350 + p351
+ p352 + p353 + p354 + p355 + p356 + p357 + p358 + p359
+ p360 + p361 + p362 + p363 + p364 + p365 + p366 + p367
+ p368 + p369 + p370 + p371 + p372 + p373 + p374 + p375
+ p376 + p377 + p378 + p379 + p380 + p381 + p382 + p383
+ p384 + p385 + p386 + p387 + p388 + p389 + p390 + p391
+ p392 + p393 + p394 + p395 + p396 + p397 + p398 + p399
+ p400 + p401 + p402 + p403 + p404 + p405 + p406 + p407
+ p408 + p409 + p410 + p411 + p412 + p413 + p414 + p415
+ p416 + p417 + p418 + p419 + p420 + p421 + p422 + p423
+ p424 + p425 + p426 + p427 + p428 + p429 + p430 + p431
+ p432 + p433 + p434 + p435 + p436 + p437 + p438 + p439
+ p440 + p441 + p442 + p443 + p444 + p445 + p446 + p447
+ p448 + p449 + p450 + p451 + p452 + p453 + p454 + p455
+ p456 + p457 + p458 + p459 + p460 + p461 + p462 + p463
+ p464 + p465 + p466 + p467 + p468 + p469 + p470 + p471
+ p472 + p473 + p474 + p475 + p476 + p477 + p478 + p479
+ p480 + p481 + p482 + p483 + p484 + p485 + p486 + p487
+ p488 + p489 + p490 + p491 + p492 + p493 + p494 + p495
+ p496 + p497 + p498 + p499 + p500 + p501 + p502 + p503
+ p504 + p505 + p506 + p507 + p508 + p509 + p510 + p511
+ p512 + p513 + p514 + p515 + p516 + p517 + p518 + p519
+ p520 + p521 + p522 + p523 + p524 + p525 + p526 + p527
+ p528 + p529 + p530 + p531 + p532 + p533 + p534 + p535
+ p536 + p537 + p538 + p539 + p540 + p541 + p542 + p543
+ p544 + p545 + p546 + p547 + p548 + p549 + p550 + p551
+ p552 + p553 + p554 + p555 + p556 + p557 + p558 + p559
+ p560 + p561 + p562 + p563 + p564 + p565 + p566 + p567
+ p568 + p569 + p570 + p571 + p572 + p573 + p574 + p575
+ p576 + p577 + p578 + p579 + p580 + p581 + p582 + p583
+ p584 + p585 + p586 + p587 + p588 + p589 + p590 + p591
+ p592 + p593 + p594 + p595 + p596 + p597 + p598 + p599
+ p600 + p601 + p602 + p603 + p604 + p605 + p606 + p607
+ p608 + p609 + p610 + p611 + p612 + p613 + p614 + p615
+ p616 + p617 + p618 + p619 + p620 + p621 + p622 + p623
+ p624 + p625 + p626 + p627 + p628 + p629 + p630 + p631
+ p632 + p633 + p634 + p635 + p636 + p637 + p638 + p639
+ p640 + p641 + p642 + p643 + p644 + p645 + p646 + p647
+ p648 + p649 + p650 + p651 + p652 + p653 + p654 + p655
+ p656 + p657 + p658 + p659 + p660 + p661 + p662 + p663
+ p664 + p665 + p666 + p667 + p668 + p669 + p670 + p671
+ p672 + p673 + p674 + p675 + p676 + p677 + p678 + p679
+ p680 + p681 + p682 + p683 + p684 + p685 + p686 + p687
+ p688 + p689 + p690 + p691 + p692 + p693 + p694 + p695
+ p696 + p697 + p698 + p699 + p700 + p701 + p702 + p703
+ p704 + p705 + p706 + p707 + p708 + p709 + p710 + p711
+ p712 + p713 + p714 + p715 + p716 + p717 + p718 + p719
+ p720 + p721 + p722 + p723 + p724 + p725 + p726 + p727
+ p728 + p729 + p730 + p731 + p732 + p733 + p734 + p735
+ p736 + p737 + p738 + p739 + p740 + p741 + p742 + p743
+ p744 + p745 + p746 + p747 + p748 + p749 + p750 + p751
+ p752 + p753 + p754 + p755 + p756 + p757 + p758 + p759
+ p760 + p761 + p762 + p763 + p764 + p765 + p766 + p767
+ p768 + p769 + p770 + p771 + p772 + p773 + p774 + p775
+ p776 + p777 + p778 + p779 + p780 + p781 + p782 + p783
+ p784 + p785 + p786 + p787 + p788 + p789 + p790 + p791
+ p792 + p793 + p794 + p795 + p796 + p797 + p798 + p799
+ p800 + p801 + p802 + p803 + p804 + p805 + p806 + p807
+ p808 + p809 + p810 + p811 + p812 + p813 + p814 + p815
+ p816 + p817 + p818 + p819 + p820 + p821 + p822 + p823
+ p824 + p825 + p826 + p827 + p828 + p829 + p830 + p831
+ p832 + p833 + p834 + p835 + p836 + p837 + p838 + p839
+ p840 + p841 + p842 + p843 + p844 + p845 + p846 + p847
+ p848 + p849 + p850 + p851 + p852 + p853 + p854 + p855
+ p856 + p857 + p858 + p859 + p860 + p861 + p862 + p863
+ p864 + p865 + p866 + p867 + p868 + p869 + p870 + p871
+ p872 + p873 + p874 + p875 + p876 + p877 + p878 + p879
+ p880 + p881 + p882 + p883 + p884 + p885 + p886 + p887
+ p888 + p889 + p890 + p891 + p892 + p893 + p894 + p895
+ p896 + p897 + p898 + p899 + p900 + p901 + p902 + p903
+ p904 + p905 + p906 + p907 + p908 + p909 + p910 + p911
+ p912 + p913 + p914 + p915 + p916 + p917 + p918 + p919
+ p920 + p921 + p922 + p923 + p924 + p925 + p926 + p927
+ p928 + p929 + p930 + p931 + p932 + p933 + p934 + p935
+ p936 + p937 + p938 + p939 + p940 + p941 + p942 + p943
+ p944 + p945 + p946 + p947 + p948 + p949 + p950 + p951
+ p952 + p953 + p954 + p955 + p956 + p957 + p958 + p959
+ p960 + p961 + p962 + p963 + p964 + p965 + p966 + p967
+ p968 + p969 + p970 + p971 + p972 + p973 + p974 + p975
+ p976 + p977 + p978 + p979 + p980 + p981 + p982 + p983
+ p984 + p985 + p986 + p987 + p988 + p989 + p990 + p991
+ p992 + p993 + p994 + p995 + p996 + p997 + p998 + p999;
return x;
}
// clang-format on

View File

@@ -0,0 +1,13 @@
(module
;; Define a memory with 1 initial page.
;; CRITICAL: We explicitly set the page size to 1 kilobyte.
;; Standard Wasm implies (pagesize 65536).
(memory 1 (pagesize 1024))
(func $finish (result i32)
;; If this module instantiates, the runtime accepted the custom page size.
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,29 @@
(module
;; Define a Mutable Global Variable to act as our counter.
;; We initialize it to 1,000,000.
(global $counter (mut i32) (i32.const 1000000))
(func $finish (result i32)
;; 1. Check if counter == 0 (Base Case)
global.get $counter
i32.eqz
if
;; If counter is 0, we are done. Return 1.
i32.const 1
return
end
;; 2. Decrement the Global Counter
global.get $counter
i32.const 1
i32.sub
global.set $counter
;; 3. Recursive Step: Call SELF
;; This puts an i32 (1) on the stack when it returns.
call $finish
)
;; Export the only function we have
(export "finish" (func $finish))
)

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,21 @@
(module
;; Define a 64-bit memory (index type i64)
;; Start with 1 page.
(memory i64 1)
(func $finish (result i32)
;; 1. Perform a store using a 64-bit address.
;; Even if the value is small (0), the type MUST be i64.
i64.const 0 ;; Address (64-bit)
i32.const 42 ;; Value (32-bit)
i32.store8 ;; Opcode doesn't change, but validation rules do.
;; 2. check memory size
;; memory.size now returns an i64.
memory.size
i64.const 1
i64.eq ;; Returns i32 (1 if true)
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,28 @@
(module
;; 1. Define Memory: 1 Page = 64KB = 65,536 bytes
(memory 1)
;; Export memory so the host can inspect it if needed
(export "memory" (memory 0))
(func $test_straddle (result i32)
;; Push the address onto the stack.
;; 65534 is valid, but it is only 2 bytes away from the end.
i32.const 65534
;; Attempt to load an i32 (4 bytes) from that address.
;; This requires bytes 65534, 65535, 65536, and 65537.
;; Since 65536 is the first invalid byte, this MUST trap.
i32.load
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
;; Export the function so you can call it from your host (JS, Python, etc.)
(export "finish" (func $test_straddle))
)

View File

@@ -0,0 +1,29 @@
(module
;; Start at your limit: 128 pages (8MB)
(memory 128)
(export "memory" (memory 0))
(func $try_grow_beyond_limit (result i32)
;; Attempt to grow by 0 page
i32.const 0
memory.grow
;; memory.grow returns:
;; -1 if the growth failed (Correct behavior for your limit)
;; 128 (old size) if growth succeeded (Means limit was bypassed)
;; Check if result == -1
i32.const -1
i32.eq
if
;; Growth FAILED (Host blocked it). Return -1.
i32.const -1
return
end
;; Growth SUCCEEDED (Host allowed it). Return 1.
i32.const 1
)
(export "finish" (func $try_grow_beyond_limit))
)

View File

@@ -0,0 +1,26 @@
(module
;; 1. Define Memory: Start with 0 pages
(memory 0)
;; Export memory to host
(export "memory" (memory 0))
(func $grow_from_zero (result i32)
;; We have 0 pages. We want to add 1 page.
;; Push delta (1) onto stack.
i32.const 1
;; Grow the memory.
;; If successful: memory becomes 64KB, returns old size (0).
;; If failed: memory stays 0, returns -1.
memory.grow
;; Drop the return value of memory.grow
drop
;; Return 1 (as requested)
i32.const 1
)
(export "finish" (func $grow_from_zero))
)

View File

@@ -0,0 +1,29 @@
(module
;; Start at your limit: 128 pages (8MB)
(memory 128)
(export "memory" (memory 0))
(func $try_grow_beyond_limit (result i32)
;; Attempt to grow by 1 page
i32.const 1
memory.grow
;; memory.grow returns:
;; -1 if the growth failed (Correct behavior for your limit)
;; 128 (old size) if growth succeeded (Means limit was bypassed)
;; Check if result == -1
i32.const -1
i32.eq
if
;; Growth FAILED (Host blocked it). Return -1.
i32.const -1
return
end
;; Growth SUCCEEDED (Host allowed it). Return 1.
i32.const 1
)
(export "finish" (func $try_grow_beyond_limit))
)

View File

@@ -0,0 +1,33 @@
(module
;; 1. Define Memory: Start with 1 page (64KB)
(memory 1)
;; Export memory to host
(export "memory" (memory 0))
(func $grow_negative (result i32)
;; The user pushed -1. In Wasm, this is interpreted as unsigned MAX_UINT32.
;; This is requesting to add 4,294,967,295 pages (approx 256 TB).
;; A secure runtime MUST fail this request (return -1) without crashing.
i32.const -1
;; Grow the memory.
;; Returns: old_size if success, -1 if failure.
memory.grow
;; Check if result == -1 (Failure)
i32.const -1
i32.eq
if
;; If memory.grow returned -1, we return -1 to signal "Correctly failed".
i32.const -1
return
end
;; If we are here, memory.grow somehow SUCCEEDED (Vulnerability).
;; We return 1 to signal "Unexpected Success".
i32.const 1
)
(export "finish" (func $grow_negative))
)

View File

@@ -0,0 +1,27 @@
(module
;; Define memory: 129 pages (> 8MB limit) min, 129 pages max
(memory 129 129)
;; Export memory so host can verify size
(export "memory" (memory 0))
;; access last byte of 8MB limit
(func $access_last_byte (result i32)
;; Math: 128 pages * 64,536 bytes/page = 8,388,608 bytes
;; Valid indices: 0 to 8,388,607
;; Push the address of the LAST valid byte
i32.const 8388607
;; Load byte from that address
i32.load8_u
;; Drop the value (we don't care what it is, just that we could read it)
drop
;; Return 1 to indicate success
i32.const 1
)
(export "finish" (func $access_last_byte))
)

View File

@@ -0,0 +1,26 @@
(module
;; Define memory: 128 pages (8MB) min, 128 pages max
(memory 128 128)
;; Export memory so host can verify size
(export "memory" (memory 0))
(func $access_last_byte (result i32)
;; Math: 128 pages * 64,536 bytes/page = 8,388,608 bytes
;; Valid indices: 0 to 8,388,607
;; Push the address of the LAST valid byte
i32.const 8388607
;; Load byte from that address
i32.load8_u
;; Drop the value (we don't care what it is, just that we could read it)
drop
;; Return 1 to indicate success
i32.const 1
)
(export "finish" (func $access_last_byte))
)

View File

@@ -0,0 +1,23 @@
(module
;; Define memory: 128 pages (8MB) min, 128 pages max
(memory 128 128)
;; Export memory so host can verify size
(export "memory" (memory 0))
(func $access_last_byte (result i32)
;; Push a negative address
i32.const -1
;; Load byte from that address
i32.load8_u
;; Drop the value
drop
;; Return 1 to indicate success
i32.const 1
)
(export "finish" (func $access_last_byte))
)

View File

@@ -0,0 +1,27 @@
(module
;; 1. Define Memory: 1 Page = 64KB
(memory 1)
(export "memory" (memory 0))
(func $test_offset_overflow (result i32)
;; 1. Push the base address onto the stack.
;; We use '0', which is the safest, most valid address possible.
i32.const 0
;; 2. Attempt to load using a static offset.
;; syntax: i32.load offset=N align=N
;; We set the offset to 65536 (the size of the memory).
;; The effective address becomes 0 + 65536 = 65536.
i32.load offset=65536
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
(export "finish" (func $test_offset_overflow))
)

View File

@@ -0,0 +1,22 @@
(module
;; Define 1 page of memory (64KB = 65,536 bytes)
(memory 1)
(func $read_edge (result i32)
;; Push the index of the LAST valid byte
i32.const 65535
;; Load 1 byte (unsigned)
i32.load8_u
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
;; Export as "finish" as requested
(export "finish" (func $read_edge))
)

View File

@@ -0,0 +1,23 @@
(module
;; Define 1 page of memory (64KB = 65,536 bytes)
(memory 1)
(func $read_overflow (result i32)
;; Push the index of the FIRST invalid byte
;; Memory is 0..65535, so 65536 is out of bounds.
i32.const 65536
;; Load 1 byte (unsigned)
i32.load8_u
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
;; Export as "finish" as requested
(export "finish" (func $read_overflow))
)

View File

@@ -0,0 +1,16 @@
(module
;; Memory 0: Index 0 (Empty)
(memory 0)
;; Memory 1: Index 1 (Size 1 page)
;; If multi-memory is disabled, this line causes a validation error (max 1 memory).
(memory 1)
(func $finish (result i32)
;; Query size of Memory Index 1.
;; Should return 1 (success).
memory.size 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,98 @@
(module
;; Type for call_indirect
(type (func (result i32)))
;; Memory and table declarations
(memory 1)
(table 1 funcref)
(data (i32.const 0) "test")
(elem (i32.const 0) $test_func)
;; Global declarations
(global $g0 (mut i32) (i32.const 0))
(global $g1 (mut i64) (i64.const 0))
;; Test function for call/call_indirect
(func $test_func (result i32)
i32.const 42
)
;; Main function with all instructions in hex order
(func $all_instructions (export "all_instructions") (result i32)
(local $l0 i32)
(local $l1 i64)
;; 0x01: nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
i32.const 11
)
)

View File

@@ -0,0 +1,25 @@
(module
;; Define 1 page of memory
(memory 1)
(export "memory" (memory 0))
(func $test_bulk_ops (result i32)
;; Setup: Write value 42 at index 0 so we have something to copy
(i32.store8 (i32.const 0) (i32.const 42))
;; Test memory.copy (Opcode 0xFC 0x0A)
;; Copy 1 byte from offset 0 to offset 100
(memory.copy
(i32.const 100) ;; Destination Offset
(i32.const 0) ;; Source Offset
(i32.const 1) ;; Size (bytes)
)
;; Verify: Read byte at offset 100. Should be 42.
(i32.load8_u (i32.const 100))
(i32.const 42)
i32.eq
)
(export "finish" (func $test_bulk_ops))
)

View File

@@ -0,0 +1,15 @@
(module
;; 1. Define a global using an EXTENDED constant expression.
;; MVP only allows (i32.const X).
;; This proposal allows (i32.add (i32.const X) (i32.const Y)).
(global $g i32 (i32.add (i32.const 10) (i32.const 32)))
(func $finish (result i32)
;; 2. verify the global equals 42
global.get $g
i32.const 42
i32.eq
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,18 @@
(module
(func $test_saturation (result i32)
;; 1. Push a float that is too big for a 32-bit integer
;; 1e10 (10 billion) > 2.14 billion (Max i32)
f32.const 1.0e10
;; 2. Attempt saturating conversion (Opcode 0xFC 0x00)
;; If supported: Clamps to MAX_I32.
;; If disabled: Validation error (unknown instruction).
i32.trunc_sat_f32_s
;; 3. Check if result is MAX_I32 (2147483647)
i32.const 2147483647
i32.eq
)
(export "finish" (func $test_saturation))
)

View File

@@ -0,0 +1,12 @@
;; generated by wasm-tools print gc_test.wasm that has the following hex
;; 0061736d01000000010b026000017f5f027f017f0103020100070a010666696e69736800000a0a010800fb01011a41010b
(module
(type (;0;) (func (result i32)))
(type (;1;) (struct (field (mut i32)) (field (mut i32))))
(export "finish" (func 0))
(func (;0;) (type 0) (result i32)
struct.new_default 1
drop
i32.const 1
)
)

View File

@@ -0,0 +1,22 @@
(module
;; 1. Function returning TWO values (Multi-Value feature)
(func $get_numbers (result i32 i32)
i32.const 10
i32.const 20
)
(func $finish (result i32)
;; Call pushes [10, 20] onto the stack
call $get_numbers
;; 2. Block taking TWO parameters (Multi-Value feature)
;; It consumes the [10, 20] from the stack.
block (param i32 i32) (result i32)
i32.add ;; 10 + 20 = 30
i32.const 30 ;; Expected result
i32.eq ;; Compare: returns 1 if equal
end
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,25 @@
(module
;; Define a mutable global initialized to 0
(global $counter (mut i32) (i32.const 0))
;; EXPORTING a mutable global is the key feature of this proposal.
;; In strict MVP, exported globals had to be immutable (const).
(export "counter" (global $counter))
(func $finish (result i32)
;; 1. Get current value
global.get $counter
;; 2. Add 1
i32.const 1
i32.add
;; 3. Set new value (Mutation)
global.set $counter
;; 4. Return 1 for success
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,18 @@
(module
;; Import a table from the host that holds externrefs
(import "env" "table" (table 1 externref))
(func $test_ref_types (result i32)
;; Store a null externref into the table at index 0
;; If reference_types is disabled, 'externref' and 'ref.null' will fail parsing.
(table.set
(i32.const 0) ;; Index
(ref.null extern) ;; Value (Null External Reference)
)
;; Return 1 (Success)
i32.const 1
)
(export "finish" (func $test_ref_types))
)

View File

@@ -0,0 +1,18 @@
(module
(func $test_sign_ext (result i32)
;; Push 255 (0x000000FF) onto the stack
i32.const 255
;; Sign-extend from 8-bit to 32-bit
;; If 255 is treated as an i8, it is -1.
;; Result should be -1 (0xFFFFFFFF).
;; Without this proposal, this opcode (0xC0) causes a validation error.
i32.extend8_s
;; Check if result is -1
i32.const -1
i32.eq
)
(export "finish" (func $test_sign_ext))
)

View File

@@ -0,0 +1 @@
;;hard to generate

View File

@@ -0,0 +1,15 @@
(module
;; Define a simple function we can tail-call
(func $target (result i32)
i32.const 1
)
(func $finish (result i32)
;; Try to use the 'return_call' instruction (Opcode 0x12)
;; If Tail Call proposal is disabled, this fails to Compile/Validate.
;; If enabled, it jumps to $target, which returns 1.
return_call $target
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,22 @@
(module
;; Function 1: The Infinite Loop
(func $run_forever
(loop $infinite
br $infinite
)
)
;; Function 2: Finish
(func $finish (result i32)
i32.const 1
)
;; 1. EXPORT the functions (optional, if you want to call them later)
(export "start" (func $run_forever))
(export "finish" (func $finish))
;; 2. The special start section
;; This tells the VM: "Run function $run_forever immediately
;; when this module is instantiated."
(start $run_forever)
)

View File

@@ -0,0 +1,10 @@
(module
;; Define a table with exactly 0 entries
(table 0 funcref)
;; Standard finish function
(func $finish (result i32)
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,24 @@
(module
;; Define a dummy function to put in the tables
(func $dummy)
;; TABLE 0: The default table (allowed in MVP)
;; Size: 1 initial, 1 max
(table $t0 1 1 funcref)
;; Initialize Table 0 at index 0
(elem (table $t0) (i32.const 0) $dummy)
;; TABLE 1: The second table (Requires Reference Types proposal)
;; If strict MVP is enforced, the parser should error here.
(table $t1 1 1 funcref)
;; Initialize Table 1 at index 0
(elem (table $t1) (i32.const 0) $dummy)
(func $finish (result i32)
;; If we successfully loaded a module with 2 tables, return 1.
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,25 @@
(module
;; Define a table with exactly 64 entries
(table 64 funcref)
;; A dummy function to reference
(func $dummy)
;; Initialize the table at offset 0 with 64 references to $dummy
(elem (i32.const 0)
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 8
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 16
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 24
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 32
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 40
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 48
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 56
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 64
)
;; Standard finish function
(func $finish (result i32)
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,25 @@
(module
;; Define a table with exactly 65 entries
(table 65 funcref)
;; A dummy function to reference
(func $dummy)
;; Initialize the table at offset 0 with 65 references to $dummy
(elem (i32.const 0)
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 8
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 16
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 24
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 32
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 40
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 48
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 56
$dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 64
$dummy ;; 65 (The one that breaks the camel's back)
)
(func $finish (result i32)
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,15 @@
(module
;; Definition: (table <min> <optional_max> <type>)
;; We use 0xFFFFFFFF (4,294,967,295), which is the unsigned equivalent of -1.
;; This tests if the runtime handles the maximum possible u32 value
;; without integer overflows or attempting a massive allocation.
;;
;; Note that using -1 as the table size cannot be parsed by wasm-tools or wat2wasm
(table 0xFFFFFFFF funcref)
(func $finish (result i32)
;; If the module loads despite the massive table, return 1.
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,15 @@
(module
(func $finish (export "finish") (result i32)
;; Setup for Requirement 2: Divide an i32 by 0
i32.const 42 ;; Push numerator
i32.const 0 ;; Push denominator (0)
i32.div_s ;; Perform signed division (42 / 0)
;; --- NOTE: Execution usually traps (crashes) at the line above ---
;; Logic to satisfy Requirement 1: Return i32 = 1
;; If execution continued, we would drop the division result and return 1
drop ;; Clear the stack
i32.const 1 ;; Push the return value
)
)

View File

@@ -0,0 +1,33 @@
(module
;; Define a table with 1 slot
(table 1 funcref)
;; Define Type A: Takes nothing, returns nothing
(type $type_void (func))
;; Define Type B: Takes nothing, returns i32
(type $type_i32 (func (result i32)))
;; Define a function of Type A
(func $void_func (type $type_void)
nop
)
;; Put Type A function into Table[0]
(elem (i32.const 0) $void_func)
(func $finish (result i32)
;; Attempt to call Index 0, but CLAIM we expect Type B (result i32).
;; The function at Index 0 matches Type A.
;; TRAP: "indirect call type mismatch"
;; 1. Push the table index (0) onto the stack
i32.const 0
;; 2. Call indirect using Type B signature.
;; This pops the index (0) from the stack.
call_indirect (type $type_i32)
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,18 @@
(module
(func $test_int_overflow (result i32)
;; 1. Push INT_MIN (-2147483648)
;; In Hex: 0x80000000
i32.const -2147483648
;; 2. Push -1
i32.const -1
;; 3. Signed Division
;; This specific case is the ONLY integer arithmetic operation
;; (besides divide by zero) that traps in the spec.
;; Result would be +2147483648, which is too big for signed i32.
i32.div_s
)
(export "finish" (func $test_int_overflow))
)

View File

@@ -0,0 +1,22 @@
(module
;; Table size is 1, so Index 0 is VALID bounds.
;; However, we do NOT initialize it, so it contains 'ref.null'.
(table 1 funcref)
(type $t (func (result i32)))
(func $finish (result i32)
;; Call Index 0.
;; Bounds check passes (0 < 1).
;; Null check fails.
;; TRAP: "uninitialized element" or "undefined element"
;; 1. Push the index (0) onto the stack first
i32.const 0
;; 2. Perform the call. This pops the index.
call_indirect (type $t)
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,12 @@
(module
(func $finish (result i32)
;; This instruction explicitly causes a trap.
;; It consumes no fuel (beyond the instruction itself) and stops execution.
unreachable
;; This code is dead and never reached
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,38 @@
(module
;; Import clock_time_get from WASI
;; Signature: (param clock_id precision return_ptr) (result errno)
(import "wasi_snapshot_preview1" "clock_time_get"
(func $clock_time_get (param i32 i64 i32) (result i32))
)
(memory 1)
(export "memory" (memory 0))
(func $finish (result i32)
;; We will store the timestamp (a 64-bit integer) at address 0.
;; No setup required in memory beforehand!
;; Call the function
(call $clock_time_get
(i32.const 0) ;; clock_id: 0 = Realtime (Wallclock)
(i64.const 1000) ;; precision: 1000ns (hint to OS)
(i32.const 0) ;; result_ptr: Write the time to address 0
)
;; The function returns an 'errno' (error code).
;; 0 = Success. Anything else = Error.
;; Check if errno (top of stack) is 0
i32.eqz
if (result i32)
;; Success! The time is now stored in heap[0..8].
;; We return 1 as requested.
i32.const 1
else
;; Failed (maybe WASI is disabled or clock is missing)
i32.const -1
end
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,59 @@
(module
;; Import WASI fd_write
;; Signature: (fd, iovs_ptr, iovs_len, nwritten_ptr) -> errno
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32))
)
(memory 1)
(export "memory" (memory 0))
;; --- DATA SEGMENTS ---
;; 1. The String Data "Hello\n" placed at offset 16
;; We assume offset 0-16 is reserved for the IOVec struct
(data (i32.const 16) "Hello\n")
;; 2. The IO Vector (struct iovec) placed at offset 0
;; Structure: { buf_ptr: u32, buf_len: u32 }
;; Field 1: buf_ptr = 16 (Location of "Hello\n")
;; Encoded in little-endian: 10 00 00 00
(data (i32.const 0) "\10\00\00\00")
;; Field 2: buf_len = 6 (Length of "Hello\n")
;; Encoded in little-endian: 06 00 00 00
(data (i32.const 4) "\06\00\00\00")
(func $finish (result i32)
(local $nwritten_ptr i32)
;; We will ask WASI to write the "number of bytes written" to address 24
;; (safely after our string data)
i32.const 24
local.set $nwritten_ptr
;; Call fd_write
(call $fd_write
(i32.const 1) ;; fd: 1 = STDOUT
(i32.const 0) ;; iovs_ptr: Address 0 (where we defined the struct)
(i32.const 1) ;; iovs_len: We are passing 1 vector
(local.get $nwritten_ptr) ;; nwritten_ptr: Address 24
)
;; The function returns an 'errno' (i32).
;; 0 means Success.
;; Check if errno == 0
i32.eqz
if (result i32)
;; Success: Return 1
i32.const 1
else
;; Failure: Return -1
i32.const -1
end
)
(export "finish" (func $finish))
)

View File

@@ -0,0 +1,22 @@
(module
(func $finish (result i32)
;; 1. Push operands
i64.const 1
i64.const 2
;; 2. Execute Wide Multiplication
;; If the feature is DISABLED, the parser/validator will trap here
;; with "unknown instruction" or "invalid opcode".
;; Input: [i64, i64] -> Output: [i64, i64]
i64.mul_wide_u
;; 3. Clean up the stack (drop the two i64 results)
drop
drop
;; 4. Return 1 to signal that validation passed
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -23,6 +23,9 @@ setupConfigForUnitTests(Config& cfg)
cfg.FEES.reference_fee = UNIT_TEST_REFERENCE_FEE;
cfg.FEES.account_reserve = XRP(200).value().xrp().drops();
cfg.FEES.owner_reserve = XRP(50).value().xrp().drops();
cfg.FEES.gas_limit = 1'000'000;
cfg.FEES.bytecode_size_limit = 1'000'000;
cfg.FEES.gas_price = 1'000;
// The Beta API (currently v2) is always available to tests
cfg.BETA_RPC_API = true;

View File

@@ -511,6 +511,22 @@ public:
if (jv.isMember(jss::reserve_inc) != isFlagLedger)
return false;
if (env.closed()->rules().enabled(featureSmartEscrow))
{
if (jv.isMember(jss::gas_limit) != isFlagLedger)
return false;
if (jv.isMember(jss::bytecode_size_limit) != isFlagLedger)
return false;
}
else
{
if (jv.isMember(jss::gas_limit))
return false;
if (jv.isMember(jss::bytecode_size_limit))
return false;
}
return true;
};
@@ -1558,7 +1574,8 @@ public:
testTransactionsAPIv1();
testTransactionsAPIv2();
testManifests();
testValidations(all - xrpFees);
testValidations(all - featureXRPFees - featureSmartEscrow);
testValidations(all - featureSmartEscrow);
testValidations(all);
testSubErrors(true);
testSubErrors(false);

View File

@@ -27,6 +27,9 @@ TEST(FeeSettingsTests, BuilderSettersRoundTrip)
auto const baseFeeDropsValue = canonical_AMOUNT();
auto const reserveBaseDropsValue = canonical_AMOUNT();
auto const reserveIncrementDropsValue = canonical_AMOUNT();
auto const gasLimitValue = canonical_UINT32();
auto const bytecodeSizeLimitValue = canonical_UINT32();
auto const gasPriceValue = canonical_UINT32();
auto const previousTxnIDValue = canonical_UINT256();
auto const previousTxnLgrSeqValue = canonical_UINT32();
@@ -40,6 +43,9 @@ TEST(FeeSettingsTests, BuilderSettersRoundTrip)
builder.setBaseFeeDrops(baseFeeDropsValue);
builder.setReserveBaseDrops(reserveBaseDropsValue);
builder.setReserveIncrementDrops(reserveIncrementDropsValue);
builder.setGasLimit(gasLimitValue);
builder.setBytecodeSizeLimit(bytecodeSizeLimitValue);
builder.setGasPrice(gasPriceValue);
builder.setPreviousTxnID(previousTxnIDValue);
builder.setPreviousTxnLgrSeq(previousTxnLgrSeqValue);
@@ -108,6 +114,30 @@ TEST(FeeSettingsTests, BuilderSettersRoundTrip)
EXPECT_TRUE(entry.hasReserveIncrementDrops());
}
{
auto const& expected = gasLimitValue;
auto const actualOpt = entry.getGasLimit();
ASSERT_TRUE(actualOpt.has_value());
expectEqualField(expected, *actualOpt, "sfGasLimit");
EXPECT_TRUE(entry.hasGasLimit());
}
{
auto const& expected = bytecodeSizeLimitValue;
auto const actualOpt = entry.getBytecodeSizeLimit();
ASSERT_TRUE(actualOpt.has_value());
expectEqualField(expected, *actualOpt, "sfBytecodeSizeLimit");
EXPECT_TRUE(entry.hasBytecodeSizeLimit());
}
{
auto const& expected = gasPriceValue;
auto const actualOpt = entry.getGasPrice();
ASSERT_TRUE(actualOpt.has_value());
expectEqualField(expected, *actualOpt, "sfGasPrice");
EXPECT_TRUE(entry.hasGasPrice());
}
{
auto const& expected = previousTxnIDValue;
auto const actualOpt = entry.getPreviousTxnID();
@@ -144,6 +174,9 @@ TEST(FeeSettingsTests, BuilderFromSleRoundTrip)
auto const baseFeeDropsValue = canonical_AMOUNT();
auto const reserveBaseDropsValue = canonical_AMOUNT();
auto const reserveIncrementDropsValue = canonical_AMOUNT();
auto const gasLimitValue = canonical_UINT32();
auto const bytecodeSizeLimitValue = canonical_UINT32();
auto const gasPriceValue = canonical_UINT32();
auto const previousTxnIDValue = canonical_UINT256();
auto const previousTxnLgrSeqValue = canonical_UINT32();
@@ -156,6 +189,9 @@ TEST(FeeSettingsTests, BuilderFromSleRoundTrip)
sle->at(sfBaseFeeDrops) = baseFeeDropsValue;
sle->at(sfReserveBaseDrops) = reserveBaseDropsValue;
sle->at(sfReserveIncrementDrops) = reserveIncrementDropsValue;
sle->at(sfGasLimit) = gasLimitValue;
sle->at(sfBytecodeSizeLimit) = bytecodeSizeLimitValue;
sle->at(sfGasPrice) = gasPriceValue;
sle->at(sfPreviousTxnID) = previousTxnIDValue;
sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue;
@@ -259,6 +295,45 @@ TEST(FeeSettingsTests, BuilderFromSleRoundTrip)
expectEqualField(expected, *fromBuilderOpt, "sfReserveIncrementDrops");
}
{
auto const& expected = gasLimitValue;
auto const fromSleOpt = entryFromSle.getGasLimit();
auto const fromBuilderOpt = entryFromBuilder.getGasLimit();
ASSERT_TRUE(fromSleOpt.has_value());
ASSERT_TRUE(fromBuilderOpt.has_value());
expectEqualField(expected, *fromSleOpt, "sfGasLimit");
expectEqualField(expected, *fromBuilderOpt, "sfGasLimit");
}
{
auto const& expected = bytecodeSizeLimitValue;
auto const fromSleOpt = entryFromSle.getBytecodeSizeLimit();
auto const fromBuilderOpt = entryFromBuilder.getBytecodeSizeLimit();
ASSERT_TRUE(fromSleOpt.has_value());
ASSERT_TRUE(fromBuilderOpt.has_value());
expectEqualField(expected, *fromSleOpt, "sfBytecodeSizeLimit");
expectEqualField(expected, *fromBuilderOpt, "sfBytecodeSizeLimit");
}
{
auto const& expected = gasPriceValue;
auto const fromSleOpt = entryFromSle.getGasPrice();
auto const fromBuilderOpt = entryFromBuilder.getGasPrice();
ASSERT_TRUE(fromSleOpt.has_value());
ASSERT_TRUE(fromBuilderOpt.has_value());
expectEqualField(expected, *fromSleOpt, "sfGasPrice");
expectEqualField(expected, *fromBuilderOpt, "sfGasPrice");
}
{
auto const& expected = previousTxnIDValue;
@@ -351,6 +426,12 @@ TEST(FeeSettingsTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(entry.getReserveBaseDrops().has_value());
EXPECT_FALSE(entry.hasReserveIncrementDrops());
EXPECT_FALSE(entry.getReserveIncrementDrops().has_value());
EXPECT_FALSE(entry.hasGasLimit());
EXPECT_FALSE(entry.getGasLimit().has_value());
EXPECT_FALSE(entry.hasBytecodeSizeLimit());
EXPECT_FALSE(entry.getBytecodeSizeLimit().has_value());
EXPECT_FALSE(entry.hasGasPrice());
EXPECT_FALSE(entry.getGasPrice().has_value());
EXPECT_FALSE(entry.hasPreviousTxnID());
EXPECT_FALSE(entry.getPreviousTxnID().has_value());
EXPECT_FALSE(entry.hasPreviousTxnLgrSeq());

View File

@@ -37,6 +37,9 @@ TEST(TransactionsSetFeeTests, BuilderSettersRoundTrip)
auto const baseFeeDropsValue = canonical_AMOUNT();
auto const reserveBaseDropsValue = canonical_AMOUNT();
auto const reserveIncrementDropsValue = canonical_AMOUNT();
auto const gasLimitValue = canonical_UINT32();
auto const bytecodeSizeLimitValue = canonical_UINT32();
auto const gasPriceValue = canonical_UINT32();
SetFeeBuilder builder{
accountValue,
@@ -53,6 +56,9 @@ TEST(TransactionsSetFeeTests, BuilderSettersRoundTrip)
builder.setBaseFeeDrops(baseFeeDropsValue);
builder.setReserveBaseDrops(reserveBaseDropsValue);
builder.setReserveIncrementDrops(reserveIncrementDropsValue);
builder.setGasLimit(gasLimitValue);
builder.setBytecodeSizeLimit(bytecodeSizeLimitValue);
builder.setGasPrice(gasPriceValue);
auto tx = builder.build(publicKey, secretKey);
@@ -134,6 +140,30 @@ TEST(TransactionsSetFeeTests, BuilderSettersRoundTrip)
EXPECT_TRUE(tx.hasReserveIncrementDrops());
}
{
auto const& expected = gasLimitValue;
auto const actualOpt = tx.getGasLimit();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGasLimit should be present";
expectEqualField(expected, *actualOpt, "sfGasLimit");
EXPECT_TRUE(tx.hasGasLimit());
}
{
auto const& expected = bytecodeSizeLimitValue;
auto const actualOpt = tx.getBytecodeSizeLimit();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBytecodeSizeLimit should be present";
expectEqualField(expected, *actualOpt, "sfBytecodeSizeLimit");
EXPECT_TRUE(tx.hasBytecodeSizeLimit());
}
{
auto const& expected = gasPriceValue;
auto const actualOpt = tx.getGasPrice();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGasPrice should be present";
expectEqualField(expected, *actualOpt, "sfGasPrice");
EXPECT_TRUE(tx.hasGasPrice());
}
}
// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper,
@@ -158,6 +188,9 @@ TEST(TransactionsSetFeeTests, BuilderFromStTxRoundTrip)
auto const baseFeeDropsValue = canonical_AMOUNT();
auto const reserveBaseDropsValue = canonical_AMOUNT();
auto const reserveIncrementDropsValue = canonical_AMOUNT();
auto const gasLimitValue = canonical_UINT32();
auto const bytecodeSizeLimitValue = canonical_UINT32();
auto const gasPriceValue = canonical_UINT32();
// Build an initial transaction
SetFeeBuilder initialBuilder{
@@ -174,6 +207,9 @@ TEST(TransactionsSetFeeTests, BuilderFromStTxRoundTrip)
initialBuilder.setBaseFeeDrops(baseFeeDropsValue);
initialBuilder.setReserveBaseDrops(reserveBaseDropsValue);
initialBuilder.setReserveIncrementDrops(reserveIncrementDropsValue);
initialBuilder.setGasLimit(gasLimitValue);
initialBuilder.setBytecodeSizeLimit(bytecodeSizeLimitValue);
initialBuilder.setGasPrice(gasPriceValue);
auto initialTx = initialBuilder.build(publicKey, secretKey);
@@ -248,6 +284,27 @@ TEST(TransactionsSetFeeTests, BuilderFromStTxRoundTrip)
expectEqualField(expected, *actualOpt, "sfReserveIncrementDrops");
}
{
auto const& expected = gasLimitValue;
auto const actualOpt = rebuiltTx.getGasLimit();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGasLimit should be present";
expectEqualField(expected, *actualOpt, "sfGasLimit");
}
{
auto const& expected = bytecodeSizeLimitValue;
auto const actualOpt = rebuiltTx.getBytecodeSizeLimit();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBytecodeSizeLimit should be present";
expectEqualField(expected, *actualOpt, "sfBytecodeSizeLimit");
}
{
auto const& expected = gasPriceValue;
auto const actualOpt = rebuiltTx.getGasPrice();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGasPrice should be present";
expectEqualField(expected, *actualOpt, "sfGasPrice");
}
}
// 3) Verify wrapper throws when constructed from wrong transaction type.
@@ -319,6 +376,12 @@ TEST(TransactionsSetFeeTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(tx.getReserveBaseDrops().has_value());
EXPECT_FALSE(tx.hasReserveIncrementDrops());
EXPECT_FALSE(tx.getReserveIncrementDrops().has_value());
EXPECT_FALSE(tx.hasGasLimit());
EXPECT_FALSE(tx.getGasLimit().has_value());
EXPECT_FALSE(tx.hasBytecodeSizeLimit());
EXPECT_FALSE(tx.getBytecodeSizeLimit().has_value());
EXPECT_FALSE(tx.hasGasPrice());
EXPECT_FALSE(tx.getGasPrice().has_value());
}
}

View File

@@ -32,23 +32,23 @@ namespace xrpl {
namespace detail {
template <typename ValueType>
class VotableValue
{
private:
using value_type = XRPAmount;
value_type const current_; // The current setting
value_type const target_; // The setting we want
std::map<value_type, int> voteMap_;
ValueType const current_; // The current setting
ValueType const target_; // The setting we want
std::map<ValueType, int> voteMap_;
public:
VotableValue(value_type current, value_type target) : current_(current), target_(target)
VotableValue(ValueType current, ValueType target) : current_(current), target_(target)
{
// Add our vote
++voteMap_[target_];
}
void
addVote(value_type vote)
addVote(ValueType vote)
{
++voteMap_[vote];
}
@@ -59,20 +59,21 @@ public:
addVote(current_);
}
[[nodiscard]] value_type
[[nodiscard]] ValueType
current() const
{
return current_;
}
[[nodiscard]] std::pair<value_type, bool>
[[nodiscard]] std::pair<ValueType, bool>
getVotes() const;
};
auto
VotableValue::getVotes() const -> std::pair<value_type, bool>
template <typename ValueType>
std::pair<ValueType, bool>
VotableValue<ValueType>::getVotes() const
{
value_type ourVote = current_;
ValueType ourVote = current_;
int weight = 0;
for (auto const& [key, val] : voteMap_)
{
@@ -124,17 +125,16 @@ FeeVoteImpl::doValidation(Fees const& lastFees, Rules const& rules, STValidation
// Values should always be in a valid range (because the voting process
// will ignore out-of-range values) but if we detect such a case, we do
// not send a value.
auto vote = [&v, this](auto const current, auto target, char const* name, auto const& sfield) {
if (current != target)
{
JLOG(journal_.info()) << "Voting for " << name << " of " << target;
v[sfield] = target;
}
};
if (rules.enabled(featureXRPFees))
{
auto vote =
[&v, this](auto const current, XRPAmount target, char const* name, auto const& sfield) {
if (current != target)
{
JLOG(journal_.info()) << "Voting for " << name << " of " << target;
v[sfield] = target;
}
};
vote(lastFees.base, target_.reference_fee, "base fee", sfBaseFeeDrops);
vote(lastFees.reserve, target_.account_reserve, "base reserve", sfReserveBaseDrops);
vote(
@@ -147,12 +147,12 @@ FeeVoteImpl::doValidation(Fees const& lastFees, Rules const& rules, STValidation
{
auto to32 = [](XRPAmount target) { return target.dropsAs<std::uint32_t>(); };
auto to64 = [](XRPAmount target) { return target.dropsAs<std::uint64_t>(); };
auto vote = [&v, this](
auto const current,
XRPAmount target,
auto const& convertCallback,
char const* name,
auto const& sfield) {
auto voteAndConvert = [&v, this](
auto const current,
XRPAmount target,
auto const& convertCallback,
char const* name,
auto const& sfield) {
if (current != target)
{
JLOG(journal_.info()) << "Voting for " << name << " of " << target;
@@ -162,15 +162,32 @@ FeeVoteImpl::doValidation(Fees const& lastFees, Rules const& rules, STValidation
}
};
vote(lastFees.base, target_.reference_fee, to64, "base fee", sfBaseFee);
vote(lastFees.reserve, target_.account_reserve, to32, "base reserve", sfReserveBase);
vote(
voteAndConvert(lastFees.base, target_.reference_fee, to64, "base fee", sfBaseFee);
voteAndConvert(
lastFees.reserve, target_.account_reserve, to32, "base reserve", sfReserveBase);
voteAndConvert(
lastFees.increment,
target_.owner_reserve,
to32,
"reserve increment",
sfReserveIncrement);
}
if (rules.enabled(featureSmartEscrow))
{
if (target_.gas_limit <= kMaxGasLimit)
{
vote(lastFees.gasLimit, target_.gas_limit, "gas limit", sfGasLimit);
}
if (target_.bytecode_size_limit <= kMaxBytecodeSizeLimit)
{
vote(
lastFees.bytecodeSizeLimit,
target_.bytecode_size_limit,
"bytecode size limit",
sfBytecodeSizeLimit);
}
vote(lastFees.gasPrice, target_.gas_price, "gas price", sfGasPrice);
}
}
void
@@ -190,11 +207,28 @@ FeeVoteImpl::doVoting(
detail::VotableValue incReserveVote(lastClosedLedger->fees().increment, target_.owner_reserve);
auto validOrCurrent = [](std::uint32_t target, std::uint32_t max, std::uint32_t current) {
return target <= max ? target : current;
};
detail::VotableValue gasLimitVote(
lastClosedLedger->fees().gasLimit,
validOrCurrent(target_.gas_limit, kMaxGasLimit, lastClosedLedger->fees().gasLimit));
detail::VotableValue bytecodeSizeLimitVote(
lastClosedLedger->fees().bytecodeSizeLimit,
validOrCurrent(
target_.bytecode_size_limit,
kMaxBytecodeSizeLimit,
lastClosedLedger->fees().bytecodeSizeLimit));
detail::VotableValue gasPriceVote(lastClosedLedger->fees().gasPrice, target_.gas_price);
auto const& rules = lastClosedLedger->rules();
if (rules.enabled(featureXRPFees))
{
auto doVote = [](std::shared_ptr<STValidation> const& val,
detail::VotableValue& value,
detail::VotableValue<XRPAmount>& value,
SF_AMOUNT const& xrpField) {
if (auto const field = ~val->at(~xrpField); field && field->native())
{
@@ -226,7 +260,7 @@ FeeVoteImpl::doVoting(
else
{
auto doVote = [](std::shared_ptr<STValidation> const& val,
detail::VotableValue& value,
detail::VotableValue<XRPAmount>& value,
auto const& valueField) {
if (auto const field = val->at(~valueField))
{
@@ -260,6 +294,38 @@ FeeVoteImpl::doVoting(
doVote(val, incReserveVote, sfReserveIncrement);
}
}
if (rules.enabled(featureSmartEscrow))
{
auto doVote = [](std::shared_ptr<STValidation> const& val,
detail::VotableValue<std::uint32_t>& value,
SF_UINT32 const& sfield,
std::uint32_t maxValue) {
if (auto const field = ~val->at(~sfield); field)
{
if (field.value() <= maxValue)
{
value.addVote(field.value());
}
else
{
value.noVote();
}
}
else
{
value.noVote();
}
};
for (auto const& val : set)
{
if (!val->isTrusted())
continue;
doVote(val, gasLimitVote, sfGasLimit, kMaxGasLimit);
doVote(val, bytecodeSizeLimitVote, sfBytecodeSizeLimit, kMaxBytecodeSizeLimit);
doVote(val, gasPriceVote, sfGasPrice, std::numeric_limits<std::uint32_t>::max());
}
}
// choose our positions
// TODO: Use structured binding once LLVM 16 is the minimum supported
@@ -268,11 +334,15 @@ FeeVoteImpl::doVoting(
auto const baseFee = baseFeeVote.getVotes();
auto const baseReserve = baseReserveVote.getVotes();
auto const incReserve = incReserveVote.getVotes();
auto const gasLimit = gasLimitVote.getVotes();
auto const bytecodeSizeLimit = bytecodeSizeLimitVote.getVotes();
auto const gasPrice = gasPriceVote.getVotes();
auto const seq = lastClosedLedger->header().seq + 1;
// add transactions to our position
if (baseFee.second || baseReserve.second || incReserve.second)
if (baseFee.second || baseReserve.second || incReserve.second || gasLimit.second ||
bytecodeSizeLimit.second || gasPrice.second)
{
JLOG(journal_.warn()) << "We are voting for a fee change: " << baseFee.first << "/"
<< baseReserve.first << "/" << incReserve.first;
@@ -297,6 +367,12 @@ FeeVoteImpl::doVoting(
incReserve.first.dropsAs<std::uint32_t>(incReserveVote.current());
obj[sfReferenceFeeUnits] = kFeeUnitsDeprecated;
}
if (rules.enabled(featureSmartEscrow))
{
obj[sfGasLimit] = gasLimit.first;
obj[sfBytecodeSizeLimit] = bytecodeSizeLimit.first;
obj[sfGasPrice] = gasPrice.first;
}
});
uint256 const txID = feeTx.getTransactionID();

View File

@@ -2429,6 +2429,15 @@ NetworkOPsImp::pubValidation(std::shared_ptr<STValidation> const& val)
reserveIncXRP && reserveIncXRP->native())
jvObj[jss::reserve_inc] = reserveIncXRP->xrp().jsonClipped();
if (auto const gasLimit = ~val->at(~sfGasLimit); gasLimit)
jvObj[jss::gas_limit] = *gasLimit;
if (auto const bytecodeSizeLimit = ~val->at(~sfBytecodeSizeLimit); bytecodeSizeLimit)
jvObj[jss::bytecode_size_limit] = *bytecodeSizeLimit;
if (auto const gasPrice = ~val->at(~sfGasPrice); gasPrice)
jvObj[jss::gas_price] = *gasPrice;
// NOTE Use MultiApiJson to publish two slightly different JSON objects
// for consumers supporting different API versions
MultiApiJson multiObj{jvObj};
@@ -2877,11 +2886,18 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
l[jss::seq] = json::UInt(lpClosed->header().seq);
l[jss::hash] = to_string(lpClosed->header().hash);
bool const smartEscrowEnabled = lpClosed->rules().enabled(featureSmartEscrow);
if (!human)
{
l[jss::base_fee] = baseFee.jsonClipped();
l[jss::reserve_base] = lpClosed->fees().reserve.jsonClipped();
l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
if (smartEscrowEnabled)
{
l[jss::gas_limit] = lpClosed->fees().gasLimit;
l[jss::bytecode_size_limit] = lpClosed->fees().bytecodeSizeLimit;
l[jss::gas_price] = lpClosed->fees().gasPrice;
}
l[jss::close_time] =
json::Value::UInt(lpClosed->header().closeTime.time_since_epoch().count());
}
@@ -2890,6 +2906,12 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
l[jss::base_fee_xrp] = baseFee.decimalXRP();
l[jss::reserve_base_xrp] = lpClosed->fees().reserve.decimalXRP();
l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
if (smartEscrowEnabled)
{
l[jss::gas_limit] = lpClosed->fees().gasLimit;
l[jss::bytecode_size_limit] = lpClosed->fees().bytecodeSizeLimit;
l[jss::gas_price] = lpClosed->fees().gasPrice;
}
if (auto const closeOffset = registry_.get().getTimeKeeper().closeOffset();
std::abs(closeOffset.count()) >= 60)
@@ -3085,6 +3107,12 @@ NetworkOPsImp::pubLedger(std::shared_ptr<ReadView const> const& lpAccepted)
jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
jvObj[jss::reserve_base] = lpAccepted->fees().reserve.jsonClipped();
jvObj[jss::reserve_inc] = lpAccepted->fees().increment.jsonClipped();
if (lpAccepted->rules().enabled(featureSmartEscrow))
{
jvObj[jss::gas_limit] = lpAccepted->fees().gasLimit;
jvObj[jss::bytecode_size_limit] = lpAccepted->fees().bytecodeSizeLimit;
jvObj[jss::gas_price] = lpAccepted->fees().gasPrice;
}
jvObj[jss::txn_count] = json::UInt(alpAccepted->size());
@@ -4065,6 +4093,12 @@ NetworkOPsImp::subLedger(InfoSub::ref isrListener, json::Value& jvResult)
jvResult[jss::reserve_base] = lpClosed->fees().reserve.jsonClipped();
jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
jvResult[jss::network_id] = registry_.get().getNetworkIDService().getNetworkID();
if (lpClosed->rules().enabled(featureSmartEscrow))
{
jvResult[jss::gas_limit] = lpClosed->fees().gasLimit;
jvResult[jss::bytecode_size_limit] = lpClosed->fees().bytecodeSizeLimit;
jvResult[jss::gas_price] = lpClosed->fees().gasPrice;
}
}
if ((mode_ >= OperatingMode::SYNCING) && !isNeedNetworkLedger())

View File

@@ -56,6 +56,15 @@ struct FeeSetup
/** The per-owned item reserve requirement in drops. */
XRPAmount owner_reserve{2 * kDropsPerXrp};
/** The gas limit for Feature Extensions. */
std::uint32_t gas_limit{1'000'000};
/** The bytecode size limit for Feature Extensions. */
std::uint32_t bytecode_size_limit{100'000};
/** The price of 1 WASM gas, in micro-drops. */
std::uint32_t gas_price{1'000'000};
/* (Remember to update the example cfg files when changing any of these
* values.) */

View File

@@ -13,6 +13,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/net/HTTPClient.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/DatabaseCon.h>
@@ -1194,6 +1195,12 @@ setupFeeVote(Section const& section)
setup.account_reserve = temp;
if (set(temp, "owner_reserve", section))
setup.owner_reserve = temp;
if (set(temp, "gas_limit", section) && temp <= kMaxGasLimit)
setup.gas_limit = temp;
if (set(temp, "bytecode_size_limit", section) && temp <= kMaxBytecodeSizeLimit)
setup.bytecode_size_limit = temp;
if (set(temp, "gas_price", section))
setup.gas_price = temp;
}
return setup;
}