mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-06 20:12:31 +00:00
Compare commits
26 Commits
xrplf/smar
...
3.2.0-b3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6a09a4d2c | ||
|
|
3adad49c86 | ||
|
|
f04943fc50 | ||
|
|
ab7f683b2f | ||
|
|
14749fdfb0 | ||
|
|
c6ddf6aa1c | ||
|
|
ee3a08c8d4 | ||
|
|
2dc705bd99 | ||
|
|
7315c57edc | ||
|
|
5a66086fce | ||
|
|
682dda8bfc | ||
|
|
aac17f588a | ||
|
|
cbc09b2999 | ||
|
|
453d94da17 | ||
|
|
b36aedb4d5 | ||
|
|
18540c97a5 | ||
|
|
8e3d87fce3 | ||
|
|
b83dc9aa16 | ||
|
|
0c76bf991a | ||
|
|
29aba28f5b | ||
|
|
b3f14c4052 | ||
|
|
e26624dcd1 | ||
|
|
885f7b8c33 | ||
|
|
dcf973bc50 | ||
|
|
68596f60d8 | ||
|
|
aac64d3b85 |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,2 +0,0 @@
|
||||
# Allow anyone to review any change by default.
|
||||
*
|
||||
8
.github/scripts/rename/copyright.sh
vendored
8
.github/scripts/rename/copyright.sh
vendored
@@ -76,11 +76,11 @@ fi
|
||||
if ! grep -q 'Dev Null' src/test/rpc/ValidatorInfo_test.cpp; then
|
||||
echo -e "// Copyright (c) 2020 Dev Null Productions\n\n$(cat src/test/rpc/ValidatorInfo_test.cpp)" > src/test/rpc/ValidatorInfo_test.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/server_info/Manifest.cpp; then
|
||||
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/server_info/Manifest.cpp)" > src/xrpld/rpc/handlers/server_info/Manifest.cpp
|
||||
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/DoManifest.cpp; then
|
||||
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/DoManifest.cpp)" > src/xrpld/rpc/handlers/DoManifest.cpp
|
||||
fi
|
||||
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/admin/status/ValidatorInfo.cpp; then
|
||||
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/admin/status/ValidatorInfo.cpp)" > src/xrpld/rpc/handlers/admin/status/ValidatorInfo.cpp
|
||||
if ! grep -q 'Dev Null' src/xrpld/rpc/handlers/ValidatorInfo.cpp; then
|
||||
echo -e "// Copyright (c) 2019 Dev Null Productions\n\n$(cat src/xrpld/rpc/handlers/ValidatorInfo.cpp)" > src/xrpld/rpc/handlers/ValidatorInfo.cpp
|
||||
fi
|
||||
if ! grep -q 'Bougalis' include/xrpl/basics/SlabAllocator.h; then
|
||||
echo -e "// Copyright (c) 2022, Nikolaos D. Bougalis <nikb@bougalis.net>\n\n$(cat include/xrpl/basics/SlabAllocator.h)" > include/xrpl/basics/SlabAllocator.h # cspell: ignore Nikolaos Bougalis nikb
|
||||
|
||||
2
.github/workflows/check-pr-commits.yml
vendored
2
.github/workflows/check-pr-commits.yml
vendored
@@ -10,4 +10,4 @@ permissions:
|
||||
|
||||
jobs:
|
||||
check_commits:
|
||||
uses: XRPLF/actions/.github/workflows/check-pr-commits.yml@e2c7f400d1e85ae65dad552fd425169fbacca4a3
|
||||
uses: XRPLF/actions/.github/workflows/check-pr-commits.yml@481048b78b94ac3343d1292b4ef125a813879f2b
|
||||
|
||||
2
.github/workflows/check-pr-title.yml
vendored
2
.github/workflows/check-pr-title.yml
vendored
@@ -11,4 +11,4 @@ on:
|
||||
jobs:
|
||||
check_title:
|
||||
if: ${{ github.event.pull_request.draft != true }}
|
||||
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@a5d8dd35be543365e90a11358447130c8763871d
|
||||
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@e2c7f400d1e85ae65dad552fd425169fbacca4a3
|
||||
|
||||
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
jobs:
|
||||
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
|
||||
run-hooks:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@9307df762265e15c745ddcdb38a581c989f7f349
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@e7896f15cc60d0da1a272c77ee5c4026b424f9c7
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }'
|
||||
|
||||
2
.github/workflows/publish-docs.yml
vendored
2
.github/workflows/publish-docs.yml
vendored
@@ -47,7 +47,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
|
||||
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
|
||||
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e
|
||||
with:
|
||||
enable_ccache: ${{ inputs.ccache_enabled }}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
|
||||
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
2
.github/workflows/upload-conan-deps.yml
vendored
2
.github/workflows/upload-conan-deps.yml
vendored
@@ -70,7 +70,7 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Prepare runner
|
||||
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
|
||||
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e
|
||||
with:
|
||||
enable_ccache: false
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ find_package(OpenSSL REQUIRED)
|
||||
find_package(secp256k1 REQUIRED)
|
||||
find_package(SOCI REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
find_package(wasmi REQUIRED)
|
||||
find_package(xxHash REQUIRED)
|
||||
|
||||
target_link_libraries(
|
||||
|
||||
@@ -1272,39 +1272,6 @@
|
||||
# Example:
|
||||
# owner_reserve = 2000000 # 2 XRP
|
||||
#
|
||||
# extension_compute_limit = <gas>
|
||||
#
|
||||
# The extension compute 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:
|
||||
# extension_compute_limit = 1000000 # 1 million gas
|
||||
#
|
||||
# extension_size_limit = <bytes>
|
||||
#
|
||||
# The extension 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:
|
||||
# extension_size_limit = 100000 # 100 kb
|
||||
#
|
||||
# gas_price = <bytes>
|
||||
#
|
||||
# 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
|
||||
|
||||
@@ -67,7 +67,6 @@ target_link_libraries(
|
||||
Xrpl::opts
|
||||
Xrpl::syslibs
|
||||
secp256k1::secp256k1
|
||||
wasmi::wasmi
|
||||
xrpl.libpb
|
||||
xxHash::xxhash
|
||||
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"requires": [
|
||||
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
|
||||
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
|
||||
"wasmi/1.0.6#407c9db14601a8af1c7dd3b388f3e4cd%1768164779.349",
|
||||
"sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1774467355.988",
|
||||
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
|
||||
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
|
||||
|
||||
@@ -35,7 +35,6 @@ class Xrpl(ConanFile):
|
||||
"openssl/3.6.1",
|
||||
"secp256k1/0.7.1",
|
||||
"soci/4.0.3",
|
||||
"wasmi/1.0.6",
|
||||
"zlib/1.3.1",
|
||||
]
|
||||
|
||||
@@ -221,7 +220,6 @@ class Xrpl(ConanFile):
|
||||
"soci::soci",
|
||||
"secp256k1::secp256k1",
|
||||
"sqlite3::sqlite",
|
||||
"wasmi::wasmi",
|
||||
"xxhash::xxhash",
|
||||
"zlib::zlib",
|
||||
]
|
||||
|
||||
@@ -7,8 +7,6 @@ ignorePaths:
|
||||
- cmake/**
|
||||
- LICENSE.md
|
||||
- .clang-tidy
|
||||
- src/test/app/wasm_fixtures/**/*.wat
|
||||
- src/test/app/wasm_fixtures/*.c
|
||||
language: en
|
||||
allowCompoundWords: true # TODO (#6334)
|
||||
ignoreRandomStrings: true
|
||||
@@ -62,7 +60,6 @@ words:
|
||||
- Britto
|
||||
- Btrfs
|
||||
- canonicality
|
||||
- cdylib
|
||||
- changespq
|
||||
- checkme
|
||||
- choco
|
||||
@@ -99,7 +96,6 @@ words:
|
||||
- distro
|
||||
- doxyfile
|
||||
- dxrpl
|
||||
- emittance
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- Falco
|
||||
@@ -249,7 +245,6 @@ words:
|
||||
- statsd
|
||||
- STATSDCOLLECTOR
|
||||
- stissue
|
||||
- stjson
|
||||
- stnum
|
||||
- stobj
|
||||
- stobject
|
||||
|
||||
@@ -729,10 +729,6 @@ abs(Number x) noexcept
|
||||
Number
|
||||
power(Number const& f, unsigned n);
|
||||
|
||||
// logarithm with base 10
|
||||
Number
|
||||
log10(Number const& value, int iterations = 50);
|
||||
|
||||
// Returns f^(1/d)
|
||||
// Uses Newton–Raphson iterations until the result stops changing
|
||||
// to find the root of the polynomial g(x) = x^d - f
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <xrpl/basics/Blob.h>
|
||||
#include <xrpl/basics/SHAMapHash.h>
|
||||
#include <xrpl/basics/TaggedCache.h>
|
||||
#include <xrpl/protocol/Fees.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
@@ -239,9 +238,6 @@ public:
|
||||
virtual DatabaseCon&
|
||||
getWalletDB() = 0;
|
||||
|
||||
virtual Fees
|
||||
getFees() const = 0;
|
||||
|
||||
// Temporary: Get the underlying Application for functions that haven't
|
||||
// been migrated yet. This should be removed once all code is migrated.
|
||||
virtual Application&
|
||||
|
||||
@@ -54,18 +54,6 @@ public:
|
||||
deliver_ = amount;
|
||||
}
|
||||
|
||||
void
|
||||
setGasUsed(std::optional<std::uint32_t> const gasUsed)
|
||||
{
|
||||
gasUsed_ = gasUsed;
|
||||
}
|
||||
|
||||
void
|
||||
setWasmReturnCode(std::int32_t const wasmReturnCode)
|
||||
{
|
||||
wasmReturnCode_ = wasmReturnCode;
|
||||
}
|
||||
|
||||
/** Get the number of modified entries
|
||||
*/
|
||||
std::size_t
|
||||
@@ -84,8 +72,6 @@ public:
|
||||
|
||||
private:
|
||||
std::optional<STAmount> deliver_;
|
||||
std::optional<std::uint32_t> gasUsed_;
|
||||
std::optional<std::int32_t> wasmReturnCode_;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class OpenViewSandbox
|
||||
{
|
||||
private:
|
||||
OpenView& parent_;
|
||||
std::unique_ptr<OpenView> sandbox_;
|
||||
|
||||
public:
|
||||
using key_type = ReadView::key_type;
|
||||
|
||||
OpenViewSandbox(OpenView& parent)
|
||||
: parent_(parent), sandbox_(std::make_unique<OpenView>(batch_view, parent))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
rawErase(std::shared_ptr<SLE> const& sle)
|
||||
{
|
||||
sandbox_->rawErase(sle);
|
||||
}
|
||||
|
||||
void
|
||||
rawInsert(std::shared_ptr<SLE> const& sle)
|
||||
{
|
||||
sandbox_->rawInsert(sle);
|
||||
}
|
||||
|
||||
void
|
||||
rawReplace(std::shared_ptr<SLE> const& sle)
|
||||
{
|
||||
sandbox_->rawReplace(sle);
|
||||
}
|
||||
|
||||
void
|
||||
rawDestroyXRP(XRPAmount const& fee)
|
||||
{
|
||||
sandbox_->rawDestroyXRP(fee);
|
||||
}
|
||||
|
||||
void
|
||||
rawTxInsert(
|
||||
key_type const& key,
|
||||
std::shared_ptr<Serializer const> const& txn,
|
||||
std::shared_ptr<Serializer const> const& metaData)
|
||||
{
|
||||
sandbox_->rawTxInsert(key, txn, metaData);
|
||||
}
|
||||
|
||||
void
|
||||
commit()
|
||||
{
|
||||
sandbox_->apply(parent_);
|
||||
sandbox_ = std::make_unique<OpenView>(batch_view, parent_);
|
||||
}
|
||||
|
||||
void
|
||||
discard()
|
||||
{
|
||||
sandbox_ = std::make_unique<OpenView>(batch_view, parent_);
|
||||
}
|
||||
|
||||
OpenView const&
|
||||
view() const
|
||||
{
|
||||
return *sandbox_;
|
||||
}
|
||||
|
||||
OpenView&
|
||||
view()
|
||||
{
|
||||
return *sandbox_;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -3,10 +3,6 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/MPTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/OfferHelpers.h>
|
||||
#include <xrpl/ledger/helpers/RippleStateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/TokenHelpers.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -215,27 +211,6 @@ doWithdraw(
|
||||
STAmount const& amount,
|
||||
beast::Journal j);
|
||||
|
||||
enum class SendIssuerHandling { ihSENDER_NOT_ALLOWED, ihRECEIVER_NOT_ALLOWED, ihIGNORE };
|
||||
enum class SendEscrowHandling { ehIGNORE, ehCHECK };
|
||||
enum class SendAuthHandling { ahCHECK_SENDER, ahCHECK_RECEIVER, ahBOTH, ahNEITHER };
|
||||
enum class SendFreezeHandling { fhCHECK_SENDER, fhCHECK_RECEIVER, fhBOTH, fhNEITHER };
|
||||
enum class SendTransferHandling { thIGNORE, thCHECK };
|
||||
enum class SendBalanceHandling { bhIGNORE, bhCHECK };
|
||||
|
||||
TER
|
||||
canTransferFT(
|
||||
ReadView const& view,
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
STAmount const& amount,
|
||||
beast::Journal j,
|
||||
SendIssuerHandling issuerHandling,
|
||||
SendEscrowHandling escrowHandling,
|
||||
SendAuthHandling authHandling,
|
||||
SendFreezeHandling freezeHandling,
|
||||
SendTransferHandling transferHandling,
|
||||
SendBalanceHandling balanceHandling);
|
||||
|
||||
/** Deleter function prototype. Returns the status of the entry deletion
|
||||
* (if should not be skipped) and if the entry should be skipped. The status
|
||||
* is always tesSUCCESS if the entry should be skipped.
|
||||
|
||||
@@ -52,8 +52,6 @@ public:
|
||||
TER ter,
|
||||
std::optional<STAmount> const& deliver,
|
||||
std::optional<uint256 const> const& parentBatchId,
|
||||
std::optional<std::uint32_t> const& gasUsed,
|
||||
std::optional<std::int32_t> const& wasmReturnCode,
|
||||
bool isDryRun,
|
||||
beast::Journal j);
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractDataMap : public std::map<xrpl::AccountID, std::pair<bool, STJson>>
|
||||
{
|
||||
public:
|
||||
uint32_t modifiedCount = 0;
|
||||
};
|
||||
|
||||
class ContractEventMap : public std::map<std::string, STJson>
|
||||
{
|
||||
};
|
||||
|
||||
namespace contract {
|
||||
|
||||
/** The maximum number of data modifications in a single function. */
|
||||
int64_t constexpr maxDataModifications = 1000;
|
||||
|
||||
/** The maximum number of bytes the data can occupy. */
|
||||
int64_t constexpr maxContractDataSize = 1024;
|
||||
|
||||
/** The multiplier for contract data size calculations. */
|
||||
int64_t constexpr dataByteMultiplier = 512;
|
||||
|
||||
/** The cost multiplier of creating a contract in bytes. */
|
||||
int64_t constexpr createByteMultiplier = 500ULL;
|
||||
|
||||
/** The value to return when the fee calculation failed. */
|
||||
int64_t constexpr feeCalculationFailed = 0x7FFFFFFFFFFFFFFFLL;
|
||||
|
||||
/** The maximum number of contract parameters that can be in a transaction. */
|
||||
std::size_t constexpr maxContractParams = 8;
|
||||
|
||||
/** The maximum number of contract functions that can be in a transaction. */
|
||||
std::size_t constexpr maxContractFunctions = 8;
|
||||
|
||||
int64_t
|
||||
contractCreateFee(uint64_t byteCount);
|
||||
|
||||
NotTEC
|
||||
preflightFunctions(STTx const& tx, beast::Journal j);
|
||||
|
||||
NotTEC
|
||||
preflightInstanceParameters(STTx const& tx, beast::Journal j);
|
||||
|
||||
bool
|
||||
validateParameterMapping(STArray const& params, STArray const& values, beast::Journal j);
|
||||
|
||||
NotTEC
|
||||
preflightInstanceParameterValues(STTx const& tx, beast::Journal j);
|
||||
|
||||
NotTEC
|
||||
preflightFlagParameters(STArray const& parameters, beast::Journal j);
|
||||
|
||||
bool
|
||||
isValidParameterFlag(std::uint32_t flags);
|
||||
|
||||
TER
|
||||
preclaimFlagParameters(
|
||||
ReadView const& view,
|
||||
AccountID const& sourceAccount,
|
||||
AccountID const& contractAccount,
|
||||
STArray const& parameters,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
doApplyFlagParameters(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& sourceAccount,
|
||||
AccountID const& contractAccount,
|
||||
STArray const& parameters,
|
||||
XRPAmount const& priorBalance,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
finalizeContractData(
|
||||
ServiceRegistry& registry,
|
||||
ApplyView& view,
|
||||
AccountID const& contractAccount,
|
||||
ContractDataMap const& dataMap,
|
||||
ContractEventMap const& eventMap,
|
||||
uint256 const& txnID);
|
||||
|
||||
} // namespace contract
|
||||
} // namespace xrpl
|
||||
@@ -1,78 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/Rules.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFormats.h>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace xrpl {
|
||||
/**
|
||||
* We have both transaction type emitables and granular type emitables.
|
||||
* Since we will reuse the TransactionFormats to parse the Transaction
|
||||
* Emitables, only the GranularEmitableType is defined here. To prevent
|
||||
* conflicts with TxType, the GranularEmitableType is always set to a value
|
||||
* greater than the maximum value of uint16.
|
||||
*/
|
||||
enum GranularEmitableType : std::uint32_t {
|
||||
#pragma push_macro("EMITABLE")
|
||||
#undef EMITABLE
|
||||
|
||||
#define EMITABLE(type, txType, value) type = value,
|
||||
|
||||
#include <xrpl/protocol/detail/emitable.macro>
|
||||
|
||||
#undef EMITABLE
|
||||
#pragma pop_macro("EMITABLE")
|
||||
};
|
||||
|
||||
enum Emittance { emitable, notEmitable };
|
||||
|
||||
class Emitable
|
||||
{
|
||||
private:
|
||||
Emitable();
|
||||
|
||||
std::unordered_map<std::uint16_t, Emittance> emitableTx_;
|
||||
|
||||
std::unordered_map<std::string, GranularEmitableType> granularEmitableMap_;
|
||||
|
||||
std::unordered_map<GranularEmitableType, std::string> granularNameMap_;
|
||||
|
||||
std::unordered_map<GranularEmitableType, TxType> granularTxTypeMap_;
|
||||
|
||||
public:
|
||||
static Emitable const&
|
||||
getInstance();
|
||||
|
||||
Emitable(Emitable const&) = delete;
|
||||
Emitable&
|
||||
operator=(Emitable const&) = delete;
|
||||
|
||||
std::optional<std::string>
|
||||
getEmitableName(std::uint32_t const value) const;
|
||||
|
||||
std::optional<std::uint32_t>
|
||||
getGranularValue(std::string const& name) const;
|
||||
|
||||
std::optional<std::string>
|
||||
getGranularName(GranularEmitableType const& value) const;
|
||||
|
||||
std::optional<TxType>
|
||||
getGranularTxType(GranularEmitableType const& gpType) const;
|
||||
|
||||
bool
|
||||
isEmitable(std::uint32_t const& emitableValue) const;
|
||||
|
||||
// for tx level emitable, emitable value is equal to tx type plus one
|
||||
uint32_t
|
||||
txToEmitableType(TxType const& type) const;
|
||||
|
||||
// tx type value is emitable value minus one
|
||||
TxType
|
||||
emitableToTxType(uint32_t const& value) const;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -8,9 +8,6 @@ namespace xrpl {
|
||||
// This was the reference fee units used in the old fee calculation.
|
||||
inline constexpr std::uint32_t FEE_UNITS_DEPRECATED = 10;
|
||||
|
||||
// Number of micro-drops in one drop.
|
||||
constexpr std::uint32_t MICRO_DROPS_PER_DROP{1'000'000};
|
||||
|
||||
/** Reflects the fee settings for a particular ledger.
|
||||
|
||||
The fees are always the same for any transactions applied
|
||||
@@ -27,15 +24,6 @@ struct Fees
|
||||
/** @brief Additional XRP reserve required per owned ledger object. */
|
||||
XRPAmount increment{0};
|
||||
|
||||
/** @brief Compute limit for Feature Extensions (instructions). */
|
||||
std::uint32_t extensionComputeLimit{0};
|
||||
|
||||
/** @brief Size limit for Feature Extensions (bytes). */
|
||||
std::uint32_t extensionSizeLimit{0};
|
||||
|
||||
/** @brief Price of WASM gas (micro-drops). */
|
||||
std::uint32_t gasPrice{0};
|
||||
|
||||
explicit Fees() = default;
|
||||
Fees(Fees const&) = default;
|
||||
Fees&
|
||||
|
||||
@@ -207,12 +207,6 @@ page(Keylet const& root, std::uint64_t index = 0) noexcept
|
||||
Keylet
|
||||
escrow(AccountID const& src, std::uint32_t seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
escrow(uint256 const& key) noexcept
|
||||
{
|
||||
return {ltESCROW, key};
|
||||
}
|
||||
|
||||
/** A PaymentChannel */
|
||||
Keylet
|
||||
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept;
|
||||
@@ -348,22 +342,6 @@ permissionedDomain(AccountID const& account, std::uint32_t seq) noexcept;
|
||||
|
||||
Keylet
|
||||
permissionedDomain(uint256 const& domainID) noexcept;
|
||||
|
||||
Keylet
|
||||
contractSource(uint256 const& contractHash) noexcept;
|
||||
|
||||
Keylet
|
||||
contract(uint256 const& contractHash, AccountID const& owner, std::uint32_t seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
contract(uint256 const& contractID)
|
||||
{
|
||||
return {ltCONTRACT, contractID};
|
||||
}
|
||||
|
||||
Keylet
|
||||
contractData(AccountID const& owner, AccountID const& contractAccount) noexcept;
|
||||
|
||||
} // namespace keylet
|
||||
|
||||
// Everything below is deprecated and should be removed in favor of keylets:
|
||||
|
||||
@@ -74,6 +74,14 @@ enum LedgerEntryType : std::uint16_t {
|
||||
*/
|
||||
ltNICKNAME [[deprecated("This object type is not supported and should not be used.")]] = 0x006e,
|
||||
|
||||
/** A legacy, deprecated type.
|
||||
|
||||
\deprecated **This object type is not supported and should not be used.**
|
||||
Support for this type of object was never implemented.
|
||||
No objects of this type were ever created.
|
||||
*/
|
||||
ltCONTRACT [[deprecated("This object type is not supported and should not be used.")]] = 0x0063,
|
||||
|
||||
/** A legacy, deprecated type.
|
||||
|
||||
\deprecated **This object type is not supported and should not be used.**
|
||||
|
||||
@@ -251,12 +251,6 @@ std::uint8_t constexpr vaultMaximumIOUScale = 18;
|
||||
* another vault; counted from 0 */
|
||||
std::uint8_t constexpr maxAssetCheckDepth = 5;
|
||||
|
||||
/** Maximum length of a Data field in Escrow object that can be updated by WASM code. */
|
||||
std::size_t constexpr maxWasmDataLength = 4 * 1024; // 4KB
|
||||
|
||||
/** Maximum length of parameters passed from WASM code to host functions. */
|
||||
std::size_t constexpr maxWasmParamLength = 1024; // 1KB
|
||||
|
||||
/** A ledger index. */
|
||||
using LedgerIndex = std::uint32_t;
|
||||
|
||||
|
||||
@@ -33,9 +33,6 @@ class STNumber;
|
||||
class STXChainBridge;
|
||||
class STVector256;
|
||||
class STCurrency;
|
||||
class STData;
|
||||
class STDataType;
|
||||
class STJson;
|
||||
|
||||
#pragma push_macro("XMACRO")
|
||||
#undef XMACRO
|
||||
@@ -74,9 +71,6 @@ class STJson;
|
||||
STYPE(STI_ISSUE, 24) \
|
||||
STYPE(STI_XCHAIN_BRIDGE, 25) \
|
||||
STYPE(STI_CURRENCY, 26) \
|
||||
STYPE(STI_DATA, 27) \
|
||||
STYPE(STI_DATATYPE, 28) \
|
||||
STYPE(STI_JSON, 29) \
|
||||
\
|
||||
/* high-level types */ \
|
||||
/* cannot be serialized inside other types */ \
|
||||
@@ -356,9 +350,6 @@ using SF_NUMBER = TypedField<STNumber>;
|
||||
using SF_VL = TypedField<STBlob>;
|
||||
using SF_VECTOR256 = TypedField<STVector256>;
|
||||
using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
|
||||
using SF_DATA = TypedField<STData>;
|
||||
using SF_DATATYPE = TypedField<STDataType>;
|
||||
using SF_JSON = TypedField<STJson>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/detail/STVar.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STData final : public STBase
|
||||
{
|
||||
private:
|
||||
using data_type = detail::STVar;
|
||||
std::uint16_t inner_type_;
|
||||
data_type data_;
|
||||
bool default_{true};
|
||||
|
||||
public:
|
||||
using value_type = STData; // Although not directly holding a single value
|
||||
|
||||
STData(SField const& n);
|
||||
STData(SField const& n, unsigned char);
|
||||
STData(SField const& n, std::uint16_t);
|
||||
STData(SField const& n, std::uint32_t);
|
||||
STData(SField const& n, std::uint64_t);
|
||||
STData(SField const& n, uint128 const&);
|
||||
STData(SField const& n, uint160 const&);
|
||||
STData(SField const& n, uint192 const&);
|
||||
STData(SField const& n, uint256 const&);
|
||||
STData(SField const& n, Blob const&);
|
||||
STData(SField const& n, Slice const&);
|
||||
STData(SField const& n, AccountID const&);
|
||||
STData(SField const& n, STAmount const&);
|
||||
STData(SField const& n, STIssue const&);
|
||||
STData(SField const& n, STCurrency const&);
|
||||
STData(SField const& n, STNumber const&);
|
||||
|
||||
STData(SerialIter& sit, SField const& name);
|
||||
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getInnerTypeString() const;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(STBase const& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
SerializedTypeID
|
||||
getInnerSType() const noexcept;
|
||||
|
||||
STBase*
|
||||
makeFieldPresent();
|
||||
|
||||
void
|
||||
setFieldU8(unsigned char);
|
||||
void
|
||||
setFieldU16(std::uint16_t);
|
||||
void
|
||||
setFieldU32(std::uint32_t);
|
||||
void
|
||||
setFieldU64(std::uint64_t);
|
||||
void
|
||||
setFieldH128(uint128 const&);
|
||||
void
|
||||
setFieldH160(uint160 const&);
|
||||
void
|
||||
setFieldH192(uint192 const&);
|
||||
void
|
||||
setFieldH256(uint256 const&);
|
||||
void
|
||||
setFieldVL(Blob const&);
|
||||
void
|
||||
setFieldVL(Slice const&);
|
||||
void
|
||||
setAccountID(AccountID const&);
|
||||
void
|
||||
setFieldAmount(STAmount const&);
|
||||
void
|
||||
setIssue(STIssue const&);
|
||||
void
|
||||
setCurrency(STCurrency const&);
|
||||
void
|
||||
setFieldNumber(STNumber const&);
|
||||
|
||||
unsigned char
|
||||
getFieldU8() const;
|
||||
std::uint16_t
|
||||
getFieldU16() const;
|
||||
std::uint32_t
|
||||
getFieldU32() const;
|
||||
std::uint64_t
|
||||
getFieldU64() const;
|
||||
uint128
|
||||
getFieldH128() const;
|
||||
uint160
|
||||
getFieldH160() const;
|
||||
uint192
|
||||
getFieldH192() const;
|
||||
uint256
|
||||
getFieldH256() const;
|
||||
Blob
|
||||
getFieldVL() const;
|
||||
AccountID
|
||||
getAccountID() const;
|
||||
STAmount const&
|
||||
getFieldAmount() const;
|
||||
STIssue
|
||||
getFieldIssue() const;
|
||||
STCurrency
|
||||
getFieldCurrency() const;
|
||||
STNumber
|
||||
getFieldNumber() const;
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
|
||||
// Implementation for getting (most) fields that return by value.
|
||||
//
|
||||
// The remove_cv and remove_reference are necessitated by the STBitString
|
||||
// types. Their value() returns by const ref. We return those types
|
||||
// by value.
|
||||
template <
|
||||
typename T,
|
||||
typename V = typename std::remove_cv<
|
||||
typename std::remove_reference<decltype(std::declval<T>().value())>::type>::type>
|
||||
V
|
||||
getFieldByValue() const;
|
||||
|
||||
// Implementations for getting (most) fields that return by const reference.
|
||||
//
|
||||
// If an absent optional field is deserialized we don't have anything
|
||||
// obvious to return. So we insist on having the call provide an
|
||||
// 'empty' value we return in that circumstance.
|
||||
template <typename T, typename V>
|
||||
V const&
|
||||
getFieldByConstRef(V const& empty) const;
|
||||
|
||||
// Implementation for setting most fields with a setValue() method.
|
||||
template <typename T, typename V>
|
||||
void
|
||||
setFieldUsingSetValue(V value);
|
||||
|
||||
// Implementation for setting fields using assignment
|
||||
template <typename T>
|
||||
void
|
||||
setFieldUsingAssignment(T const& value);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Implementation
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline SerializedTypeID
|
||||
STData::getInnerSType() const noexcept
|
||||
{
|
||||
return static_cast<SerializedTypeID>(inner_type_);
|
||||
}
|
||||
|
||||
template <typename T, typename V>
|
||||
V
|
||||
STData::getFieldByValue() const
|
||||
{
|
||||
STBase const* rf = &data_.get();
|
||||
|
||||
// if (!rf)
|
||||
// throwFieldNotFound(getFName());
|
||||
|
||||
SerializedTypeID id = rf->getSType();
|
||||
|
||||
if (id == STI_NOTPRESENT)
|
||||
Throw<std::runtime_error>("Field not present");
|
||||
|
||||
T const* cf = dynamic_cast<T const*>(rf);
|
||||
|
||||
if (!cf)
|
||||
Throw<std::runtime_error>("Wrong field type");
|
||||
|
||||
return cf->value();
|
||||
}
|
||||
|
||||
// Implementations for getting (most) fields that return by const reference.
|
||||
//
|
||||
// If an absent optional field is deserialized we don't have anything
|
||||
// obvious to return. So we insist on having the call provide an
|
||||
// 'empty' value we return in that circumstance.
|
||||
template <typename T, typename V>
|
||||
V const&
|
||||
STData::getFieldByConstRef(V const& empty) const
|
||||
{
|
||||
STBase const* rf = &data_.get();
|
||||
|
||||
// if (!rf)
|
||||
// throwFieldNotFound(field);
|
||||
|
||||
SerializedTypeID id = rf->getSType();
|
||||
|
||||
if (id == STI_NOTPRESENT)
|
||||
return empty; // optional field not present
|
||||
|
||||
T const* cf = dynamic_cast<T const*>(rf);
|
||||
|
||||
if (!cf)
|
||||
Throw<std::runtime_error>("Wrong field type");
|
||||
|
||||
return *cf;
|
||||
}
|
||||
|
||||
// Implementation for setting most fields with a setValue() method.
|
||||
template <typename T, typename V>
|
||||
void
|
||||
STData::setFieldUsingSetValue(V value)
|
||||
{
|
||||
static_assert(!std::is_lvalue_reference<V>::value, "");
|
||||
|
||||
STBase* rf = &data_.get();
|
||||
|
||||
// if (!rf)
|
||||
// throwFieldNotFound(field);
|
||||
|
||||
if (rf->getSType() == STI_NOTPRESENT)
|
||||
rf = makeFieldPresent();
|
||||
|
||||
T* cf = dynamic_cast<T*>(rf);
|
||||
|
||||
if (!cf)
|
||||
Throw<std::runtime_error>("Wrong field type");
|
||||
|
||||
cf->setValue(std::move(value));
|
||||
}
|
||||
|
||||
// Implementation for setting fields using assignment
|
||||
template <typename T>
|
||||
void
|
||||
STData::setFieldUsingAssignment(T const& value)
|
||||
{
|
||||
STBase* rf = &data_.get();
|
||||
|
||||
// if (!rf)
|
||||
// throwFieldNotFound(field);
|
||||
|
||||
// if (rf->getSType() == STI_NOTPRESENT)
|
||||
// rf = makeFieldPresent(field);
|
||||
|
||||
T* cf = dynamic_cast<T*>(rf);
|
||||
|
||||
if (!cf)
|
||||
Throw<std::runtime_error>("Wrong field type");
|
||||
|
||||
(*cf) = value;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Creation
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
STData
|
||||
dataFromJson(SField const& field, Json::Value const& value);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,87 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/detail/STVar.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STDataType final : public STBase
|
||||
{
|
||||
private:
|
||||
std::uint16_t inner_type_;
|
||||
bool default_{true};
|
||||
|
||||
public:
|
||||
using value_type = STDataType; // Although not directly holding a single value
|
||||
|
||||
STDataType(SField const& n);
|
||||
STDataType(SField const& n, SerializedTypeID);
|
||||
|
||||
STDataType(SerialIter& sit, SField const& name);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getInnerTypeString() const;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(STBase const& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
void setInnerSType(SerializedTypeID);
|
||||
|
||||
SerializedTypeID
|
||||
getInnerSType() const noexcept;
|
||||
|
||||
STBase*
|
||||
makeFieldPresent();
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Implementation
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline SerializedTypeID
|
||||
STDataType::getInnerSType() const noexcept
|
||||
{
|
||||
return static_cast<SerializedTypeID>(inner_type_);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Creation
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
STDataType
|
||||
dataTypeFromJson(SField const& field, Json::Value const& value);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,193 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
/**
|
||||
* STJson: Serialized Type for JSON-like structures (objects or arrays).
|
||||
*
|
||||
* Supports two modes:
|
||||
* - Object: Key-value pairs where keys are VL-encoded strings
|
||||
* - Array: Ordered list of values
|
||||
*
|
||||
* Values are [SType marker][VL-encoded SType serialization].
|
||||
* Values can be any SType, including nested STJson.
|
||||
*
|
||||
* Serialization format: [type_byte][VL_length][data...]
|
||||
* - type_byte: 0x00 = Object, 0x01 = Array
|
||||
*/
|
||||
class STJson : public STBase
|
||||
{
|
||||
public:
|
||||
enum class JsonType : uint8_t { Object = 0x00, Array = 0x01 };
|
||||
|
||||
using value_type = STJson;
|
||||
value_type
|
||||
value() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
using Key = std::string;
|
||||
using Value = std::shared_ptr<STBase>;
|
||||
using Map = std::map<Key, Value>;
|
||||
using Array = std::vector<Value>;
|
||||
|
||||
STJson() = default;
|
||||
|
||||
explicit STJson(Map&& map);
|
||||
explicit STJson(Array&& array);
|
||||
explicit STJson(SField const& name);
|
||||
explicit STJson(SerialIter& sit, SField const& name);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
// Type checking
|
||||
bool
|
||||
isArray() const;
|
||||
|
||||
bool
|
||||
isObject() const;
|
||||
|
||||
JsonType
|
||||
getType() const;
|
||||
|
||||
// Depth checking (0 = no nesting, 1 = one level of nesting)
|
||||
int
|
||||
getDepth() const;
|
||||
|
||||
// Parse from binary blob
|
||||
static std::shared_ptr<STJson>
|
||||
fromBlob(void const* data, std::size_t size);
|
||||
|
||||
// Parse from SerialIter
|
||||
static std::shared_ptr<STJson>
|
||||
fromSerialIter(SerialIter& sit);
|
||||
|
||||
// Serialize to binary
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
// JSON representation
|
||||
Json::Value
|
||||
getJson(JsonOptions options) const override;
|
||||
|
||||
bool
|
||||
isEquivalent(STBase const& t) const override;
|
||||
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
// Blob representation
|
||||
Blob
|
||||
toBlob() const;
|
||||
|
||||
// STJson size
|
||||
std::size_t
|
||||
size() const;
|
||||
|
||||
// Object accessors (only valid when isObject() == true)
|
||||
Map const&
|
||||
getMap() const;
|
||||
|
||||
void
|
||||
setObjectField(Key const& key, Value const& value);
|
||||
|
||||
std::optional<STJson::Value>
|
||||
getObjectField(Key const& key) const;
|
||||
|
||||
void
|
||||
setNestedObjectField(Key const& key, Key const& nestedKey, Value const& value);
|
||||
|
||||
std::optional<Value>
|
||||
getNestedObjectField(Key const& key, Key const& nestedKey) const;
|
||||
|
||||
// Array accessors (only valid when isArray() == true)
|
||||
Array const&
|
||||
getArray() const;
|
||||
|
||||
void
|
||||
pushArrayElement(Value const& value);
|
||||
|
||||
std::optional<Value>
|
||||
getArrayElement(size_t index) const;
|
||||
|
||||
void
|
||||
setArrayElement(size_t index, Value const& value);
|
||||
|
||||
void
|
||||
setArrayElementField(size_t index, Key const& key, Value const& value);
|
||||
|
||||
std::optional<Value>
|
||||
getArrayElementField(size_t index, Key const& key) const;
|
||||
|
||||
size_t
|
||||
arraySize() const;
|
||||
|
||||
// Nested array accessors (for arrays stored in object fields)
|
||||
void
|
||||
setNestedArrayElement(Key const& key, size_t index, Value const& value);
|
||||
|
||||
void
|
||||
setNestedArrayElementField(
|
||||
Key const& key,
|
||||
size_t index,
|
||||
Key const& nestedKey,
|
||||
Value const& value);
|
||||
|
||||
std::optional<Value>
|
||||
getNestedArrayElement(Key const& key, size_t index) const;
|
||||
|
||||
std::optional<Value>
|
||||
getNestedArrayElementField(Key const& key, size_t index, Key const& nestedKey) const;
|
||||
|
||||
// Factory for SType value from blob (with SType marker)
|
||||
static Value
|
||||
makeValueFromVLWithType(SerialIter& sit);
|
||||
|
||||
void
|
||||
setValue(STJson const& v);
|
||||
|
||||
private:
|
||||
std::variant<Map, Array> data_{Map{}};
|
||||
bool default_{false};
|
||||
|
||||
// Helper: validate nesting depth (max 1 level)
|
||||
void
|
||||
validateDepth(Value const& value, int currentDepth) const;
|
||||
|
||||
// Helper: parse a single key-value pair from SerialIter
|
||||
static std::pair<Key, Value>
|
||||
parsePair(SerialIter& sit);
|
||||
|
||||
// Helper: parse array elements from SerialIter
|
||||
static Array
|
||||
parseArray(SerialIter& sit, int length);
|
||||
|
||||
// Helper: encode a key as VL
|
||||
static void
|
||||
addVLKey(Serializer& s, std::string const& str);
|
||||
|
||||
// Helper: encode a value as [SType marker][VL]
|
||||
static void
|
||||
addVLValue(Serializer& s, std::shared_ptr<STBase> const& value);
|
||||
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/Units.h>
|
||||
@@ -217,10 +216,6 @@ public:
|
||||
getFieldI32(SField const& field) const;
|
||||
AccountID
|
||||
getAccountID(SField const& field) const;
|
||||
STData
|
||||
getFieldData(SField const& field) const;
|
||||
STDataType
|
||||
getFieldDataType(SField const& field) const;
|
||||
|
||||
Blob
|
||||
getFieldVL(SField const& field) const;
|
||||
@@ -239,8 +234,6 @@ public:
|
||||
getFieldCurrency(SField const& field) const;
|
||||
STNumber const&
|
||||
getFieldNumber(SField const& field) const;
|
||||
STJson const&
|
||||
getFieldJson(SField const& field) const;
|
||||
|
||||
/** Get the value of a field.
|
||||
@param A TypedField built from an SField value representing the desired
|
||||
@@ -345,9 +338,6 @@ public:
|
||||
void
|
||||
set(STBase&& v);
|
||||
|
||||
void
|
||||
addFieldFromSlice(SField const& sfield, Slice const& data);
|
||||
|
||||
void
|
||||
setFieldU8(SField const& field, unsigned char);
|
||||
void
|
||||
@@ -386,8 +376,6 @@ public:
|
||||
setFieldArray(SField const& field, STArray const& v);
|
||||
void
|
||||
setFieldObject(SField const& field, STObject const& v);
|
||||
void
|
||||
setFieldJson(SField const& field, STJson const& v);
|
||||
|
||||
template <class Tag>
|
||||
void
|
||||
|
||||
@@ -121,9 +121,6 @@ enum TEMcodes : TERUnderlyingType {
|
||||
temARRAY_TOO_LARGE,
|
||||
temBAD_TRANSFER_FEE,
|
||||
temINVALID_INNER_BATCH,
|
||||
|
||||
temBAD_WASM,
|
||||
temTEMP_DISABLED,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -168,8 +165,6 @@ enum TEFcodes : TERUnderlyingType {
|
||||
tefNO_TICKET,
|
||||
tefNFTOKEN_IS_NOT_TRANSFERABLE,
|
||||
tefINVALID_LEDGER_FIX_TYPE,
|
||||
tefNO_WASM,
|
||||
tefWASM_FIELD_NOT_INCLUDED,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -351,8 +346,6 @@ enum TECcodes : TERUnderlyingType {
|
||||
// backward compatibility with historical data on non-prod networks, can be
|
||||
// reclaimed after those networks reset.
|
||||
tecNO_DELEGATE_PERMISSION = 198,
|
||||
tecWASM_REJECTED = 199,
|
||||
tecINVALID_PARAMETERS = 200,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -212,21 +212,8 @@ inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
|
||||
TF_FLAG(tfLoanDefault, 0x00010000) \
|
||||
TF_FLAG(tfLoanImpair, 0x00020000) \
|
||||
TF_FLAG(tfLoanUnimpair, 0x00040000), \
|
||||
MASK_ADJ(0)) \
|
||||
\
|
||||
TRANSACTION(Contract, \
|
||||
TF_FLAG(tfImmutable, 0x00010000) \
|
||||
TF_FLAG(tfCodeImmutable, 0x00020000) \
|
||||
TF_FLAG(tfABIImmutable, 0x00040000) \
|
||||
TF_FLAG(tfUndeletable, 0x00080000), \
|
||||
MASK_ADJ(0))
|
||||
|
||||
constexpr std::uint32_t tfSendAmount = 0x00010000;
|
||||
constexpr std::uint32_t tfSendNFToken = 0x00020000;
|
||||
constexpr std::uint32_t tfAuthorizeToken = 0x00040000;
|
||||
constexpr std::uint32_t tfContractParameterMask =
|
||||
~(tfSendAmount | tfSendNFToken | tfAuthorizeToken);
|
||||
|
||||
// clang-format on
|
||||
|
||||
// Create all the flag values.
|
||||
|
||||
@@ -84,12 +84,6 @@ public:
|
||||
|
||||
if (obj.isFieldPresent(sfParentBatchID))
|
||||
parentBatchID_ = obj.getFieldH256(sfParentBatchID);
|
||||
|
||||
if (obj.isFieldPresent(sfGasUsed))
|
||||
gasUsed_ = obj.getFieldU32(sfGasUsed);
|
||||
|
||||
if (obj.isFieldPresent(sfWasmReturnCode))
|
||||
wasmReturnCode_ = obj.getFieldI32(sfWasmReturnCode);
|
||||
}
|
||||
|
||||
std::optional<STAmount> const&
|
||||
@@ -110,30 +104,6 @@ public:
|
||||
parentBatchID_ = id;
|
||||
}
|
||||
|
||||
void
|
||||
setGasUsed(std::optional<std::uint32_t> const gasUsed)
|
||||
{
|
||||
gasUsed_ = gasUsed;
|
||||
}
|
||||
|
||||
std::optional<std::uint32_t> const&
|
||||
getGasUsed() const
|
||||
{
|
||||
return gasUsed_;
|
||||
}
|
||||
|
||||
void
|
||||
setWasmReturnCode(std::optional<std::int32_t> const wasmReturnCode)
|
||||
{
|
||||
wasmReturnCode_ = wasmReturnCode;
|
||||
}
|
||||
|
||||
std::optional<std::int32_t> const&
|
||||
getWasmReturnCode() const
|
||||
{
|
||||
return wasmReturnCode_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint256 transactionID_;
|
||||
std::uint32_t ledgerSeq_;
|
||||
@@ -142,8 +112,6 @@ private:
|
||||
|
||||
std::optional<STAmount> deliveredAmount_;
|
||||
std::optional<uint256> parentBatchID_;
|
||||
std::optional<std::uint32_t> gasUsed_;
|
||||
std::optional<std::int32_t> wasmReturnCode_;
|
||||
|
||||
STArray nodes_;
|
||||
};
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#if !defined(EMITABLE)
|
||||
#error "undefined macro: EMITABLE"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* EMITABLE(name, type, txType, value)
|
||||
*
|
||||
* This macro defines a permission:
|
||||
* name: the name of the permission.
|
||||
* type: the GranularPermissionType enum.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
*/
|
||||
|
||||
/** This removes the contract account the ability to set or remove deposit auth. */
|
||||
EMITABLE(AccountDepositAuth, ttACCOUNT_SET, 65537)
|
||||
|
||||
// ** This removes the contract account the ability to set or remove disable master key. */
|
||||
EMITABLE(AccountDisableMaster, ttACCOUNT_SET, 65538)
|
||||
@@ -15,8 +15,6 @@
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
|
||||
XRPL_FEATURE(SmartContract, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(SmartEscrow, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (Security3_1_3, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PermissionedDomainInvariant, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -150,7 +150,6 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
|
||||
{sfAMMID, soeOPTIONAL}, // pseudo-account designator
|
||||
{sfVaultID, soeOPTIONAL}, // pseudo-account designator
|
||||
{sfLoanBrokerID, soeOPTIONAL}, // pseudo-account designator
|
||||
{sfContractID, soeOPTIONAL}, // pseudo-account designator
|
||||
}))
|
||||
|
||||
/** A ledger object which contains a list of object identifiers.
|
||||
@@ -303,11 +302,6 @@ LEDGER_ENTRY(ltFEE_SETTINGS, 0x0073, FeeSettings, fee, ({
|
||||
{sfBaseFeeDrops, soeOPTIONAL},
|
||||
{sfReserveBaseDrops, soeOPTIONAL},
|
||||
{sfReserveIncrementDrops, soeOPTIONAL},
|
||||
// Smart Escrow fields
|
||||
{sfExtensionComputeLimit, soeOPTIONAL},
|
||||
{sfExtensionSizeLimit, soeOPTIONAL},
|
||||
{sfGasPrice, soeOPTIONAL},
|
||||
|
||||
{sfPreviousTxnID, soeOPTIONAL},
|
||||
{sfPreviousTxnLgrSeq, soeOPTIONAL},
|
||||
}))
|
||||
@@ -338,8 +332,6 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
|
||||
{sfCondition, soeOPTIONAL},
|
||||
{sfCancelAfter, soeOPTIONAL},
|
||||
{sfFinishAfter, soeOPTIONAL},
|
||||
{sfFinishFunction, soeOPTIONAL},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfSourceTag, soeOPTIONAL},
|
||||
{sfDestinationTag, soeOPTIONAL},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
@@ -586,7 +578,7 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
|
||||
// The unrounded true total value of the loan.
|
||||
//
|
||||
// - TrueTotalPrincipalOutstanding can be computed using the algorithm
|
||||
// in the xrpl::detail::loanPrincipalFromPeriodicPayment function.
|
||||
// in the ripple::detail::loanPrincipalFromPeriodicPayment function.
|
||||
//
|
||||
// - TrueTotalInterestOutstanding = TrueTotalLoanValue -
|
||||
// TrueTotalPrincipalOutstanding
|
||||
@@ -611,45 +603,5 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
|
||||
{sfLoanScale, soeDEFAULT},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a contract source.
|
||||
\sa keylet::contractSource
|
||||
*/
|
||||
LEDGER_ENTRY(ltCONTRACT_SOURCE, 0x0085, ContractSource, contract_source, ({
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfContractHash, soeREQUIRED},
|
||||
{sfContractCode, soeREQUIRED},
|
||||
{sfFunctions, soeREQUIRED},
|
||||
{sfInstanceParameters, soeOPTIONAL},
|
||||
{sfReferenceCount, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a contract.
|
||||
\sa keylet::contract
|
||||
*/
|
||||
LEDGER_ENTRY(ltCONTRACT, 0x0086, Contract, contract, ({
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfSequence, soeREQUIRED},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfContractAccount, soeREQUIRED},
|
||||
{sfContractHash, soeREQUIRED},
|
||||
{sfInstanceParameterValues, soeOPTIONAL},
|
||||
{sfURI, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** A ledger object representing a contract data.
|
||||
\sa keylet::contractData
|
||||
*/
|
||||
LEDGER_ENTRY(ltCONTRACT_DATA, 0x0087, ContractData, contract_data, ({
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfContractAccount, soeREQUIRED},
|
||||
{sfContractJson, soeREQUIRED},
|
||||
}))
|
||||
|
||||
#undef EXPAND
|
||||
#undef LEDGER_ENTRY_DUPLICATE
|
||||
|
||||
@@ -22,10 +22,9 @@ TYPED_SFIELD(sfAssetScale, UINT8, 5)
|
||||
// 8-bit integers (uncommon)
|
||||
TYPED_SFIELD(sfTickSize, UINT8, 16)
|
||||
TYPED_SFIELD(sfUNLModifyDisabling, UINT8, 17)
|
||||
// 18 unused
|
||||
TYPED_SFIELD(sfHookResult, UINT8, 18)
|
||||
TYPED_SFIELD(sfWasLockingChainSend, UINT8, 19)
|
||||
TYPED_SFIELD(sfWithdrawalPolicy, UINT8, 20)
|
||||
TYPED_SFIELD(sfContractResult, UINT8, 21)
|
||||
|
||||
// 16-bit integers (common)
|
||||
TYPED_SFIELD(sfLedgerEntryType, UINT16, 1, SField::sMD_Never)
|
||||
@@ -37,7 +36,10 @@ TYPED_SFIELD(sfDiscountedFee, UINT16, 6)
|
||||
|
||||
// 16-bit integers (uncommon)
|
||||
TYPED_SFIELD(sfVersion, UINT16, 16)
|
||||
// 17 to 20 unused
|
||||
TYPED_SFIELD(sfHookStateChangeCount, UINT16, 17)
|
||||
TYPED_SFIELD(sfHookEmitCount, UINT16, 18)
|
||||
TYPED_SFIELD(sfHookExecutionIndex, UINT16, 19)
|
||||
TYPED_SFIELD(sfHookApiVersion, UINT16, 20)
|
||||
TYPED_SFIELD(sfLedgerFixType, UINT16, 21)
|
||||
TYPED_SFIELD(sfManagementFeeRate, UINT16, 22) // 1/10 basis points (bips)
|
||||
|
||||
@@ -88,7 +90,9 @@ TYPED_SFIELD(sfTicketSequence, UINT32, 41)
|
||||
TYPED_SFIELD(sfNFTokenTaxon, UINT32, 42)
|
||||
TYPED_SFIELD(sfMintedNFTokens, UINT32, 43)
|
||||
TYPED_SFIELD(sfBurnedNFTokens, UINT32, 44)
|
||||
// 45 to 47 unused
|
||||
TYPED_SFIELD(sfHookStateCount, UINT32, 45)
|
||||
TYPED_SFIELD(sfEmitGeneration, UINT32, 46)
|
||||
// 47 reserved for Hooks
|
||||
TYPED_SFIELD(sfVoteWeight, UINT32, 48)
|
||||
TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
|
||||
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
|
||||
@@ -109,12 +113,6 @@ 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(sfExtensionComputeLimit, UINT32, 69)
|
||||
TYPED_SFIELD(sfExtensionSizeLimit, UINT32, 70)
|
||||
TYPED_SFIELD(sfGasPrice, UINT32, 71)
|
||||
TYPED_SFIELD(sfComputationAllowance, UINT32, 72)
|
||||
TYPED_SFIELD(sfGasUsed, UINT32, 73)
|
||||
TYPED_SFIELD(sfParameterFlag, UINT32, 74)
|
||||
|
||||
// 64-bit integers (common)
|
||||
TYPED_SFIELD(sfIndexNext, UINT64, 1)
|
||||
@@ -132,7 +130,9 @@ TYPED_SFIELD(sfNFTokenOfferNode, UINT64, 12)
|
||||
TYPED_SFIELD(sfEmitBurden, UINT64, 13)
|
||||
|
||||
// 64-bit integers (uncommon)
|
||||
// 16 to 18 unused
|
||||
TYPED_SFIELD(sfHookOn, UINT64, 16)
|
||||
TYPED_SFIELD(sfHookInstructionCount, UINT64, 17)
|
||||
TYPED_SFIELD(sfHookReturnCode, UINT64, 18)
|
||||
TYPED_SFIELD(sfReferenceCount, UINT64, 19)
|
||||
TYPED_SFIELD(sfXChainClaimID, UINT64, 20)
|
||||
TYPED_SFIELD(sfXChainAccountCreateCount, UINT64, 21)
|
||||
@@ -192,7 +192,10 @@ TYPED_SFIELD(sfPreviousPageMin, UINT256, 26)
|
||||
TYPED_SFIELD(sfNextPageMin, UINT256, 27)
|
||||
TYPED_SFIELD(sfNFTokenBuyOffer, UINT256, 28)
|
||||
TYPED_SFIELD(sfNFTokenSellOffer, UINT256, 29)
|
||||
// 30 to 33 unused
|
||||
TYPED_SFIELD(sfHookStateKey, UINT256, 30)
|
||||
TYPED_SFIELD(sfHookHash, UINT256, 31)
|
||||
TYPED_SFIELD(sfHookNamespace, UINT256, 32)
|
||||
TYPED_SFIELD(sfHookSetTxnID, UINT256, 33)
|
||||
TYPED_SFIELD(sfDomainID, UINT256, 34)
|
||||
TYPED_SFIELD(sfVaultID, UINT256, 35,
|
||||
SField::sMD_PseudoAccount | SField::sMD_Default)
|
||||
@@ -200,9 +203,6 @@ TYPED_SFIELD(sfParentBatchID, UINT256, 36)
|
||||
TYPED_SFIELD(sfLoanBrokerID, UINT256, 37,
|
||||
SField::sMD_PseudoAccount | SField::sMD_Default)
|
||||
TYPED_SFIELD(sfLoanID, UINT256, 38)
|
||||
TYPED_SFIELD(sfContractHash, UINT256, 39)
|
||||
TYPED_SFIELD(sfContractID, UINT256, 40,
|
||||
SField::sMD_PseudoAccount | SField::sMD_Default)
|
||||
|
||||
// number (common)
|
||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||
@@ -223,9 +223,8 @@ TYPED_SFIELD(sfTotalValueOutstanding, NUMBER, 15, SField::sMD_NeedsAsset
|
||||
TYPED_SFIELD(sfPeriodicPayment, NUMBER, 16)
|
||||
TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17, SField::sMD_NeedsAsset | SField::sMD_Default)
|
||||
|
||||
// 32-bit signed (common)
|
||||
// int32
|
||||
TYPED_SFIELD(sfLoanScale, INT32, 1)
|
||||
TYPED_SFIELD(sfWasmReturnCode, INT32, 2)
|
||||
|
||||
// currency amount (common)
|
||||
TYPED_SFIELD(sfAmount, AMOUNT, 1)
|
||||
@@ -247,13 +246,15 @@ TYPED_SFIELD(sfMinimumOffer, AMOUNT, 16)
|
||||
TYPED_SFIELD(sfRippleEscrow, AMOUNT, 17)
|
||||
TYPED_SFIELD(sfDeliveredAmount, AMOUNT, 18)
|
||||
TYPED_SFIELD(sfNFTokenBrokerFee, AMOUNT, 19)
|
||||
// 20 to 21 unused
|
||||
|
||||
// Reserve 20 & 21 for Hooks.
|
||||
|
||||
// currency amount (fees)
|
||||
TYPED_SFIELD(sfBaseFeeDrops, AMOUNT, 22)
|
||||
TYPED_SFIELD(sfReserveBaseDrops, AMOUNT, 23)
|
||||
TYPED_SFIELD(sfReserveIncrementDrops, AMOUNT, 24)
|
||||
|
||||
// currency amount (more)
|
||||
// currency amount (AMM)
|
||||
TYPED_SFIELD(sfLPTokenOut, AMOUNT, 25)
|
||||
TYPED_SFIELD(sfLPTokenIn, AMOUNT, 26)
|
||||
TYPED_SFIELD(sfEPrice, AMOUNT, 27)
|
||||
@@ -285,16 +286,16 @@ TYPED_SFIELD(sfMasterSignature, VL, 18, SField::sMD_Default, SFi
|
||||
TYPED_SFIELD(sfUNLModifyValidator, VL, 19)
|
||||
TYPED_SFIELD(sfValidatorToDisable, VL, 20)
|
||||
TYPED_SFIELD(sfValidatorToReEnable, VL, 21)
|
||||
// 22 to 25 unused
|
||||
TYPED_SFIELD(sfHookStateData, VL, 22)
|
||||
TYPED_SFIELD(sfHookReturnString, VL, 23)
|
||||
TYPED_SFIELD(sfHookParameterName, VL, 24)
|
||||
TYPED_SFIELD(sfHookParameterValue, VL, 25)
|
||||
TYPED_SFIELD(sfDIDDocument, VL, 26)
|
||||
TYPED_SFIELD(sfData, VL, 27)
|
||||
TYPED_SFIELD(sfAssetClass, VL, 28)
|
||||
TYPED_SFIELD(sfProvider, VL, 29)
|
||||
TYPED_SFIELD(sfMPTokenMetadata, VL, 30)
|
||||
TYPED_SFIELD(sfCredentialType, VL, 31)
|
||||
TYPED_SFIELD(sfFinishFunction, VL, 32)
|
||||
TYPED_SFIELD(sfContractCode, VL, 33)
|
||||
TYPED_SFIELD(sfFunctionName, VL, 34)
|
||||
|
||||
// account (common)
|
||||
TYPED_SFIELD(sfAccount, ACCOUNT, 1)
|
||||
@@ -311,7 +312,7 @@ TYPED_SFIELD(sfHolder, ACCOUNT, 11)
|
||||
TYPED_SFIELD(sfDelegate, ACCOUNT, 12)
|
||||
|
||||
// account (uncommon)
|
||||
// 16 unused
|
||||
TYPED_SFIELD(sfHookAccount, ACCOUNT, 16)
|
||||
TYPED_SFIELD(sfOtherChainSource, ACCOUNT, 18)
|
||||
TYPED_SFIELD(sfOtherChainDestination, ACCOUNT, 19)
|
||||
TYPED_SFIELD(sfAttestationSignerAccount, ACCOUNT, 20)
|
||||
@@ -321,7 +322,6 @@ TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
|
||||
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
|
||||
TYPED_SFIELD(sfBorrower, ACCOUNT, 25)
|
||||
TYPED_SFIELD(sfCounterparty, ACCOUNT, 26)
|
||||
TYPED_SFIELD(sfContractAccount, ACCOUNT, 27)
|
||||
|
||||
// vector of 256-bit
|
||||
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
|
||||
@@ -360,7 +360,7 @@ UNTYPED_SFIELD(sfMemo, OBJECT, 10)
|
||||
UNTYPED_SFIELD(sfSignerEntry, OBJECT, 11)
|
||||
UNTYPED_SFIELD(sfNFToken, OBJECT, 12)
|
||||
UNTYPED_SFIELD(sfEmitDetails, OBJECT, 13)
|
||||
// 14 unused
|
||||
UNTYPED_SFIELD(sfHook, OBJECT, 14)
|
||||
UNTYPED_SFIELD(sfPermission, OBJECT, 15)
|
||||
|
||||
// inner object (uncommon)
|
||||
@@ -368,7 +368,11 @@ UNTYPED_SFIELD(sfSigner, OBJECT, 16)
|
||||
// 17 unused
|
||||
UNTYPED_SFIELD(sfMajority, OBJECT, 18)
|
||||
UNTYPED_SFIELD(sfDisabledValidator, OBJECT, 19)
|
||||
// 20 to 24 unused
|
||||
UNTYPED_SFIELD(sfEmittedTxn, OBJECT, 20)
|
||||
UNTYPED_SFIELD(sfHookExecution, OBJECT, 21)
|
||||
UNTYPED_SFIELD(sfHookDefinition, OBJECT, 22)
|
||||
UNTYPED_SFIELD(sfHookParameter, OBJECT, 23)
|
||||
UNTYPED_SFIELD(sfHookGrant, OBJECT, 24)
|
||||
UNTYPED_SFIELD(sfVoteEntry, OBJECT, 25)
|
||||
UNTYPED_SFIELD(sfAuctionSlot, OBJECT, 26)
|
||||
UNTYPED_SFIELD(sfAuthAccount, OBJECT, 27)
|
||||
@@ -382,10 +386,6 @@ UNTYPED_SFIELD(sfRawTransaction, OBJECT, 34)
|
||||
UNTYPED_SFIELD(sfBatchSigner, OBJECT, 35)
|
||||
UNTYPED_SFIELD(sfBook, OBJECT, 36)
|
||||
UNTYPED_SFIELD(sfCounterpartySignature, OBJECT, 37, SField::sMD_Default, SField::notSigning)
|
||||
UNTYPED_SFIELD(sfFunction, OBJECT, 38)
|
||||
UNTYPED_SFIELD(sfInstanceParameter, OBJECT, 39)
|
||||
UNTYPED_SFIELD(sfInstanceParameterValue, OBJECT, 40)
|
||||
UNTYPED_SFIELD(sfParameter, OBJECT, 41)
|
||||
|
||||
// array of objects (common)
|
||||
// ARRAY/1 is reserved for end of array
|
||||
@@ -399,14 +399,16 @@ UNTYPED_SFIELD(sfSufficient, ARRAY, 7)
|
||||
UNTYPED_SFIELD(sfAffectedNodes, ARRAY, 8)
|
||||
UNTYPED_SFIELD(sfMemos, ARRAY, 9)
|
||||
UNTYPED_SFIELD(sfNFTokens, ARRAY, 10)
|
||||
// 11 unused
|
||||
UNTYPED_SFIELD(sfHooks, ARRAY, 11)
|
||||
UNTYPED_SFIELD(sfVoteSlots, ARRAY, 12)
|
||||
UNTYPED_SFIELD(sfAdditionalBooks, ARRAY, 13)
|
||||
|
||||
// array of objects (uncommon)
|
||||
UNTYPED_SFIELD(sfMajorities, ARRAY, 16)
|
||||
UNTYPED_SFIELD(sfDisabledValidators, ARRAY, 17)
|
||||
// 18 to 20 unused
|
||||
UNTYPED_SFIELD(sfHookExecutions, ARRAY, 18)
|
||||
UNTYPED_SFIELD(sfHookParameters, ARRAY, 19)
|
||||
UNTYPED_SFIELD(sfHookGrants, ARRAY, 20)
|
||||
UNTYPED_SFIELD(sfXChainClaimAttestations, ARRAY, 21)
|
||||
UNTYPED_SFIELD(sfXChainCreateAccountAttestations, ARRAY, 22)
|
||||
// 23 unused
|
||||
@@ -418,16 +420,3 @@ UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
|
||||
UNTYPED_SFIELD(sfPermissions, ARRAY, 29)
|
||||
UNTYPED_SFIELD(sfRawTransactions, ARRAY, 30)
|
||||
UNTYPED_SFIELD(sfBatchSigners, ARRAY, 31, SField::sMD_Default, SField::notSigning)
|
||||
UNTYPED_SFIELD(sfFunctions, ARRAY, 32)
|
||||
UNTYPED_SFIELD(sfInstanceParameters, ARRAY, 33)
|
||||
UNTYPED_SFIELD(sfInstanceParameterValues, ARRAY, 34)
|
||||
UNTYPED_SFIELD(sfParameters, ARRAY, 35)
|
||||
|
||||
// data
|
||||
TYPED_SFIELD(sfParameterValue, DATA, 1, SField::sMD_Default)
|
||||
|
||||
// data type
|
||||
TYPED_SFIELD(sfParameterType, DATATYPE, 1)
|
||||
|
||||
// json
|
||||
TYPED_SFIELD(sfContractJson, JSON, 1)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TRANSACTION(tag, value, name, delegable, amendments, privileges, emitable, fields)
|
||||
* TRANSACTION(tag, value, name, delegable, amendments, privileges, fields)
|
||||
*
|
||||
* To ease maintenance, you may replace any unneeded values with "..."
|
||||
* e.g. #define TRANSACTION(tag, value, name, ...)
|
||||
@@ -28,7 +28,6 @@ TRANSACTION(ttPAYMENT, 0, Payment,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
createAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
@@ -49,16 +48,13 @@ TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfDestinationTag, soeOPTIONAL},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
{sfCondition, soeOPTIONAL},
|
||||
{sfCancelAfter, soeOPTIONAL},
|
||||
{sfFinishAfter, soeOPTIONAL},
|
||||
{sfFinishFunction, soeOPTIONAL},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfDestinationTag, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction type completes an existing escrow. */
|
||||
@@ -69,14 +65,12 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfOfferSequence, soeREQUIRED},
|
||||
{sfFulfillment, soeOPTIONAL},
|
||||
{sfCondition, soeOPTIONAL},
|
||||
{sfCredentialIDs, soeOPTIONAL},
|
||||
{sfComputationAllowance, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
|
||||
@@ -88,7 +82,6 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfEmailHash, soeOPTIONAL},
|
||||
{sfWalletLocator, soeOPTIONAL},
|
||||
@@ -110,7 +103,6 @@ TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfOfferSequence, soeREQUIRED},
|
||||
@@ -124,7 +116,6 @@ TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfRegularKey, soeOPTIONAL},
|
||||
}))
|
||||
@@ -139,7 +130,6 @@ TRANSACTION(ttOFFER_CREATE, 7, OfferCreate,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfTakerPays, soeREQUIRED},
|
||||
{sfTakerGets, soeREQUIRED},
|
||||
@@ -156,7 +146,6 @@ TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfOfferSequence, soeREQUIRED},
|
||||
}))
|
||||
@@ -171,7 +160,6 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfTicketCount, soeREQUIRED},
|
||||
}))
|
||||
@@ -188,7 +176,6 @@ TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfSignerQuorum, soeREQUIRED},
|
||||
{sfSignerEntries, soeOPTIONAL},
|
||||
@@ -202,7 +189,6 @@ TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED},
|
||||
@@ -220,7 +206,6 @@ TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfChannel, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED},
|
||||
@@ -235,7 +220,6 @@ TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfChannel, soeREQUIRED},
|
||||
{sfAmount, soeOPTIONAL},
|
||||
@@ -253,7 +237,6 @@ TRANSACTION(ttCHECK_CREATE, 16, CheckCreate,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfSendMax, soeREQUIRED},
|
||||
@@ -270,7 +253,6 @@ TRANSACTION(ttCHECK_CASH, 17, CheckCash,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfCheckID, soeREQUIRED},
|
||||
{sfAmount, soeOPTIONAL},
|
||||
@@ -285,7 +267,6 @@ TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfCheckID, soeREQUIRED},
|
||||
}))
|
||||
@@ -298,7 +279,6 @@ TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfAuthorize, soeOPTIONAL},
|
||||
{sfUnauthorize, soeOPTIONAL},
|
||||
@@ -314,7 +294,6 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfLimitAmount, soeOPTIONAL},
|
||||
{sfQualityIn, soeOPTIONAL},
|
||||
@@ -329,7 +308,6 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
mustDeleteAcct,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfDestination, soeREQUIRED},
|
||||
{sfDestinationTag, soeOPTIONAL},
|
||||
@@ -346,7 +324,6 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
changeNFTCounts,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfNFTokenTaxon, soeREQUIRED},
|
||||
{sfTransferFee, soeOPTIONAL},
|
||||
@@ -365,7 +342,6 @@ TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
changeNFTCounts,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfNFTokenID, soeREQUIRED},
|
||||
{sfOwner, soeOPTIONAL},
|
||||
@@ -379,7 +355,6 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfNFTokenID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED},
|
||||
@@ -396,7 +371,6 @@ TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfNFTokenOffers, soeREQUIRED},
|
||||
}))
|
||||
@@ -409,7 +383,6 @@ TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
|
||||
Delegation::delegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfNFTokenBuyOffer, soeOPTIONAL},
|
||||
{sfNFTokenSellOffer, soeOPTIONAL},
|
||||
@@ -424,7 +397,6 @@ TRANSACTION(ttCLAWBACK, 30, Clawback,
|
||||
Delegation::delegable,
|
||||
featureClawback,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
{sfHolder, soeOPTIONAL},
|
||||
@@ -438,7 +410,6 @@ TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
|
||||
Delegation::delegable,
|
||||
featureAMMClawback,
|
||||
mayDeleteAcct | overrideFreeze,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfHolder, soeREQUIRED},
|
||||
{sfAsset, soeREQUIRED},
|
||||
@@ -454,7 +425,6 @@ TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
|
||||
Delegation::delegable,
|
||||
featureAMM,
|
||||
createPseudoAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAmount, soeREQUIRED},
|
||||
{sfAmount2, soeREQUIRED},
|
||||
@@ -469,7 +439,6 @@ TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
|
||||
Delegation::delegable,
|
||||
featureAMM,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAsset, soeREQUIRED},
|
||||
{sfAsset2, soeREQUIRED},
|
||||
@@ -488,7 +457,6 @@ TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
|
||||
Delegation::delegable,
|
||||
featureAMM,
|
||||
mayDeleteAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAsset, soeREQUIRED},
|
||||
{sfAsset2, soeREQUIRED},
|
||||
@@ -506,7 +474,6 @@ TRANSACTION(ttAMM_VOTE, 38, AMMVote,
|
||||
Delegation::delegable,
|
||||
featureAMM,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAsset, soeREQUIRED},
|
||||
{sfAsset2, soeREQUIRED},
|
||||
@@ -521,7 +488,6 @@ TRANSACTION(ttAMM_BID, 39, AMMBid,
|
||||
Delegation::delegable,
|
||||
featureAMM,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAsset, soeREQUIRED},
|
||||
{sfAsset2, soeREQUIRED},
|
||||
@@ -538,7 +504,6 @@ TRANSACTION(ttAMM_DELETE, 40, AMMDelete,
|
||||
Delegation::delegable,
|
||||
featureAMM,
|
||||
mustDeleteAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAsset, soeREQUIRED},
|
||||
{sfAsset2, soeREQUIRED},
|
||||
@@ -552,7 +517,6 @@ TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
{sfSignatureReward, soeREQUIRED},
|
||||
@@ -564,7 +528,6 @@ TRANSACTION(ttXCHAIN_COMMIT, 42, XChainCommit,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
{sfXChainClaimID, soeREQUIRED},
|
||||
@@ -577,7 +540,6 @@ TRANSACTION(ttXCHAIN_CLAIM, 43, XChainClaim,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
{sfXChainClaimID, soeREQUIRED},
|
||||
@@ -591,7 +553,6 @@ TRANSACTION(ttXCHAIN_ACCOUNT_CREATE_COMMIT, 44, XChainAccountCreateCommit,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
{sfDestination, soeREQUIRED},
|
||||
@@ -604,7 +565,6 @@ TRANSACTION(ttXCHAIN_ADD_CLAIM_ATTESTATION, 45, XChainAddClaimAttestation,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
createAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
|
||||
@@ -626,7 +586,6 @@ TRANSACTION(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, 46,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
createAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
|
||||
@@ -648,7 +607,6 @@ TRANSACTION(ttXCHAIN_MODIFY_BRIDGE, 47, XChainModifyBridge,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
{sfSignatureReward, soeOPTIONAL},
|
||||
@@ -660,7 +618,6 @@ TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge,
|
||||
Delegation::delegable,
|
||||
featureXChainBridge,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfXChainBridge, soeREQUIRED},
|
||||
{sfSignatureReward, soeREQUIRED},
|
||||
@@ -675,7 +632,6 @@ TRANSACTION(ttDID_SET, 49, DIDSet,
|
||||
Delegation::delegable,
|
||||
featureDID,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDIDDocument, soeOPTIONAL},
|
||||
{sfURI, soeOPTIONAL},
|
||||
@@ -690,7 +646,6 @@ TRANSACTION(ttDID_DELETE, 50, DIDDelete,
|
||||
Delegation::delegable,
|
||||
featureDID,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({}))
|
||||
|
||||
/** This transaction type creates an Oracle instance */
|
||||
@@ -701,7 +656,6 @@ TRANSACTION(ttORACLE_SET, 51, OracleSet,
|
||||
Delegation::delegable,
|
||||
featurePriceOracle,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfOracleDocumentID, soeREQUIRED},
|
||||
{sfProvider, soeOPTIONAL},
|
||||
@@ -719,7 +673,6 @@ TRANSACTION(ttORACLE_DELETE, 52, OracleDelete,
|
||||
Delegation::delegable,
|
||||
featurePriceOracle,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfOracleDocumentID, soeREQUIRED},
|
||||
}))
|
||||
@@ -732,7 +685,6 @@ TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix,
|
||||
Delegation::delegable,
|
||||
fixNFTokenPageLinks,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfLedgerFixType, soeREQUIRED},
|
||||
{sfOwner, soeOPTIONAL},
|
||||
@@ -746,7 +698,6 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
|
||||
Delegation::delegable,
|
||||
featureMPTokensV1,
|
||||
createMPTIssuance,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAssetScale, soeOPTIONAL},
|
||||
{sfTransferFee, soeOPTIONAL},
|
||||
@@ -764,7 +715,6 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy,
|
||||
Delegation::delegable,
|
||||
featureMPTokensV1,
|
||||
destroyMPTIssuance,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
}))
|
||||
@@ -777,7 +727,6 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet,
|
||||
Delegation::delegable,
|
||||
featureMPTokensV1,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfHolder, soeOPTIONAL},
|
||||
@@ -795,7 +744,6 @@ TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize,
|
||||
Delegation::delegable,
|
||||
featureMPTokensV1,
|
||||
mustAuthorizeMPT,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfMPTokenIssuanceID, soeREQUIRED},
|
||||
{sfHolder, soeOPTIONAL},
|
||||
@@ -809,7 +757,6 @@ TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate,
|
||||
Delegation::delegable,
|
||||
featureCredentials,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfSubject, soeREQUIRED},
|
||||
{sfCredentialType, soeREQUIRED},
|
||||
@@ -825,7 +772,6 @@ TRANSACTION(ttCREDENTIAL_ACCEPT, 59, CredentialAccept,
|
||||
Delegation::delegable,
|
||||
featureCredentials,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfIssuer, soeREQUIRED},
|
||||
{sfCredentialType, soeREQUIRED},
|
||||
@@ -839,7 +785,6 @@ TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete,
|
||||
Delegation::delegable,
|
||||
featureCredentials,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfSubject, soeOPTIONAL},
|
||||
{sfIssuer, soeOPTIONAL},
|
||||
@@ -854,7 +799,6 @@ TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify,
|
||||
Delegation::delegable,
|
||||
featureDynamicNFT,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfNFTokenID, soeREQUIRED},
|
||||
{sfOwner, soeOPTIONAL},
|
||||
@@ -869,7 +813,6 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet,
|
||||
Delegation::delegable,
|
||||
featurePermissionedDomains,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDomainID, soeOPTIONAL},
|
||||
{sfAcceptedCredentials, soeREQUIRED},
|
||||
@@ -883,7 +826,6 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
|
||||
Delegation::delegable,
|
||||
featurePermissionedDomains,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfDomainID, soeREQUIRED},
|
||||
}))
|
||||
@@ -896,7 +838,6 @@ TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
|
||||
Delegation::notDelegable,
|
||||
featurePermissionDelegationV1_1,
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfAuthorize, soeREQUIRED},
|
||||
{sfPermissions, soeREQUIRED},
|
||||
@@ -910,7 +851,6 @@ TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
|
||||
Delegation::notDelegable,
|
||||
featureSingleAssetVault,
|
||||
createPseudoAcct | createMPTIssuance | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfAsset, soeREQUIRED, soeMPTSupported},
|
||||
{sfAssetsMaximum, soeOPTIONAL},
|
||||
@@ -929,7 +869,6 @@ TRANSACTION(ttVAULT_SET, 66, VaultSet,
|
||||
Delegation::notDelegable,
|
||||
featureSingleAssetVault,
|
||||
mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfAssetsMaximum, soeOPTIONAL},
|
||||
@@ -945,7 +884,6 @@ TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
|
||||
Delegation::notDelegable,
|
||||
featureSingleAssetVault,
|
||||
mustDeleteAcct | destroyMPTIssuance | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
}))
|
||||
@@ -958,7 +896,6 @@ TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
|
||||
Delegation::notDelegable,
|
||||
featureSingleAssetVault,
|
||||
mayAuthorizeMPT | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
@@ -972,7 +909,6 @@ TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
|
||||
Delegation::notDelegable,
|
||||
featureSingleAssetVault,
|
||||
mayDeleteMPT | mayAuthorizeMPT | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
@@ -988,7 +924,6 @@ TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
|
||||
Delegation::notDelegable,
|
||||
featureSingleAssetVault,
|
||||
mayDeleteMPT | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfHolder, soeREQUIRED},
|
||||
@@ -1003,7 +938,6 @@ TRANSACTION(ttBATCH, 71, Batch,
|
||||
Delegation::notDelegable,
|
||||
featureBatch,
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfRawTransactions, soeREQUIRED},
|
||||
{sfBatchSigners, soeOPTIONAL},
|
||||
@@ -1018,9 +952,7 @@ TRANSACTION(ttBATCH, 71, Batch,
|
||||
TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
createPseudoAcct | mayAuthorizeMPT,
|
||||
Emittance::emitable,
|
||||
({
|
||||
createPseudoAcct | mayAuthorizeMPT, ({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
{sfLoanBrokerID, soeOPTIONAL},
|
||||
{sfData, soeOPTIONAL},
|
||||
@@ -1037,9 +969,7 @@ TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
|
||||
TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
mustDeleteAcct | mayAuthorizeMPT,
|
||||
Emittance::emitable,
|
||||
({
|
||||
mustDeleteAcct | mayAuthorizeMPT, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
@@ -1050,9 +980,7 @@ TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
|
||||
TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
noPriv, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
}))
|
||||
@@ -1064,9 +992,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit,
|
||||
TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
mayAuthorizeMPT,
|
||||
Emittance::emitable,
|
||||
({
|
||||
mayAuthorizeMPT, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
{sfDestination, soeOPTIONAL},
|
||||
@@ -1081,9 +1007,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw,
|
||||
TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
noPriv, ({
|
||||
{sfLoanBrokerID, soeOPTIONAL},
|
||||
{sfAmount, soeOPTIONAL, soeMPTSupported},
|
||||
}))
|
||||
@@ -1095,9 +1019,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback,
|
||||
TRANSACTION(ttLOAN_SET, 80, LoanSet,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
mayAuthorizeMPT | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
mayAuthorizeMPT | mustModifyVault, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfCounterparty, soeOPTIONAL},
|
||||
@@ -1124,9 +1046,7 @@ TRANSACTION(ttLOAN_SET, 80, LoanSet,
|
||||
TRANSACTION(ttLOAN_DELETE, 81, LoanDelete,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
noPriv, ({
|
||||
{sfLoanID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
@@ -1140,9 +1060,7 @@ TRANSACTION(ttLOAN_MANAGE, 82, LoanManage,
|
||||
// All of the LoanManage options will modify the vault, but the
|
||||
// transaction can succeed without options, essentially making it
|
||||
// a noop.
|
||||
mayModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
mayModifyVault, ({
|
||||
{sfLoanID, soeREQUIRED},
|
||||
}))
|
||||
|
||||
@@ -1153,110 +1071,11 @@ TRANSACTION(ttLOAN_MANAGE, 82, LoanManage,
|
||||
TRANSACTION(ttLOAN_PAY, 84, LoanPay,
|
||||
Delegation::notDelegable,
|
||||
featureLendingProtocol,
|
||||
mayAuthorizeMPT | mustModifyVault,
|
||||
Emittance::emitable,
|
||||
({
|
||||
mayAuthorizeMPT | mustModifyVault, ({
|
||||
{sfLoanID, soeREQUIRED},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
}))
|
||||
|
||||
/** This transaction type creates the smart contract. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/contract/ContractCreate.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONTRACT_CREATE, 85, ContractCreate,
|
||||
Delegation::delegable,
|
||||
featureSmartContract,
|
||||
createPseudoAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfContractCode, soeOPTIONAL},
|
||||
{sfContractHash, soeOPTIONAL},
|
||||
{sfFunctions, soeOPTIONAL},
|
||||
{sfInstanceParameters, soeOPTIONAL},
|
||||
{sfInstanceParameterValues, soeOPTIONAL},
|
||||
{sfURI, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction type modifies the smart contract. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/contract/ContractModify.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONTRACT_MODIFY, 86, ContractModify,
|
||||
Delegation::delegable,
|
||||
featureSmartContract,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfContractAccount, soeOPTIONAL},
|
||||
{sfOwner, soeOPTIONAL},
|
||||
{sfContractCode, soeOPTIONAL},
|
||||
{sfContractHash, soeOPTIONAL},
|
||||
{sfFunctions, soeOPTIONAL},
|
||||
{sfInstanceParameters, soeOPTIONAL},
|
||||
{sfInstanceParameterValues, soeOPTIONAL},
|
||||
{sfURI, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction type deletes the smart contract. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/contract/ContractDelete.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONTRACT_DELETE, 87, ContractDelete,
|
||||
Delegation::delegable,
|
||||
featureSmartContract,
|
||||
mustDeleteAcct,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfContractAccount, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction type claws back funds from the contract. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/contract/ContractClawback.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONTRACT_CLAWBACK, 88, ContractClawback,
|
||||
Delegation::delegable,
|
||||
featureSmartContract,
|
||||
noPriv,
|
||||
Emittance::emitable,
|
||||
({
|
||||
{sfContractAccount, soeOPTIONAL},
|
||||
{sfAmount, soeREQUIRED, soeMPTSupported},
|
||||
}))
|
||||
|
||||
/** This transaction type deletes user data. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/contract/ContractUserDelete.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONTRACT_USER_DELETE, 89, ContractUserDelete,
|
||||
Delegation::delegable,
|
||||
featureSmartContract,
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfContractAccount, soeREQUIRED},
|
||||
{sfFunctionName, soeREQUIRED},
|
||||
{sfParameters, soeOPTIONAL},
|
||||
{sfComputationAllowance, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction type calls the smart contract. */
|
||||
#if TRANSACTION_INCLUDE
|
||||
# include <xrpl/tx/transactors/contract/ContractCall.h>
|
||||
#endif
|
||||
TRANSACTION(ttCONTRACT_CALL, 90, ContractCall,
|
||||
Delegation::delegable,
|
||||
featureSmartContract,
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfContractAccount, soeREQUIRED},
|
||||
{sfFunctionName, soeREQUIRED},
|
||||
{sfParameters, soeOPTIONAL},
|
||||
{sfComputationAllowance, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||
|
||||
For details, see: https://xrpl.org/amendments.html
|
||||
@@ -1268,7 +1087,6 @@ TRANSACTION(ttAMENDMENT, 100, EnableAmendment,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfLedgerSequence, soeREQUIRED},
|
||||
{sfAmendment, soeREQUIRED},
|
||||
@@ -1281,7 +1099,6 @@ TRANSACTION(ttFEE, 101, SetFee,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfLedgerSequence, soeOPTIONAL},
|
||||
// Old version uses raw numbers
|
||||
@@ -1293,10 +1110,6 @@ TRANSACTION(ttFEE, 101, SetFee,
|
||||
{sfBaseFeeDrops, soeOPTIONAL},
|
||||
{sfReserveBaseDrops, soeOPTIONAL},
|
||||
{sfReserveIncrementDrops, soeOPTIONAL},
|
||||
// Smart Escrow fields
|
||||
{sfExtensionComputeLimit, soeOPTIONAL},
|
||||
{sfExtensionSizeLimit, soeOPTIONAL},
|
||||
{sfGasPrice, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This system-generated transaction type is used to update the network's negative UNL
|
||||
@@ -1307,7 +1120,6 @@ TRANSACTION(ttUNL_MODIFY, 102, UNLModify,
|
||||
Delegation::notDelegable,
|
||||
uint256{},
|
||||
noPriv,
|
||||
Emittance::notEmitable,
|
||||
({
|
||||
{sfUNLModifyDisabling, soeREQUIRED},
|
||||
{sfLedgerSequence, soeREQUIRED},
|
||||
|
||||
@@ -186,7 +186,6 @@ JSS(common); // out: RPC server_definitions
|
||||
JSS(complete); // out: NetworkOPs, InboundLedger
|
||||
JSS(complete_ledgers); // out: NetworkOPs, PeerImp
|
||||
JSS(consensus); // out: NetworkOPs, LedgerConsensus
|
||||
JSS(contract_account); // out: ContractInfo
|
||||
JSS(converge_time); // out: NetworkOPs
|
||||
JSS(converge_time_s); // out: NetworkOPs
|
||||
JSS(cookie); // out: NetworkOPs
|
||||
@@ -249,9 +248,6 @@ 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(extension_compute); // out: NetworkOPs
|
||||
JSS(extension_size); // out: NetworkOPs
|
||||
JSS(gas_price); // out: NetworkOPs
|
||||
JSS(fail_hard); // in: Sign, Submit
|
||||
JSS(failed); // out: InboundLedger
|
||||
JSS(feature); // in: Feature
|
||||
@@ -271,8 +267,6 @@ JSS(flags); // out: AccountOffers, NetworkOPs
|
||||
JSS(forward); // in: AccountTx
|
||||
JSS(freeze); // out: AccountLines
|
||||
JSS(freeze_peer); // out: AccountLines
|
||||
JSS(function); // in: ContractInfo
|
||||
JSS(functions); // out: ContractInfo
|
||||
JSS(deep_freeze); // out: AccountLines
|
||||
JSS(deep_freeze_peer); // out: AccountLines
|
||||
JSS(frozen_balances); // out: GatewayBalances
|
||||
@@ -554,7 +548,6 @@ JSS(size); // out: get_aggregate_price
|
||||
JSS(snapshot); // in: Subscribe
|
||||
JSS(source_account); // in: PathRequest, RipplePathFind
|
||||
JSS(source_amount); // in: PathRequest, RipplePathFind
|
||||
JSS(source_code_uri); // out: ContractInfo
|
||||
JSS(source_currencies); // in: PathRequest, RipplePathFind
|
||||
JSS(source_tag); // out: AccountChannels
|
||||
JSS(stand_alone); // out: NetworkOPs
|
||||
@@ -652,7 +645,6 @@ JSS(url); // in/out: Subscribe, Unsubscribe
|
||||
JSS(url_password); // in: Subscribe
|
||||
JSS(url_username); // in: Subscribe
|
||||
JSS(urlgravatar); //
|
||||
JSS(user_data); // out: ContractInfo
|
||||
JSS(username); // in: Subscribe
|
||||
JSS(validated); // out: NetworkOPs, RPCHelpers, AccountTx*, Tx
|
||||
JSS(validator_list_expires); // out: NetworkOps, ValidatorList
|
||||
|
||||
@@ -7,12 +7,7 @@
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STDataType.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
|
||||
@@ -518,30 +518,6 @@ public:
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfLoanBrokerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractID (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getContractID() const
|
||||
{
|
||||
if (hasContractID())
|
||||
return this->sle_->at(sfContractID);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractID is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractID() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfContractID);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -843,17 +819,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractID (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
AccountRootBuilder&
|
||||
setContractID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed AccountRoot wrapper.
|
||||
* @param index The ledger entry index.
|
||||
|
||||
@@ -1,334 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::ledger_entries {
|
||||
|
||||
class ContractBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: Contract
|
||||
*
|
||||
* Type: ltCONTRACT (0x0086)
|
||||
* RPC Name: contract
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use ContractBuilder to construct new ledger entries.
|
||||
*/
|
||||
class Contract : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltCONTRACT;
|
||||
|
||||
/**
|
||||
* @brief Construct a Contract ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit Contract(std::shared_ptr<SLE const> sle)
|
||||
: LedgerEntryBase(std::move(sle))
|
||||
{
|
||||
// Verify ledger entry type
|
||||
if (sle_->getType() != entryType)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Contract");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnID (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getPreviousTxnID() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getPreviousTxnLgrSeq() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSequence (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getSequence() const
|
||||
{
|
||||
return this->sle_->at(sfSequence);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwner (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOwner() const
|
||||
{
|
||||
return this->sle_->at(sfOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getContractAccount() const
|
||||
{
|
||||
return this->sle_->at(sfContractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractHash (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getContractHash() const
|
||||
{
|
||||
return this->sle_->at(sfContractHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfInstanceParameterValues (soeOPTIONAL)
|
||||
* @note This is an untyped field (unknown).
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getInstanceParameterValues() const
|
||||
{
|
||||
if (this->sle_->isFieldPresent(sfInstanceParameterValues))
|
||||
return this->sle_->getFieldArray(sfInstanceParameterValues);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfInstanceParameterValues is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasInstanceParameterValues() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfInstanceParameterValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfURI (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getURI() const
|
||||
{
|
||||
if (hasURI())
|
||||
return this->sle_->at(sfURI);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfURI is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasURI() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfURI);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for Contract ledger entries.
|
||||
*
|
||||
* Provides a fluent interface for constructing ledger entries with method chaining.
|
||||
* Uses Json::Value internally for flexible ledger entry construction.
|
||||
* Inherits common field setters from LedgerEntryBuilderBase.
|
||||
*/
|
||||
class ContractBuilder : public LedgerEntryBuilderBase<ContractBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractBuilder with required fields.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
* @param sequence The sfSequence field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param owner The sfOwner field value.
|
||||
* @param contractAccount The sfContractAccount field value.
|
||||
* @param contractHash The sfContractHash field value.
|
||||
*/
|
||||
ContractBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT32::type::value_type> const& sequence,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount,std::decay_t<typename SF_UINT256::type::value_type> const& contractHash)
|
||||
: LedgerEntryBuilderBase<ContractBuilder>(ltCONTRACT)
|
||||
{
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
setSequence(sequence);
|
||||
setOwnerNode(ownerNode);
|
||||
setOwner(owner);
|
||||
setContractAccount(contractAccount);
|
||||
setContractHash(contractHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractBuilder from an existing SLE object.
|
||||
* @param sle The existing ledger entry to copy from.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
ContractBuilder(std::shared_ptr<SLE const> sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltCONTRACT)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for Contract");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/** @brief Ledger entry-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSequence (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setSequence(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfSequence] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwner (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwner] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractHash (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractHash] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfInstanceParameterValues (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setInstanceParameterValues(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfInstanceParameterValues, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfURI (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractBuilder&
|
||||
setURI(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfURI] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed Contract wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
Contract
|
||||
build(uint256 const& index)
|
||||
{
|
||||
return Contract{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
@@ -1,239 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::ledger_entries {
|
||||
|
||||
class ContractDataBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: ContractData
|
||||
*
|
||||
* Type: ltCONTRACT_DATA (0x0087)
|
||||
* RPC Name: contract_data
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use ContractDataBuilder to construct new ledger entries.
|
||||
*/
|
||||
class ContractData : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltCONTRACT_DATA;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractData ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit ContractData(std::shared_ptr<SLE const> sle)
|
||||
: LedgerEntryBase(std::move(sle))
|
||||
{
|
||||
// Verify ledger entry type
|
||||
if (sle_->getType() != entryType)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for ContractData");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnID (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getPreviousTxnID() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getPreviousTxnLgrSeq() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwner (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOwner() const
|
||||
{
|
||||
return this->sle_->at(sfOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getContractAccount() const
|
||||
{
|
||||
return this->sle_->at(sfContractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractJson (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_JSON::type::value_type
|
||||
getContractJson() const
|
||||
{
|
||||
return this->sle_->at(sfContractJson);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractData ledger entries.
|
||||
*
|
||||
* Provides a fluent interface for constructing ledger entries with method chaining.
|
||||
* Uses Json::Value internally for flexible ledger entry construction.
|
||||
* Inherits common field setters from LedgerEntryBuilderBase.
|
||||
*/
|
||||
class ContractDataBuilder : public LedgerEntryBuilderBase<ContractDataBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractDataBuilder with required fields.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param owner The sfOwner field value.
|
||||
* @param contractAccount The sfContractAccount field value.
|
||||
* @param contractJson The sfContractJson field value.
|
||||
*/
|
||||
ContractDataBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount,std::decay_t<typename SF_JSON::type::value_type> const& contractJson)
|
||||
: LedgerEntryBuilderBase<ContractDataBuilder>(ltCONTRACT_DATA)
|
||||
{
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
setOwnerNode(ownerNode);
|
||||
setOwner(owner);
|
||||
setContractAccount(contractAccount);
|
||||
setContractJson(contractJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractDataBuilder from an existing SLE object.
|
||||
* @param sle The existing ledger entry to copy from.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
ContractDataBuilder(std::shared_ptr<SLE const> sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltCONTRACT_DATA)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for ContractData");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/** @brief Ledger entry-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDataBuilder&
|
||||
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDataBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDataBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwner (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDataBuilder&
|
||||
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwner] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDataBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractJson (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDataBuilder&
|
||||
setContractJson(std::decay_t<typename SF_JSON::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractJson] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed ContractData wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
ContractData
|
||||
build(uint256 const& index)
|
||||
{
|
||||
return ContractData{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
@@ -1,276 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::ledger_entries {
|
||||
|
||||
class ContractSourceBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: ContractSource
|
||||
*
|
||||
* Type: ltCONTRACT_SOURCE (0x0085)
|
||||
* RPC Name: contract_source
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use ContractSourceBuilder to construct new ledger entries.
|
||||
*/
|
||||
class ContractSource : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltCONTRACT_SOURCE;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractSource ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit ContractSource(std::shared_ptr<SLE const> sle)
|
||||
: LedgerEntryBase(std::move(sle))
|
||||
{
|
||||
// Verify ledger entry type
|
||||
if (sle_->getType() != entryType)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for ContractSource");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnID (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getPreviousTxnID() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getPreviousTxnLgrSeq() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractHash (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getContractHash() const
|
||||
{
|
||||
return this->sle_->at(sfContractHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractCode (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getContractCode() const
|
||||
{
|
||||
return this->sle_->at(sfContractCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFunctions (soeREQUIRED)
|
||||
* @note This is an untyped field (unknown).
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
STArray const&
|
||||
getFunctions() const
|
||||
{
|
||||
return this->sle_->getFieldArray(sfFunctions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfInstanceParameters (soeOPTIONAL)
|
||||
* @note This is an untyped field (unknown).
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getInstanceParameters() const
|
||||
{
|
||||
if (this->sle_->isFieldPresent(sfInstanceParameters))
|
||||
return this->sle_->getFieldArray(sfInstanceParameters);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfInstanceParameters is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasInstanceParameters() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfInstanceParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfReferenceCount (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getReferenceCount() const
|
||||
{
|
||||
return this->sle_->at(sfReferenceCount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractSource ledger entries.
|
||||
*
|
||||
* Provides a fluent interface for constructing ledger entries with method chaining.
|
||||
* Uses Json::Value internally for flexible ledger entry construction.
|
||||
* Inherits common field setters from LedgerEntryBuilderBase.
|
||||
*/
|
||||
class ContractSourceBuilder : public LedgerEntryBuilderBase<ContractSourceBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractSourceBuilder with required fields.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
* @param contractHash The sfContractHash field value.
|
||||
* @param contractCode The sfContractCode field value.
|
||||
* @param functions The sfFunctions field value.
|
||||
* @param referenceCount The sfReferenceCount field value.
|
||||
*/
|
||||
ContractSourceBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT256::type::value_type> const& contractHash,std::decay_t<typename SF_VL::type::value_type> const& contractCode,STArray const& functions,std::decay_t<typename SF_UINT64::type::value_type> const& referenceCount)
|
||||
: LedgerEntryBuilderBase<ContractSourceBuilder>(ltCONTRACT_SOURCE)
|
||||
{
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
setContractHash(contractHash);
|
||||
setContractCode(contractCode);
|
||||
setFunctions(functions);
|
||||
setReferenceCount(referenceCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractSourceBuilder from an existing SLE object.
|
||||
* @param sle The existing ledger entry to copy from.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
ContractSourceBuilder(std::shared_ptr<SLE const> sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltCONTRACT_SOURCE)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for ContractSource");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/** @brief Ledger entry-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnLgrSeq (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractHash (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractHash] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractCode (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setContractCode(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractCode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFunctions (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setFunctions(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfFunctions, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfInstanceParameters (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setInstanceParameters(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfInstanceParameters, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfReferenceCount (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractSourceBuilder&
|
||||
setReferenceCount(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfReferenceCount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed ContractSource wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
ContractSource
|
||||
build(uint256 const& index)
|
||||
{
|
||||
return ContractSource{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
@@ -174,54 +174,6 @@ public:
|
||||
return this->sle_->isFieldPresent(sfFinishAfter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFinishFunction (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getFinishFunction() const
|
||||
{
|
||||
if (hasFinishFunction())
|
||||
return this->sle_->at(sfFinishFunction);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFinishFunction is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFinishFunction() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfFinishFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfData (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getData() const
|
||||
{
|
||||
if (hasData())
|
||||
return this->sle_->at(sfData);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfData is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasData() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfSourceTag (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
@@ -499,28 +451,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFinishFunction (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
EscrowBuilder&
|
||||
setFinishFunction(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFinishFunction] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfData (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
EscrowBuilder&
|
||||
setData(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfData] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfSourceTag (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
|
||||
@@ -213,78 +213,6 @@ public:
|
||||
return this->sle_->isFieldPresent(sfReserveIncrementDrops);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfExtensionComputeLimit (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getExtensionComputeLimit() const
|
||||
{
|
||||
if (hasExtensionComputeLimit())
|
||||
return this->sle_->at(sfExtensionComputeLimit);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfExtensionComputeLimit is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasExtensionComputeLimit() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfExtensionComputeLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfExtensionSizeLimit (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getExtensionSizeLimit() const
|
||||
{
|
||||
if (hasExtensionSizeLimit())
|
||||
return this->sle_->at(sfExtensionSizeLimit);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfExtensionSizeLimit is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasExtensionSizeLimit() const
|
||||
{
|
||||
return this->sle_->isFieldPresent(sfExtensionSizeLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
@@ -445,39 +373,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfExtensionComputeLimit (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
FeeSettingsBuilder&
|
||||
setExtensionComputeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfExtensionComputeLimit] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfExtensionSizeLimit (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
FeeSettingsBuilder&
|
||||
setExtensionSizeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfExtensionSizeLimit] = 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.
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class ContractCallBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: ContractCall
|
||||
*
|
||||
* Type: ttCONTRACT_CALL (90)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: noPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractCallBuilder to construct new transactions.
|
||||
*/
|
||||
class ContractCall : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttCONTRACT_CALL;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractCall transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit ContractCall(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractCall");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getContractAccount() const
|
||||
{
|
||||
return this->tx_->at(sfContractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFunctionName (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getFunctionName() const
|
||||
{
|
||||
return this->tx_->at(sfFunctionName);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfParameters (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getParameters() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfParameters))
|
||||
return this->tx_->getFieldArray(sfParameters);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfParameters is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasParameters() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfComputationAllowance (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getComputationAllowance() const
|
||||
{
|
||||
return this->tx_->at(sfComputationAllowance);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractCall transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class ContractCallBuilder : public TransactionBuilderBase<ContractCallBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractCallBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param contractAccount The sfContractAccount field value.
|
||||
* @param functionName The sfFunctionName field value.
|
||||
* @param computationAllowance The sfComputationAllowance field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
ContractCallBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount, std::decay_t<typename SF_VL::type::value_type> const& functionName, std::decay_t<typename SF_UINT32::type::value_type> const& computationAllowance, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<ContractCallBuilder>(ttCONTRACT_CALL, account, sequence, fee)
|
||||
{
|
||||
setContractAccount(contractAccount);
|
||||
setFunctionName(functionName);
|
||||
setComputationAllowance(computationAllowance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractCallBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
ContractCallBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttCONTRACT_CALL)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractCallBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCallBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFunctionName (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCallBuilder&
|
||||
setFunctionName(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFunctionName] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfParameters (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCallBuilder&
|
||||
setParameters(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfParameters, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfComputationAllowance (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCallBuilder&
|
||||
setComputationAllowance(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfComputationAllowance] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the ContractCall wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
ContractCall
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return ContractCall{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,168 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class ContractClawbackBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: ContractClawback
|
||||
*
|
||||
* Type: ttCONTRACT_CLAWBACK (88)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: noPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractClawbackBuilder to construct new transactions.
|
||||
*/
|
||||
class ContractClawback : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttCONTRACT_CLAWBACK;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractClawback transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit ContractClawback(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractClawback");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getContractAccount() const
|
||||
{
|
||||
if (hasContractAccount())
|
||||
{
|
||||
return this->tx_->at(sfContractAccount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractAccount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractAccount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfContractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAmount (soeREQUIRED)
|
||||
* @note This field supports MPT (Multi-Purpose Token) amounts.
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_AMOUNT::type::value_type
|
||||
getAmount() const
|
||||
{
|
||||
return this->tx_->at(sfAmount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractClawback transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class ContractClawbackBuilder : public TransactionBuilderBase<ContractClawbackBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractClawbackBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param amount The sfAmount field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
ContractClawbackBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_AMOUNT::type::value_type> const& amount, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<ContractClawbackBuilder>(ttCONTRACT_CLAWBACK, account, sequence, fee)
|
||||
{
|
||||
setAmount(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractClawbackBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
ContractClawbackBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttCONTRACT_CLAWBACK)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractClawbackBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractClawbackBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (soeREQUIRED)
|
||||
* @note This field supports MPT (Multi-Purpose Token) amounts.
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractClawbackBuilder&
|
||||
setAmount(std::decay_t<typename SF_AMOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfAmount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the ContractClawback wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
ContractClawback
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return ContractClawback{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,321 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class ContractCreateBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: ContractCreate
|
||||
*
|
||||
* Type: ttCONTRACT_CREATE (85)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: createPseudoAcct
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractCreateBuilder to construct new transactions.
|
||||
*/
|
||||
class ContractCreate : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttCONTRACT_CREATE;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractCreate transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit ContractCreate(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractCreate");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfContractCode (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getContractCode() const
|
||||
{
|
||||
if (hasContractCode())
|
||||
{
|
||||
return this->tx_->at(sfContractCode);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractCode is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractCode() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfContractCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractHash (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getContractHash() const
|
||||
{
|
||||
if (hasContractHash())
|
||||
{
|
||||
return this->tx_->at(sfContractHash);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractHash is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractHash() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfContractHash);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfFunctions (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getFunctions() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfFunctions))
|
||||
return this->tx_->getFieldArray(sfFunctions);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFunctions is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFunctions() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfFunctions);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfInstanceParameters (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getInstanceParameters() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfInstanceParameters))
|
||||
return this->tx_->getFieldArray(sfInstanceParameters);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfInstanceParameters is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasInstanceParameters() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfInstanceParameters);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfInstanceParameterValues (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getInstanceParameterValues() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfInstanceParameterValues))
|
||||
return this->tx_->getFieldArray(sfInstanceParameterValues);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfInstanceParameterValues is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasInstanceParameterValues() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfInstanceParameterValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfURI (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getURI() const
|
||||
{
|
||||
if (hasURI())
|
||||
{
|
||||
return this->tx_->at(sfURI);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfURI is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasURI() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfURI);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractCreate transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class ContractCreateBuilder : public TransactionBuilderBase<ContractCreateBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractCreateBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
ContractCreateBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<ContractCreateBuilder>(ttCONTRACT_CREATE, account, sequence, fee)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractCreateBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
ContractCreateBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttCONTRACT_CREATE)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractCreateBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfContractCode (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCreateBuilder&
|
||||
setContractCode(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractCode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractHash (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCreateBuilder&
|
||||
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractHash] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFunctions (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCreateBuilder&
|
||||
setFunctions(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfFunctions, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfInstanceParameters (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCreateBuilder&
|
||||
setInstanceParameters(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfInstanceParameters, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfInstanceParameterValues (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCreateBuilder&
|
||||
setInstanceParameterValues(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfInstanceParameterValues, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfURI (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractCreateBuilder&
|
||||
setURI(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfURI] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the ContractCreate wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
ContractCreate
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return ContractCreate{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,129 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class ContractDeleteBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: ContractDelete
|
||||
*
|
||||
* Type: ttCONTRACT_DELETE (87)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: mustDeleteAcct
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractDeleteBuilder to construct new transactions.
|
||||
*/
|
||||
class ContractDelete : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttCONTRACT_DELETE;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractDelete transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit ContractDelete(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractDelete");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getContractAccount() const
|
||||
{
|
||||
return this->tx_->at(sfContractAccount);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractDelete transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class ContractDeleteBuilder : public TransactionBuilderBase<ContractDeleteBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractDeleteBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param contractAccount The sfContractAccount field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
ContractDeleteBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<ContractDeleteBuilder>(ttCONTRACT_DELETE, account, sequence, fee)
|
||||
{
|
||||
setContractAccount(contractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractDeleteBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
ContractDeleteBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttCONTRACT_DELETE)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractDeleteBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractDeleteBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the ContractDelete wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
ContractDelete
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return ContractDelete{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,395 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class ContractModifyBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: ContractModify
|
||||
*
|
||||
* Type: ttCONTRACT_MODIFY (86)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: noPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractModifyBuilder to construct new transactions.
|
||||
*/
|
||||
class ContractModify : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttCONTRACT_MODIFY;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractModify transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit ContractModify(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractModify");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getContractAccount() const
|
||||
{
|
||||
if (hasContractAccount())
|
||||
{
|
||||
return this->tx_->at(sfContractAccount);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractAccount is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractAccount() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfContractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwner (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_ACCOUNT::type::value_type>
|
||||
getOwner() const
|
||||
{
|
||||
if (hasOwner())
|
||||
{
|
||||
return this->tx_->at(sfOwner);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfOwner is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasOwner() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractCode (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getContractCode() const
|
||||
{
|
||||
if (hasContractCode())
|
||||
{
|
||||
return this->tx_->at(sfContractCode);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractCode is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractCode() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfContractCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfContractHash (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT256::type::value_type>
|
||||
getContractHash() const
|
||||
{
|
||||
if (hasContractHash())
|
||||
{
|
||||
return this->tx_->at(sfContractHash);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfContractHash is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasContractHash() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfContractHash);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfFunctions (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getFunctions() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfFunctions))
|
||||
return this->tx_->getFieldArray(sfFunctions);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFunctions is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFunctions() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfFunctions);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfInstanceParameters (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getInstanceParameters() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfInstanceParameters))
|
||||
return this->tx_->getFieldArray(sfInstanceParameters);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfInstanceParameters is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasInstanceParameters() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfInstanceParameters);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfInstanceParameterValues (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getInstanceParameterValues() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfInstanceParameterValues))
|
||||
return this->tx_->getFieldArray(sfInstanceParameterValues);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfInstanceParameterValues is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasInstanceParameterValues() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfInstanceParameterValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfURI (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getURI() const
|
||||
{
|
||||
if (hasURI())
|
||||
{
|
||||
return this->tx_->at(sfURI);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfURI is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasURI() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfURI);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractModify transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class ContractModifyBuilder : public TransactionBuilderBase<ContractModifyBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractModifyBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
ContractModifyBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<ContractModifyBuilder>(ttCONTRACT_MODIFY, account, sequence, fee)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractModifyBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
ContractModifyBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttCONTRACT_MODIFY)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractModifyBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwner (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwner] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractCode (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setContractCode(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractCode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfContractHash (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setContractHash(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractHash] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFunctions (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setFunctions(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfFunctions, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfInstanceParameters (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setInstanceParameters(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfInstanceParameters, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfInstanceParameterValues (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setInstanceParameterValues(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfInstanceParameterValues, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfURI (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractModifyBuilder&
|
||||
setURI(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfURI] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the ContractModify wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
ContractModify
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return ContractModify{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -1,212 +0,0 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class ContractUserDeleteBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: ContractUserDelete
|
||||
*
|
||||
* Type: ttCONTRACT_USER_DELETE (89)
|
||||
* Delegable: Delegation::delegable
|
||||
* Amendment: featureSmartContract
|
||||
* Privileges: noPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use ContractUserDeleteBuilder to construct new transactions.
|
||||
*/
|
||||
class ContractUserDelete : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttCONTRACT_USER_DELETE;
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractUserDelete transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit ContractUserDelete(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractUserDelete");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfContractAccount (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getContractAccount() const
|
||||
{
|
||||
return this->tx_->at(sfContractAccount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFunctionName (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_VL::type::value_type
|
||||
getFunctionName() const
|
||||
{
|
||||
return this->tx_->at(sfFunctionName);
|
||||
}
|
||||
/**
|
||||
* @brief Get sfParameters (soeOPTIONAL)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
std::optional<std::reference_wrapper<STArray const>>
|
||||
getParameters() const
|
||||
{
|
||||
if (this->tx_->isFieldPresent(sfParameters))
|
||||
return this->tx_->getFieldArray(sfParameters);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfParameters is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasParameters() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfComputationAllowance (soeREQUIRED)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getComputationAllowance() const
|
||||
{
|
||||
return this->tx_->at(sfComputationAllowance);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for ContractUserDelete transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses Json::Value internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class ContractUserDeleteBuilder : public TransactionBuilderBase<ContractUserDeleteBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new ContractUserDeleteBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param contractAccount The sfContractAccount field value.
|
||||
* @param functionName The sfFunctionName field value.
|
||||
* @param computationAllowance The sfComputationAllowance field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
ContractUserDeleteBuilder(SF_ACCOUNT::type::value_type account,
|
||||
std::decay_t<typename SF_ACCOUNT::type::value_type> const& contractAccount, std::decay_t<typename SF_VL::type::value_type> const& functionName, std::decay_t<typename SF_UINT32::type::value_type> const& computationAllowance, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<ContractUserDeleteBuilder>(ttCONTRACT_USER_DELETE, account, sequence, fee)
|
||||
{
|
||||
setContractAccount(contractAccount);
|
||||
setFunctionName(functionName);
|
||||
setComputationAllowance(computationAllowance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a ContractUserDeleteBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
ContractUserDeleteBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttCONTRACT_USER_DELETE)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for ContractUserDeleteBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/** @brief Transaction-specific field setters */
|
||||
|
||||
/**
|
||||
* @brief Set sfContractAccount (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractUserDeleteBuilder&
|
||||
setContractAccount(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfContractAccount] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFunctionName (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractUserDeleteBuilder&
|
||||
setFunctionName(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFunctionName] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfParameters (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractUserDeleteBuilder&
|
||||
setParameters(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfParameters, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfComputationAllowance (soeREQUIRED)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
ContractUserDeleteBuilder&
|
||||
setComputationAllowance(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfComputationAllowance] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the ContractUserDelete wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
ContractUserDelete
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return ContractUserDelete{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
@@ -58,32 +58,6 @@ public:
|
||||
return this->tx_->at(sfDestination);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfDestinationTag (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getDestinationTag() const
|
||||
{
|
||||
if (hasDestinationTag())
|
||||
{
|
||||
return this->tx_->at(sfDestinationTag);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfDestinationTag is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasDestinationTag() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfDestinationTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfAmount (soeREQUIRED)
|
||||
* @note This field supports MPT (Multi-Purpose Token) amounts.
|
||||
@@ -175,55 +149,29 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfFinishFunction (soeOPTIONAL)
|
||||
* @brief Get sfDestinationTag (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getFinishFunction() const
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getDestinationTag() const
|
||||
{
|
||||
if (hasFinishFunction())
|
||||
if (hasDestinationTag())
|
||||
{
|
||||
return this->tx_->at(sfFinishFunction);
|
||||
return this->tx_->at(sfDestinationTag);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfFinishFunction is present.
|
||||
* @brief Check if sfDestinationTag is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasFinishFunction() const
|
||||
hasDestinationTag() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfFinishFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfData (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_VL::type::value_type>
|
||||
getData() const
|
||||
{
|
||||
if (hasData())
|
||||
{
|
||||
return this->tx_->at(sfData);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfData is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasData() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfData);
|
||||
return this->tx_->isFieldPresent(sfDestinationTag);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -282,17 +230,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfDestinationTag (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
EscrowCreateBuilder&
|
||||
setDestinationTag(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfDestinationTag] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfAmount (soeREQUIRED)
|
||||
* @note This field supports MPT (Multi-Purpose Token) amounts.
|
||||
@@ -339,24 +276,13 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfFinishFunction (soeOPTIONAL)
|
||||
* @brief Set sfDestinationTag (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
EscrowCreateBuilder&
|
||||
setFinishFunction(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
setDestinationTag(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfFinishFunction] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfData (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
EscrowCreateBuilder&
|
||||
setData(std::decay_t<typename SF_VL::type::value_type> const& value)
|
||||
{
|
||||
object_[sfData] = value;
|
||||
object_[sfDestinationTag] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -146,32 +146,6 @@ public:
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfCredentialIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfComputationAllowance (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getComputationAllowance() const
|
||||
{
|
||||
if (hasComputationAllowance())
|
||||
{
|
||||
return this->tx_->at(sfComputationAllowance);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfComputationAllowance is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasComputationAllowance() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfComputationAllowance);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -273,17 +247,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfComputationAllowance (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
EscrowFinishBuilder&
|
||||
setComputationAllowance(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfComputationAllowance] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the EscrowFinish wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
|
||||
@@ -254,84 +254,6 @@ public:
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfReserveIncrementDrops);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfExtensionComputeLimit (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getExtensionComputeLimit() const
|
||||
{
|
||||
if (hasExtensionComputeLimit())
|
||||
{
|
||||
return this->tx_->at(sfExtensionComputeLimit);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfExtensionComputeLimit is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasExtensionComputeLimit() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfExtensionComputeLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfExtensionSizeLimit (soeOPTIONAL)
|
||||
* @return The field value, or std::nullopt if not present.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
protocol_autogen::Optional<SF_UINT32::type::value_type>
|
||||
getExtensionSizeLimit() const
|
||||
{
|
||||
if (hasExtensionSizeLimit())
|
||||
{
|
||||
return this->tx_->at(sfExtensionSizeLimit);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if sfExtensionSizeLimit is present.
|
||||
* @return True if the field is present, false otherwise.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
bool
|
||||
hasExtensionSizeLimit() const
|
||||
{
|
||||
return this->tx_->isFieldPresent(sfExtensionSizeLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -462,39 +384,6 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfExtensionComputeLimit (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SetFeeBuilder&
|
||||
setExtensionComputeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfExtensionComputeLimit] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfExtensionSizeLimit (soeOPTIONAL)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
SetFeeBuilder&
|
||||
setExtensionSizeLimit(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfExtensionSizeLimit] = 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.
|
||||
|
||||
@@ -148,11 +148,6 @@ public:
|
||||
virtual bool
|
||||
unsubConsensus(std::uint64_t uListener) = 0;
|
||||
|
||||
virtual bool
|
||||
subContractEvent(ref ispListener) = 0;
|
||||
virtual bool
|
||||
unsubContractEvent(std::uint64_t uListener) = 0;
|
||||
|
||||
// VFALCO TODO Remove
|
||||
// This was added for one particular partner, it
|
||||
// "pushes" subscription data to a particular URL.
|
||||
|
||||
@@ -247,9 +247,6 @@ public:
|
||||
virtual void
|
||||
pubValidation(std::shared_ptr<STValidation> const& val) = 0;
|
||||
|
||||
virtual void
|
||||
pubContractEvent(std::string const& name, STJson const& event) = 0;
|
||||
|
||||
virtual void
|
||||
stateAccounting(Json::Value& obj) = 0;
|
||||
};
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyViewImpl.h>
|
||||
#include <xrpl/ledger/OpenViewSandbox.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -45,12 +43,6 @@ public:
|
||||
XRPAmount const baseFee;
|
||||
beast::Journal const journal;
|
||||
|
||||
OpenView&
|
||||
openView()
|
||||
{
|
||||
return base_.view();
|
||||
}
|
||||
|
||||
ApplyView&
|
||||
view()
|
||||
{
|
||||
@@ -83,41 +75,10 @@ public:
|
||||
view_->deliver(amount);
|
||||
}
|
||||
|
||||
/** Sets the gas used in the metadata */
|
||||
void
|
||||
setGasUsed(std::uint32_t const gasUsed)
|
||||
{
|
||||
gasUsed_ = gasUsed;
|
||||
}
|
||||
|
||||
/** Sets the gas used in the metadata */
|
||||
void
|
||||
setWasmReturnCode(std::int32_t const wasmReturnCode)
|
||||
{
|
||||
wasmReturnCode_ = wasmReturnCode;
|
||||
}
|
||||
|
||||
/** Sets the gas used in the metadata */
|
||||
void
|
||||
setEmittedTxns(std::queue<std::shared_ptr<STTx const>> const emittedTxns)
|
||||
{
|
||||
emittedTxns_ = emittedTxns;
|
||||
}
|
||||
|
||||
std::queue<std::shared_ptr<STTx const>>
|
||||
getEmittedTxns()
|
||||
{
|
||||
return emittedTxns_;
|
||||
}
|
||||
|
||||
/** Discard changes and start fresh. */
|
||||
void
|
||||
discard();
|
||||
|
||||
/** Finalize changes. */
|
||||
void
|
||||
finalize();
|
||||
|
||||
/** Apply the transaction result to the base. */
|
||||
std::optional<TxMeta> apply(TER);
|
||||
|
||||
@@ -157,13 +118,11 @@ private:
|
||||
TER
|
||||
checkInvariantsHelper(TER const result, XRPAmount const fee, std::index_sequence<Is...>);
|
||||
|
||||
OpenViewSandbox base_;
|
||||
OpenView& base_;
|
||||
ApplyFlags flags_;
|
||||
std::optional<ApplyViewImpl> view_;
|
||||
|
||||
std::optional<std::uint32_t> gasUsed_;
|
||||
std::optional<std::int32_t> wasmReturnCode_;
|
||||
std::queue<std::shared_ptr<STTx const>> emittedTxns_;
|
||||
// The ID of the batch transaction we are executing under, if seated.
|
||||
std::optional<uint256 const> parentBatchId_;
|
||||
};
|
||||
|
||||
|
||||
@@ -297,9 +297,6 @@ private:
|
||||
std::pair<TER, XRPAmount>
|
||||
reset(XRPAmount fee);
|
||||
|
||||
std::pair<TER, XRPAmount>
|
||||
checkInvariants(TER result, XRPAmount fee);
|
||||
|
||||
TER
|
||||
consumeSeqProxy(SLE::pointer const& sleAccount);
|
||||
TER
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class Application;
|
||||
|
||||
class HashRouter;
|
||||
class ServiceRegistry;
|
||||
|
||||
@@ -104,24 +102,6 @@ apply(
|
||||
ApplyFlags flags,
|
||||
beast::Journal journal);
|
||||
|
||||
ApplyResult
|
||||
apply(
|
||||
ServiceRegistry& registry,
|
||||
OpenView& view,
|
||||
uint256 const& parentBatchId,
|
||||
STTx const& tx,
|
||||
ApplyFlags flags,
|
||||
beast::Journal j);
|
||||
|
||||
ApplyResult
|
||||
apply(
|
||||
Application& app,
|
||||
OpenView& view,
|
||||
uint256 const& parentBatchId,
|
||||
STTx const& tx,
|
||||
ApplyFlags flags,
|
||||
beast::Journal j);
|
||||
|
||||
/** Enum class for return value from `applyTransaction`
|
||||
|
||||
@see applyTransaction
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Define a function pointer type that can be used to delete ledger node types.
|
||||
using DeleterFuncPtr = TER (*)(
|
||||
ServiceRegistry& registry,
|
||||
ApplyView& view,
|
||||
AccountID const& account,
|
||||
uint256 const& delIndex,
|
||||
std::shared_ptr<SLE> const& sleDel,
|
||||
beast::Journal j);
|
||||
|
||||
DeleterFuncPtr
|
||||
nonObligationDeleter(LedgerEntryType t);
|
||||
|
||||
TER
|
||||
deletePreclaim(
|
||||
PreclaimContext const& ctx,
|
||||
std::uint32_t seqDelta,
|
||||
AccountID const account,
|
||||
AccountID const dest,
|
||||
bool isPseudoAccount = false);
|
||||
|
||||
TER
|
||||
deleteDoApply(
|
||||
ApplyContext& applyCtx,
|
||||
STAmount const& accountBalance,
|
||||
AccountID const& account,
|
||||
AccountID const& dest);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractCall : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ContractCall(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractClawback : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ContractClawback(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,32 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractCreate : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ContractCreate(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static std::uint32_t
|
||||
getFlagsMask(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractDelete : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ContractDelete(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
// Interface used by DeleteAccount
|
||||
static TER
|
||||
deleteContract(
|
||||
ApplyView& view,
|
||||
std::shared_ptr<SLE> const& sle,
|
||||
AccountID const& account,
|
||||
beast::Journal j);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractModify : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ContractModify(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class ContractUserDelete : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ContractUserDelete(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -13,21 +13,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static bool
|
||||
checkExtraFeatures(PreflightContext const& ctx);
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflightSigValidated(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/helpers/NFTokenUtils.h>
|
||||
#include <xrpl/protocol/nft.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/transactors/nft/NFTokenUtils.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/nft.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -140,13 +140,6 @@ checkTrustlineDeepFrozen(
|
||||
beast::Journal const j,
|
||||
Issue const& issue);
|
||||
|
||||
TER
|
||||
transferNFToken(
|
||||
ApplyView& view,
|
||||
AccountID const& buyer,
|
||||
AccountID const& seller,
|
||||
uint256 const& nftokenID);
|
||||
|
||||
} // namespace nft
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/helpers/ContractUtils.h>
|
||||
#include <xrpl/protocol/st.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
|
||||
#include <queue>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
struct ParameterValueVec
|
||||
{
|
||||
STData const value;
|
||||
};
|
||||
|
||||
struct FunctionParameterValueVecWithName
|
||||
{
|
||||
Blob const name;
|
||||
STData const value;
|
||||
};
|
||||
|
||||
struct ParameterTypeVec
|
||||
{
|
||||
STDataType const type;
|
||||
};
|
||||
|
||||
std::vector<ParameterValueVec>
|
||||
getParameterValueVec(STArray const& functionParameters);
|
||||
|
||||
std::vector<ParameterTypeVec>
|
||||
getParameterTypeVec(STArray const& functionParameters);
|
||||
|
||||
enum ExitType : uint8_t {
|
||||
UNSET = 0,
|
||||
WASM_ERROR = 1,
|
||||
ROLLBACK = 2,
|
||||
ACCEPT = 3,
|
||||
};
|
||||
|
||||
struct ContractResult
|
||||
{
|
||||
uint256 const contractHash; // Hash of the contract code
|
||||
Keylet const contractKeylet; // Keylet for the contract instance
|
||||
Keylet const contractSourceKeylet; // Keylet for the contract source
|
||||
Keylet const contractAccountKeylet; // Keylet for the contract account
|
||||
AccountID const contractAccount; // AccountID of the contract account
|
||||
std::uint32_t nextSequence; // Next sequence number for the contract account
|
||||
AccountID const otxnAccount; // AccountID for the originating transaction
|
||||
uint256 const otxnId; // ID for the originating transaction
|
||||
std::string exitReason{""};
|
||||
int64_t exitCode{-1};
|
||||
ContractDataMap dataMap;
|
||||
ContractEventMap eventMap;
|
||||
std::queue<std::shared_ptr<STTx const>> emittedTxns{};
|
||||
std::size_t changedDataCount{0};
|
||||
};
|
||||
|
||||
struct ContractContext
|
||||
{
|
||||
ApplyContext& applyCtx;
|
||||
std::vector<ParameterValueVec> instanceParameters;
|
||||
std::vector<ParameterValueVec> functionParameters;
|
||||
std::vector<STObject> built_txns;
|
||||
int64_t expected_etxn_count{-1}; // expected emitted transaction count
|
||||
std::map<uint256, bool> nonce_used{}; // nonces used in this execution
|
||||
uint32_t generation = 0; // generation of the contract being executed
|
||||
uint64_t burden = 0; // computational burden used
|
||||
ContractResult result;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,95 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/ContractContext.h>
|
||||
#include <xrpl/tx/wasm/HostFunc.h>
|
||||
#include <xrpl/tx/wasm/HostFuncImpl.h>
|
||||
|
||||
namespace xrpl {
|
||||
class ContractHostFunctionsImpl : public WasmHostFunctionsImpl
|
||||
{
|
||||
ContractContext& contractCtx;
|
||||
uint256 const contractId = contractCtx.result.contractKeylet.key;
|
||||
|
||||
public:
|
||||
// Constructor for contract-specific functionality
|
||||
ContractHostFunctionsImpl(ContractContext& contractContext)
|
||||
: WasmHostFunctionsImpl(contractContext.applyCtx, contractContext.result.contractKeylet)
|
||||
, contractCtx(contractContext)
|
||||
{
|
||||
}
|
||||
|
||||
// Expected<Bytes, HostFunctionError>
|
||||
// getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t
|
||||
// stTypeId);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
instanceParam(std::uint32_t index, std::uint32_t stTypeId) override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
functionParam(std::uint32_t index, std::uint32_t stTypeId) override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getDataObjectField(AccountID const& account, std::string_view const& key) override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getDataNestedObjectField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
std::string_view const& nestedKey) override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getDataArrayElementField(AccountID const& account, size_t index, std::string_view const& key)
|
||||
override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getDataNestedArrayElementField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
size_t index,
|
||||
std::string_view const& nestedKey) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
setDataObjectField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
STJson::Value const& value) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
setDataNestedObjectField(
|
||||
AccountID const& account,
|
||||
std::string_view const& nestedKey,
|
||||
std::string_view const& key,
|
||||
STJson::Value const& value) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
setDataArrayElementField(
|
||||
AccountID const& account,
|
||||
size_t index,
|
||||
std::string_view const& key,
|
||||
STJson::Value const& value) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
setDataNestedArrayElementField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
size_t index,
|
||||
std::string_view const& nestedKey,
|
||||
STJson::Value const& value) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
buildTxn(std::uint16_t const& txType) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
addTxnField(std::uint32_t const& index, SField const& field, Slice const& data) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
emitBuiltTxn(std::uint32_t const& index) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
emitTxn(std::shared_ptr<STTx const> const& stxPtr) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
emitEvent(std::string_view const& eventName, STJson const& eventData) override;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,619 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Expected.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <xrpl/tx/wasm/ParamsHelper.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
enum class HostFunctionError : int32_t {
|
||||
SUCCESS = 0,
|
||||
INTERNAL = -1,
|
||||
FIELD_NOT_FOUND = -2,
|
||||
BUFFER_TOO_SMALL = -3,
|
||||
NO_ARRAY = -4,
|
||||
NOT_LEAF_FIELD = -5,
|
||||
LOCATOR_MALFORMED = -6,
|
||||
SLOT_OUT_RANGE = -7,
|
||||
SLOTS_FULL = -8,
|
||||
EMPTY_SLOT = -9,
|
||||
LEDGER_OBJ_NOT_FOUND = -10,
|
||||
DECODING = -11,
|
||||
DATA_FIELD_TOO_LARGE = -12,
|
||||
POINTER_OUT_OF_BOUNDS = -13,
|
||||
NO_MEM_EXPORTED = -14,
|
||||
INVALID_PARAMS = -15,
|
||||
INVALID_ACCOUNT = -16,
|
||||
INVALID_FIELD = -17,
|
||||
INDEX_OUT_OF_BOUNDS = -18,
|
||||
FLOAT_INPUT_MALFORMED = -19,
|
||||
FLOAT_COMPUTATION_ERROR = -20,
|
||||
NO_RUNTIME = -21,
|
||||
OUT_OF_GAS = -22,
|
||||
SUBMIT_TXN_FAILURE = -23,
|
||||
INVALID_STATE = -24,
|
||||
};
|
||||
|
||||
inline int32_t
|
||||
HfErrorToInt(HostFunctionError e)
|
||||
{
|
||||
return static_cast<int32_t>(e);
|
||||
}
|
||||
|
||||
namespace wasm_float {
|
||||
|
||||
std::string
|
||||
floatToString(Slice const& data);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromIntImpl(int64_t x, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromUintImpl(uint64_t x, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSetImpl(int64_t mantissa, int32_t exponent, int32_t mode);
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
floatCompareImpl(Slice const& x, Slice const& y);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatAddImpl(Slice const& x, Slice const& y, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatDivideImpl(Slice const& x, Slice const& y, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatRootImpl(Slice const& x, int32_t n, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatPowerImpl(Slice const& x, int32_t n, int32_t mode);
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatLogImpl(Slice const& x, int32_t mode);
|
||||
|
||||
} // namespace wasm_float
|
||||
|
||||
struct HostFunctions
|
||||
{
|
||||
beast::Journal j_;
|
||||
|
||||
HostFunctions(beast::Journal j = beast::Journal{beast::Journal::getNullSink()}) : j_(j)
|
||||
{
|
||||
}
|
||||
|
||||
// LCOV_EXCL_START
|
||||
virtual void
|
||||
setRT(void const*)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void const*
|
||||
getRT() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
beast::Journal
|
||||
getJournal() const
|
||||
{
|
||||
return j_;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
checkSelf() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getLedgerSqn() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getParentLedgerTime() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Hash, HostFunctionError>
|
||||
getParentLedgerHash() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<uint32_t, HostFunctionError>
|
||||
getBaseFee() const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
isAmendmentEnabled(uint256 const& amendmentId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
isAmendmentEnabled(std::string_view const& amendmentName) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getTxField(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjField(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjField(int32_t cacheIdx, SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getTxNestedField(Slice const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjNestedField(Slice const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getTxArrayLen(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjArrayLen(SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getTxNestedArrayLen(Slice const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
updateData(Slice const& data)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Hash, HostFunctionError>
|
||||
computeSha512HalfHash(Slice const& data) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
accountKeylet(AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
ammKeylet(Asset const& issue1, Asset const& issue2) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
checkKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
|
||||
const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
didKeylet(AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
delegateKeylet(AccountID const& account, AccountID const& authorize) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
escrowKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
offerKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
oracleKeylet(AccountID const& account, std::uint32_t docId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
signersKeylet(AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
ticketKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
vaultKeylet(AccountID const& account, std::uint32_t seq) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getNFT(AccountID const& account, uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getNFTIssuer(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getNFTTaxon(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getNFTFlags(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
getNFTTransferFee(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<std::uint32_t, HostFunctionError>
|
||||
getNFTSerial(uint256 const& nftId) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
trace(std::string_view const& msg, Slice const& data, bool asHex) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceNum(std::string_view const& msg, int64_t data) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceAccount(std::string_view const& msg, AccountID const& account) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceFloat(std::string_view const& msg, Slice const& data) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
traceAmount(std::string_view const& msg, STAmount const& amount) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromInt(int64_t x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatFromUint(uint64_t x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
floatCompare(Slice const& x, Slice const& y) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatAdd(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatDivide(Slice const& x, Slice const& y, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatRoot(Slice const& x, int32_t n, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatPower(Slice const& x, int32_t n, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
floatLog(Slice const& x, int32_t mode) const
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
instanceParam(std::uint32_t index, std::uint32_t stTypeId)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
functionParam(std::uint32_t index, std::uint32_t stTypeId)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getDataObjectField(AccountID const& account, std::string_view const& key)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getDataNestedObjectField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
std::string_view const& nestedKey)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getDataArrayElementField(AccountID const& account, size_t index, std::string_view const& key)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<Bytes, HostFunctionError>
|
||||
getDataNestedArrayElementField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
size_t index,
|
||||
std::string_view const& nestedKey)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
setDataObjectField(
|
||||
AccountID const& account,
|
||||
std::string_view const& keyName,
|
||||
STJson::Value const& value)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
setDataNestedObjectField(
|
||||
AccountID const& account,
|
||||
std::string_view const& nestedKey,
|
||||
std::string_view const& key,
|
||||
STJson::Value const& value)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
setDataArrayElementField(
|
||||
AccountID const& account,
|
||||
size_t index,
|
||||
std::string_view const& key,
|
||||
STJson::Value const& value)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
setDataNestedArrayElementField(
|
||||
AccountID const& account,
|
||||
std::string_view const& key,
|
||||
size_t index,
|
||||
std::string_view const& nestedKey,
|
||||
STJson::Value const& value)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
buildTxn(std::uint16_t const& txType)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
addTxnField(std::uint32_t const& index, SField const& field, Slice const& data)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
emitBuiltTxn(std::uint32_t const& index)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
emitTxn(std::shared_ptr<STTx const> const& stxPtr)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual Expected<int32_t, HostFunctionError>
|
||||
emitEvent(std::string_view const& eventName, STJson const& eventData)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
|
||||
virtual ~HostFunctions() = default;
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,295 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/wasm/HostFunc.h>
|
||||
|
||||
namespace xrpl {
|
||||
class WasmHostFunctionsImpl : public HostFunctions
|
||||
{
|
||||
ApplyContext& ctx_;
|
||||
|
||||
Keylet leKey_;
|
||||
mutable std::optional<std::shared_ptr<SLE const>> currentLedgerObj_;
|
||||
|
||||
static int constexpr MAX_CACHE = 256;
|
||||
std::array<std::shared_ptr<SLE const>, MAX_CACHE> cache_;
|
||||
|
||||
std::optional<Bytes> data_;
|
||||
|
||||
void const* rt_ = nullptr;
|
||||
|
||||
Expected<std::shared_ptr<SLE const>, HostFunctionError>
|
||||
getCurrentLedgerObj() const
|
||||
{
|
||||
if (!currentLedgerObj_)
|
||||
currentLedgerObj_ = ctx_.view().read(leKey_);
|
||||
if (*currentLedgerObj_)
|
||||
return *currentLedgerObj_;
|
||||
return Unexpected(HostFunctionError::LEDGER_OBJ_NOT_FOUND);
|
||||
}
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
normalizeCacheIndex(int32_t cacheIdx) const
|
||||
{
|
||||
--cacheIdx;
|
||||
if (cacheIdx < 0 || cacheIdx >= MAX_CACHE)
|
||||
return Unexpected(HostFunctionError::SLOT_OUT_RANGE);
|
||||
if (!cache_[cacheIdx])
|
||||
return Unexpected(HostFunctionError::EMPTY_SLOT);
|
||||
return cacheIdx;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void
|
||||
log(std::string_view const& msg, F&& dataFn) const
|
||||
{
|
||||
#ifdef DEBUG_OUTPUT
|
||||
auto& j = std::cerr;
|
||||
#else
|
||||
if (!getJournal().active(beast::severities::kTrace))
|
||||
return;
|
||||
auto j = getJournal().trace();
|
||||
#endif
|
||||
j << "WasmTrace[" << to_short_string(leKey_.key) << "]: " << msg << " " << dataFn();
|
||||
|
||||
#ifdef DEBUG_OUTPUT
|
||||
j << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
WasmHostFunctionsImpl(ApplyContext& ct, Keylet const& leKey)
|
||||
: HostFunctions(ct.journal), ctx_(ct), leKey_(leKey)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
setRT(void const* rt) override
|
||||
{
|
||||
rt_ = rt;
|
||||
}
|
||||
|
||||
virtual void const*
|
||||
getRT() const override
|
||||
{
|
||||
return rt_;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
checkSelf() const override
|
||||
{
|
||||
return !currentLedgerObj_ && !data_ &&
|
||||
std::ranges::find_if(cache_, [](auto& p) { return !!p; }) == cache_.end();
|
||||
}
|
||||
|
||||
std::optional<Bytes> const&
|
||||
getData() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
Expected<std::uint32_t, HostFunctionError>
|
||||
getLedgerSqn() const override;
|
||||
|
||||
Expected<std::uint32_t, HostFunctionError>
|
||||
getParentLedgerTime() const override;
|
||||
|
||||
Expected<Hash, HostFunctionError>
|
||||
getParentLedgerHash() const override;
|
||||
|
||||
Expected<std::uint32_t, HostFunctionError>
|
||||
getBaseFee() const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
isAmendmentEnabled(uint256 const& amendmentId) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
isAmendmentEnabled(std::string_view const& amendmentName) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getTxField(SField const& fname) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjField(SField const& fname) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjField(int32_t cacheIdx, SField const& fname) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getTxNestedField(Slice const& locator) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getCurrentLedgerObjNestedField(Slice const& locator) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getLedgerObjNestedField(int32_t cacheIdx, Slice const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getTxArrayLen(SField const& fname) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjArrayLen(SField const& fname) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getTxNestedArrayLen(Slice const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getCurrentLedgerObjNestedArrayLen(Slice const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getLedgerObjNestedArrayLen(int32_t cacheIdx, Slice const& locator) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
updateData(Slice const& data) override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey)
|
||||
const override;
|
||||
|
||||
Expected<Hash, HostFunctionError>
|
||||
computeSha512HalfHash(Slice const& data) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
accountKeylet(AccountID const& account) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
ammKeylet(Asset const& issue1, Asset const& issue2) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
checkKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType)
|
||||
const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
didKeylet(AccountID const& account) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
delegateKeylet(AccountID const& account, AccountID const& authorize) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
depositPreauthKeylet(AccountID const& account, AccountID const& authorize) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
escrowKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
lineKeylet(AccountID const& account1, AccountID const& account2, Currency const& currency)
|
||||
const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
mptIssuanceKeylet(AccountID const& issuer, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
mptokenKeylet(MPTID const& mptid, AccountID const& holder) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
nftOfferKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
offerKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
oracleKeylet(AccountID const& account, std::uint32_t docId) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
paychanKeylet(AccountID const& account, AccountID const& destination, std::uint32_t seq)
|
||||
const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
permissionedDomainKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
signersKeylet(AccountID const& account) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
ticketKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
vaultKeylet(AccountID const& account, std::uint32_t seq) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getNFT(AccountID const& account, uint256 const& nftId) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
getNFTIssuer(uint256 const& nftId) const override;
|
||||
|
||||
Expected<std::uint32_t, HostFunctionError>
|
||||
getNFTTaxon(uint256 const& nftId) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getNFTFlags(uint256 const& nftId) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
getNFTTransferFee(uint256 const& nftId) const override;
|
||||
|
||||
Expected<std::uint32_t, HostFunctionError>
|
||||
getNFTSerial(uint256 const& nftId) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
trace(std::string_view const& msg, Slice const& data, bool asHex) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
traceNum(std::string_view const& msg, int64_t data) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
traceAccount(std::string_view const& msg, AccountID const& account) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
traceFloat(std::string_view const& msg, Slice const& data) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
traceAmount(std::string_view const& msg, STAmount const& amount) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromInt(int64_t x, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatFromUint(uint64_t x, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSet(int64_t mantissa, int32_t exponent, int32_t mode) const override;
|
||||
|
||||
Expected<int32_t, HostFunctionError>
|
||||
floatCompare(Slice const& x, Slice const& y) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatAdd(Slice const& x, Slice const& y, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatSubtract(Slice const& x, Slice const& y, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatMultiply(Slice const& x, Slice const& y, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatDivide(Slice const& x, Slice const& y, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatRoot(Slice const& x, int32_t n, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatPower(Slice const& x, int32_t n, int32_t mode) const override;
|
||||
|
||||
Expected<Bytes, HostFunctionError>
|
||||
floatLog(Slice const& x, int32_t mode) const override;
|
||||
};
|
||||
|
||||
namespace wasm_float {
|
||||
|
||||
// The range for the mantissa and exponent when normalized
|
||||
static std::int64_t constexpr wasmMinMantissa = 1'000'000'000'000'000ll;
|
||||
static std::int64_t constexpr wasmMaxMantissa = wasmMinMantissa * 10 - 1;
|
||||
static int constexpr wasmMinExponent = -96;
|
||||
static int constexpr wasmMaxExponent = 80;
|
||||
|
||||
} // namespace wasm_float
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,395 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/WasmiVM.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
using getLedgerSqn_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerSqn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getParentLedgerTime_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getParentLedgerTime_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getParentLedgerHash_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getParentLedgerHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getBaseFee_proto = int32_t(uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getBaseFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using isAmendmentEnabled_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
isAmendmentEnabled_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using cacheLedgerObj_proto = int32_t(uint8_t const*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
cacheLedgerObj_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getTxField_proto = int32_t(int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getTxField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getCurrentLedgerObjField_proto = int32_t(int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getLedgerObjField_proto = int32_t(int32_t, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getTxNestedField_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getTxNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getCurrentLedgerObjNestedField_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjNestedField_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
|
||||
using getLedgerObjNestedField_proto = int32_t(int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjNestedField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getTxArrayLen_proto = int32_t(int32_t);
|
||||
wasm_trap_t*
|
||||
getTxArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getCurrentLedgerObjArrayLen_proto = int32_t(int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getLedgerObjArrayLen_proto = int32_t(int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getTxNestedArrayLen_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getTxNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getCurrentLedgerObjNestedArrayLen_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getCurrentLedgerObjNestedArrayLen_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
|
||||
using getLedgerObjNestedArrayLen_proto = int32_t(int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getLedgerObjNestedArrayLen_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using updateData_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
updateData_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using checkSignature_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
checkSignature_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using computeSha512HalfHash_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
computeSha512HalfHash_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using accountKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
accountKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using ammKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
ammKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using checkKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
checkKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using credentialKeylet_proto = int32_t(
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
credentialKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using delegateKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
delegateKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using depositPreauthKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
depositPreauthKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using didKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
didKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using escrowKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
escrowKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using lineKeylet_proto = int32_t(
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
lineKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using mptIssuanceKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
mptIssuanceKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using mptokenKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
mptokenKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using nftOfferKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
nftOfferKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using offerKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
offerKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using oracleKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
oracleKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using paychanKeylet_proto = int32_t(
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
paychanKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using permissionedDomainKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
permissionedDomainKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using signersKeylet_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
signersKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using ticketKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
ticketKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using vaultKeylet_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
vaultKeylet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getNFT_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFT_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getNFTIssuer_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTIssuer_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getNFTTaxon_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTTaxon_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getNFTFlags_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTFlags_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getNFTTransferFee_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTTransferFee_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getNFTSerial_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getNFTSerial_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using trace_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
trace_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using traceNum_proto = int32_t(uint8_t const*, int32_t, int64_t);
|
||||
wasm_trap_t*
|
||||
traceNum_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using traceAccount_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
traceAccount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using traceFloat_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
traceFloat_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using traceAmount_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
traceAmount_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatFromInt_proto = int32_t(int64_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromInt_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatFromUint_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatFromUint_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatSet_proto = int32_t(int32_t, int64_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatSet_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatCompare_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
floatCompare_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatAdd_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatAdd_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatSubtract_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatSubtract_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatMultiply_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatMultiply_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatDivide_proto =
|
||||
int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatDivide_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatRoot_proto = int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatRoot_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatPower_proto = int32_t(uint8_t const*, int32_t, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatPower_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using floatLog_proto = int32_t(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
|
||||
wasm_trap_t*
|
||||
floatLog_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
// Contract-specific host function wrappers
|
||||
|
||||
using instanceParam_proto = int32_t(int32_t, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
instanceParam_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using functionParam_proto = int32_t(int32_t, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
functionParam_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getDataObjectField_proto =
|
||||
int32_t(uint8_t*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getDataObjectField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getDataNestedObjectField_proto =
|
||||
int32_t(uint8_t*, int32_t, uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getDataNestedObjectField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using setDataObjectField_proto =
|
||||
int32_t(uint8_t*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
setDataObjectField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using setDataNestedObjectField_proto =
|
||||
int32_t(uint8_t*, int32_t, uint8_t const*, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
setDataNestedObjectField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getDataArrayElementField_proto =
|
||||
int32_t(uint8_t*, int32_t, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
getDataArrayElementField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using getDataNestedArrayElementField_proto = int32_t(
|
||||
uint8_t*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
getDataNestedArrayElementField_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
|
||||
using setDataArrayElementField_proto =
|
||||
int32_t(uint8_t*, int32_t, int32_t, uint8_t const*, int32_t, uint8_t*, int32_t);
|
||||
wasm_trap_t*
|
||||
setDataArrayElementField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using setDataNestedArrayElementField_proto = int32_t(
|
||||
uint8_t*,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
int32_t,
|
||||
uint8_t const*,
|
||||
int32_t,
|
||||
uint8_t*,
|
||||
int32_t);
|
||||
wasm_trap_t*
|
||||
setDataNestedArrayElementField_wrap(
|
||||
void* env,
|
||||
wasm_val_vec_t const* params,
|
||||
wasm_val_vec_t* results);
|
||||
|
||||
using buildTxn_proto = int32_t(int32_t);
|
||||
wasm_trap_t*
|
||||
buildTxn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using addTxnField_proto = int32_t(int32_t, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
addTxnField_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using emitBuiltTxn_proto = int32_t(int32_t);
|
||||
wasm_trap_t*
|
||||
emitBuiltTxn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using emitTxn_proto = int32_t(uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
emitTxn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
using emitEvent_proto = int32_t(uint8_t const*, int32_t, uint8_t const*, int32_t);
|
||||
wasm_trap_t*
|
||||
emitEvent_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,269 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
|
||||
#include <boost/function_types/function_arity.hpp>
|
||||
#include <boost/function_types/parameter_types.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace bft = boost::function_types;
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
using Bytes = std::vector<std::uint8_t>;
|
||||
using Hash = xrpl::uint256;
|
||||
|
||||
struct wmem
|
||||
{
|
||||
std::uint8_t* p = nullptr;
|
||||
std::size_t s = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct WasmResult
|
||||
{
|
||||
T result;
|
||||
int64_t cost;
|
||||
};
|
||||
typedef WasmResult<int32_t> EscrowResult;
|
||||
typedef WasmResult<int32_t> WasmRunResult;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum WasmTypes { WT_I32, WT_I64, WT_U8V };
|
||||
|
||||
struct WasmImportFunc
|
||||
{
|
||||
std::string name;
|
||||
std::optional<WasmTypes> result;
|
||||
std::vector<WasmTypes> params;
|
||||
// void* udata = nullptr;
|
||||
// wasm_func_callback_with_env_t
|
||||
void* wrap = nullptr;
|
||||
uint32_t gas = 0;
|
||||
};
|
||||
|
||||
typedef std::pair<void*, WasmImportFunc> WasmUserData;
|
||||
typedef std::vector<WasmUserData> ImportVec;
|
||||
|
||||
#define WASM_IMPORT_FUNC(v, f, ...) \
|
||||
WasmImpFunc<f##_proto>(v, #f, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
|
||||
|
||||
#define WASM_IMPORT_FUNC2(v, f, n, ...) \
|
||||
WasmImpFunc<f##_proto>(v, n, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
|
||||
|
||||
template <int N, int C, typename mpl>
|
||||
void
|
||||
WasmImpArgs(WasmImportFunc& e)
|
||||
{
|
||||
if constexpr (N < C)
|
||||
{
|
||||
using at = typename boost::mpl::at_c<mpl, N>::type;
|
||||
if constexpr (std::is_pointer_v<at>)
|
||||
e.params.push_back(WT_I32);
|
||||
else if constexpr (std::is_same_v<at, std::int32_t>)
|
||||
e.params.push_back(WT_I32);
|
||||
else if constexpr (std::is_same_v<at, std::int64_t>)
|
||||
e.params.push_back(WT_I64);
|
||||
else
|
||||
static_assert(std::is_pointer_v<at>, "Unsupported argument type");
|
||||
|
||||
return WasmImpArgs<N + 1, C, mpl>(e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
template <typename rt>
|
||||
void
|
||||
WasmImpRet(WasmImportFunc& e)
|
||||
{
|
||||
if constexpr (std::is_pointer_v<rt>)
|
||||
e.result = WT_I32;
|
||||
else if constexpr (std::is_same_v<rt, std::int32_t>)
|
||||
e.result = WT_I32;
|
||||
else if constexpr (std::is_same_v<rt, std::int64_t>)
|
||||
e.result = WT_I64;
|
||||
else if constexpr (std::is_void_v<rt>)
|
||||
e.result.reset();
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 14)) || \
|
||||
((defined(__clang_major__)) && (__clang_major__ >= 18))
|
||||
else
|
||||
static_assert(false, "Unsupported return type");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void
|
||||
WasmImpFuncHelper(WasmImportFunc& e)
|
||||
{
|
||||
using rt = typename bft::result_type<F>::type;
|
||||
using pt = typename bft::parameter_types<F>::type;
|
||||
// typename boost::mpl::at_c<mpl, N>::type
|
||||
|
||||
WasmImpRet<rt>(e);
|
||||
WasmImpArgs<0, bft::function_arity<F>::value, pt>(e);
|
||||
// WasmImpWrap(e, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void
|
||||
WasmImpFunc(
|
||||
ImportVec& v,
|
||||
std::string_view imp_name,
|
||||
void* f_wrap,
|
||||
void* data = nullptr,
|
||||
uint32_t gas = 0)
|
||||
{
|
||||
WasmImportFunc e;
|
||||
e.name = imp_name;
|
||||
e.wrap = f_wrap;
|
||||
e.gas = gas;
|
||||
WasmImpFuncHelper<F>(e);
|
||||
v.push_back(std::make_pair(data, std::move(e)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct WasmParamVec
|
||||
{
|
||||
std::uint8_t const* d = nullptr;
|
||||
std::int32_t sz = 0;
|
||||
};
|
||||
|
||||
struct WasmParam
|
||||
{
|
||||
WasmTypes type = WT_I32;
|
||||
union
|
||||
{
|
||||
std::int32_t i32;
|
||||
std::int64_t i64 = 0;
|
||||
float f32;
|
||||
double f64;
|
||||
WasmParamVec u8v;
|
||||
} of;
|
||||
};
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::int32_t p, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WT_I32, .of = {.i32 = p}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::int64_t p, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WT_I64, .of = {.i64 = p}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
// We are not supporting float/double for now
|
||||
// Leaving this code here so that it is easier to add later if needed
|
||||
// template <class... Types>
|
||||
// inline void
|
||||
// wasmParamsHlp(std::vector<WasmParam>& v, float p, Types&&... args)
|
||||
// {
|
||||
// v.push_back({.type = WT_F32, .of = {.f32 = p}});
|
||||
// wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
// }
|
||||
|
||||
// template <class... Types>
|
||||
// inline void
|
||||
// wasmParamsHlp(std::vector<WasmParam>& v, double p, Types&&... args)
|
||||
// {
|
||||
// v.push_back({.type = WT_F64, .of = {.f64 = p}});
|
||||
// wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
// }
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::uint8_t const* dt, std::int32_t sz, Types&&... args)
|
||||
{
|
||||
v.push_back({.type = WT_U8V, .of = {.u8v = {.d = dt, .sz = sz}}});
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, Bytes const& p, Types&&... args)
|
||||
{
|
||||
wasmParamsHlp(v, p.data(), static_cast<std::int32_t>(p.size()), std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::string_view const& p, Types&&... args)
|
||||
{
|
||||
wasmParamsHlp(
|
||||
v,
|
||||
reinterpret_cast<std::uint8_t const*>(p.data()),
|
||||
static_cast<std::int32_t>(p.size()),
|
||||
std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v, std::string const& p, Types&&... args)
|
||||
{
|
||||
wasmParamsHlp(
|
||||
v,
|
||||
reinterpret_cast<std::uint8_t const*>(p.c_str()),
|
||||
static_cast<std::int32_t>(p.size()),
|
||||
std::forward<Types>(args)...);
|
||||
}
|
||||
|
||||
inline void
|
||||
wasmParamsHlp(std::vector<WasmParam>& v)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
template <class... Types>
|
||||
inline std::vector<WasmParam>
|
||||
wasmParams(Types&&... args)
|
||||
{
|
||||
std::vector<WasmParam> v;
|
||||
v.reserve(sizeof...(args));
|
||||
wasmParamsHlp(v, std::forward<Types>(args)...);
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T, size_t size = sizeof(T)>
|
||||
inline constexpr T
|
||||
adjustWasmEndianessHlp(T x)
|
||||
{
|
||||
static_assert(std::is_integral<T>::value, "Only integral types");
|
||||
if constexpr (size > 1)
|
||||
{
|
||||
using U = std::make_unsigned<T>::type;
|
||||
U u = static_cast<U>(x);
|
||||
U const low = (u & 0xFF) << ((size - 1) << 3);
|
||||
u = adjustWasmEndianessHlp<U, size - 1>(u >> 8);
|
||||
return static_cast<T>(low | u);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename T, size_t size = sizeof(T)>
|
||||
inline constexpr T
|
||||
adjustWasmEndianess(T x)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
static_assert(std::is_integral<T>::value, "Only integral types");
|
||||
if constexpr (std::endian::native == std::endian::big)
|
||||
{
|
||||
return adjustWasmEndianessHlp(x);
|
||||
}
|
||||
return x;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,189 +0,0 @@
|
||||
# WASM Module for Programmable Escrows
|
||||
|
||||
This module provides WebAssembly (WASM) execution capabilities for programmable
|
||||
escrows on the XRP Ledger. When an escrow is finished, the WASM code runs to
|
||||
determine whether the escrow conditions are met, enabling custom programmable
|
||||
logic for escrow release conditions.
|
||||
|
||||
For the full specification, see
|
||||
[XLS-0102: WASM VM](https://xls.xrpl.org/xls/XLS-0102-wasm-vm.html).
|
||||
|
||||
## Architecture
|
||||
|
||||
The module follows a layered architecture:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ WasmEngine (WasmVM.h) │
|
||||
│ runEscrowWasm(), preflightEscrowWasm() │
|
||||
│ Host function registration │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ WasmiEngine (WasmiVM.h) │
|
||||
│ Low-level wasmi interpreter integration │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ HostFuncWrapper │ HostFuncImpl │
|
||||
│ C-style WASM bridges │ C++ implementations │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ HostFunc (Interface) │
|
||||
│ Abstract base class for host functions │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
- **`WasmVM.h` / `detail/WasmVM.cpp`** - High-level facade providing:
|
||||
- `WasmEngine` singleton that wraps the underlying WASM interpreter
|
||||
- `runEscrowWasm()` - Execute WASM code for escrow finish
|
||||
- `preflightEscrowWasm()` - Validate WASM code during preflight
|
||||
- `createWasmImport()` - Register all host functions
|
||||
|
||||
- **`WasmiVM.h` / `detail/WasmiVM.cpp`** - Low-level integration with the
|
||||
[wasmi](https://github.com/wasmi-labs/wasmi) WebAssembly interpreter:
|
||||
- `WasmiEngine` - Manages WASM modules, instances, and execution
|
||||
- Memory management and gas metering
|
||||
- Function invocation and result handling
|
||||
|
||||
- **`HostFunc.h`** - Abstract `HostFunctions` base class defining the interface
|
||||
for all callable host functions. Each method returns
|
||||
`Expected<T, HostFunctionError>`.
|
||||
|
||||
- **`HostFuncImpl.h` / `detail/HostFuncImpl*.cpp`** - Concrete
|
||||
`WasmHostFunctionsImpl` class that implements host functions with access to
|
||||
`ApplyContext` for ledger state queries. Implementation split across files:
|
||||
- `HostFuncImpl.cpp` - Core utilities (updateData, checkSignature, etc.)
|
||||
- `HostFuncImplFloat.cpp` - Float/number arithmetic operations
|
||||
- `HostFuncImplGetter.cpp` - Field access (transaction, ledger objects)
|
||||
- `HostFuncImplKeylet.cpp` - Keylet construction functions
|
||||
- `HostFuncImplLedgerHeader.cpp` - Ledger header info access
|
||||
- `HostFuncImplNFT.cpp` - NFT-related queries
|
||||
- `HostFuncImplTrace.cpp` - Debugging/tracing functions
|
||||
|
||||
- **`HostFuncWrapper.h` / `detail/HostFuncWrapper.cpp`** - C-style wrapper
|
||||
functions that bridge WASM calls to C++ `HostFunctions` methods. Each host
|
||||
function has:
|
||||
- A `_proto` type alias defining the function signature
|
||||
- A `_wrap` function that extracts parameters and calls the implementation
|
||||
|
||||
- **`ParamsHelper.h`** - Utilities for WASM parameter handling:
|
||||
- `WASM_IMPORT_FUNC` / `WASM_IMPORT_FUNC2` macros for registration
|
||||
- `wasmParams()` helper for building parameter vectors
|
||||
- Type conversion between WASM and C++ types
|
||||
|
||||
## Host Functions
|
||||
|
||||
Host functions allow WASM code to interact with the XRP Ledger. They are
|
||||
organized into categories:
|
||||
|
||||
- **Ledger Information** - Access ledger sequence, timestamps, hashes, fees
|
||||
- **Transaction & Ledger Object Access** - Read fields from the transaction
|
||||
and ledger objects (including the current escrow object)
|
||||
- **Keylet Construction** - Build keylets to look up various ledger object types
|
||||
- **Cryptography** - Signature verification and hashing
|
||||
- **Float Arithmetic** - Mathematical operations for amount calculations
|
||||
- **NFT Operations** - Query NFT properties
|
||||
- **Tracing/Debugging** - Log messages for debugging
|
||||
|
||||
For the complete list of available host functions, their WASM names, and gas
|
||||
costs, see the [XLS-0102 specification](https://xls.xrpl.org/xls/XLS-0102-wasm-vm.html)
|
||||
or `detail/WasmVM.cpp` where they are registered via `WASM_IMPORT_FUNC2` macros.
|
||||
For method signatures, see `HostFunc.h`.
|
||||
|
||||
## Gas Model
|
||||
|
||||
Each host function has an associated gas cost. The gas cost is specified when
|
||||
registering the function in `detail/WasmVM.cpp`:
|
||||
|
||||
```cpp
|
||||
WASM_IMPORT_FUNC2(i, getLedgerSqn, "get_ledger_sqn", hfs, 60);
|
||||
// ^^ gas cost
|
||||
```
|
||||
|
||||
WASM execution is metered, and if the gas limit is exceeded, execution fails.
|
||||
|
||||
## Entry Point
|
||||
|
||||
The WASM module must export a function with the name defined by
|
||||
`ESCROW_FUNCTION_NAME` (currently `"finish"`). This function:
|
||||
|
||||
- Takes no parameters (or parameters passed via host function calls)
|
||||
- Returns an `int32_t`:
|
||||
- `1` (or positive): Escrow conditions are met, allow finish
|
||||
- `0` (or negative): Escrow conditions are not met, reject finish
|
||||
|
||||
## Adding a New Host Function
|
||||
|
||||
To add a new host function, follow these steps:
|
||||
|
||||
### 1. Add to HostFunc.h (Base Class)
|
||||
|
||||
Add a virtual method declaration with a default implementation that returns an
|
||||
error:
|
||||
|
||||
```cpp
|
||||
virtual Expected<ReturnType, HostFunctionError>
|
||||
myNewFunction(ParamType1 param1, ParamType2 param2)
|
||||
{
|
||||
return Unexpected(HostFunctionError::INTERNAL);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Add to HostFuncImpl.h (Declaration)
|
||||
|
||||
Add the method override declaration in `WasmHostFunctionsImpl`:
|
||||
|
||||
```cpp
|
||||
Expected<ReturnType, HostFunctionError>
|
||||
myNewFunction(ParamType1 param1, ParamType2 param2) override;
|
||||
```
|
||||
|
||||
### 3. Implement in detail/HostFuncImpl\*.cpp
|
||||
|
||||
Add the implementation in the appropriate file:
|
||||
|
||||
```cpp
|
||||
Expected<ReturnType, HostFunctionError>
|
||||
WasmHostFunctionsImpl::myNewFunction(ParamType1 param1, ParamType2 param2)
|
||||
{
|
||||
// Implementation using ctx (ApplyContext) for ledger access
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Add Wrapper to HostFuncWrapper.h
|
||||
|
||||
Add the prototype and wrapper declaration:
|
||||
|
||||
```cpp
|
||||
using myNewFunction_proto = int32_t(uint8_t const*, int32_t, ...);
|
||||
wasm_trap_t*
|
||||
myNewFunction_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results);
|
||||
```
|
||||
|
||||
### 5. Implement Wrapper in detail/HostFuncWrapper.cpp
|
||||
|
||||
Implement the C-style wrapper that bridges WASM to C++:
|
||||
|
||||
```cpp
|
||||
wasm_trap_t*
|
||||
myNewFunction_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
{
|
||||
// Extract parameters from params
|
||||
// Call hfs->myNewFunction(...)
|
||||
// Set results and return
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Register in WasmVM.cpp
|
||||
|
||||
Add the function registration in `setCommonHostFunctions()` or
|
||||
`createWasmImport()`:
|
||||
|
||||
```cpp
|
||||
WASM_IMPORT_FUNC2(i, myNewFunction, "my_new_function", hfs, 100);
|
||||
// ^^ WASM name ^^ gas cost
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> New host functions MUST be amendment-gated in `WasmVM.cpp`.
|
||||
> Wrap the registration in an amendment check to ensure the function is only
|
||||
> available after the corresponding amendment is enabled on the network.
|
||||
@@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/HostFunc.h>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
static std::string_view const W_ENV = "env";
|
||||
static std::string_view const W_HOST_LIB = "host_lib";
|
||||
static std::string_view const W_MEM = "memory";
|
||||
static std::string_view const W_STORE = "store";
|
||||
static std::string_view const W_LOAD = "load";
|
||||
static std::string_view const W_SIZE = "size";
|
||||
static std::string_view const W_ALLOC = "allocate";
|
||||
static std::string_view const W_DEALLOC = "deallocate";
|
||||
static std::string_view const W_PROC_EXIT = "proc_exit";
|
||||
|
||||
static std::string_view const ESCROW_FUNCTION_NAME = "finish";
|
||||
|
||||
uint32_t const MAX_PAGES = 128; // 8MB = 64KB*128
|
||||
|
||||
class WasmiEngine;
|
||||
|
||||
class WasmEngine
|
||||
{
|
||||
std::unique_ptr<WasmiEngine> const impl_;
|
||||
|
||||
WasmEngine();
|
||||
|
||||
WasmEngine(WasmEngine const&) = delete;
|
||||
WasmEngine(WasmEngine&&) = delete;
|
||||
WasmEngine&
|
||||
operator=(WasmEngine const&) = delete;
|
||||
WasmEngine&
|
||||
operator=(WasmEngine&&) = delete;
|
||||
|
||||
public:
|
||||
~WasmEngine() = default;
|
||||
|
||||
static WasmEngine&
|
||||
instance();
|
||||
|
||||
Expected<WasmResult<int32_t>, TER>
|
||||
run(Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
int64_t gasLimit,
|
||||
std::string_view funcName = {},
|
||||
std::vector<WasmParam> const& params = {},
|
||||
ImportVec const& imports = {},
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
NotTEC
|
||||
check(
|
||||
Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
std::string_view funcName,
|
||||
std::vector<WasmParam> const& params = {},
|
||||
ImportVec const& imports = {},
|
||||
beast::Journal j = beast::Journal{beast::Journal::getNullSink()});
|
||||
|
||||
// Host functions helper functionality
|
||||
void*
|
||||
newTrap(std::string const& txt = std::string());
|
||||
|
||||
beast::Journal
|
||||
getJournal() const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ImportVec
|
||||
createWasmImport(HostFunctions& hfs);
|
||||
|
||||
Expected<EscrowResult, TER>
|
||||
runEscrowWasm(
|
||||
Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
int64_t gasLimit,
|
||||
std::string_view funcName = ESCROW_FUNCTION_NAME,
|
||||
std::vector<WasmParam> const& params = {});
|
||||
|
||||
NotTEC
|
||||
preflightEscrowWasm(
|
||||
Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
std::string_view funcName = ESCROW_FUNCTION_NAME,
|
||||
std::vector<WasmParam> const& params = {});
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,321 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/tx/wasm/WasmVM.h>
|
||||
|
||||
#include <wasm.h>
|
||||
#include <wasmi.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <class T, void (*Create)(T*, size_t), void (*Destroy)(T*)>
|
||||
struct WasmVec
|
||||
{
|
||||
T vec_;
|
||||
|
||||
WasmVec(size_t s = 0) : vec_ WASM_EMPTY_VEC
|
||||
{
|
||||
if (s > 0)
|
||||
Create(&vec_, s); // zeroes memory
|
||||
}
|
||||
|
||||
~WasmVec()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
WasmVec(WasmVec const&) = delete;
|
||||
WasmVec&
|
||||
operator=(WasmVec const&) = delete;
|
||||
|
||||
WasmVec(WasmVec&& other) noexcept : vec_ WASM_EMPTY_VEC
|
||||
{
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
WasmVec&
|
||||
operator=(WasmVec&& other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
clear();
|
||||
vec_ = other.vec_;
|
||||
other.vec_ = WASM_EMPTY_VEC;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
Destroy(&vec_); // call destructor for every elements too
|
||||
vec_ = WASM_EMPTY_VEC;
|
||||
}
|
||||
|
||||
T
|
||||
release()
|
||||
{
|
||||
T result = vec_;
|
||||
vec_ = WASM_EMPTY_VEC;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
using WasmValtypeVec =
|
||||
WasmVec<wasm_valtype_vec_t, &wasm_valtype_vec_new_uninitialized, &wasm_valtype_vec_delete>;
|
||||
using WasmValVec = WasmVec<wasm_val_vec_t, &wasm_val_vec_new_uninitialized, &wasm_val_vec_delete>;
|
||||
using WasmExternVec =
|
||||
WasmVec<wasm_extern_vec_t, &wasm_extern_vec_new_uninitialized, &wasm_extern_vec_delete>;
|
||||
using WasmExporttypeVec = WasmVec<
|
||||
wasm_exporttype_vec_t,
|
||||
&wasm_exporttype_vec_new_uninitialized,
|
||||
&wasm_exporttype_vec_delete>;
|
||||
using WasmImporttypeVec = WasmVec<
|
||||
wasm_importtype_vec_t,
|
||||
&wasm_importtype_vec_new_uninitialized,
|
||||
&wasm_importtype_vec_delete>;
|
||||
|
||||
struct WasmiResult
|
||||
{
|
||||
WasmValVec r;
|
||||
bool f{false}; // failure flag
|
||||
|
||||
WasmiResult(unsigned N = 0) : r(N)
|
||||
{
|
||||
}
|
||||
|
||||
~WasmiResult() = default;
|
||||
WasmiResult(WasmiResult&& o) = default;
|
||||
WasmiResult&
|
||||
operator=(WasmiResult&& o) = default;
|
||||
};
|
||||
|
||||
using ModulePtr = std::unique_ptr<wasm_module_t, decltype(&wasm_module_delete)>;
|
||||
using InstancePtr = std::unique_ptr<wasm_instance_t, decltype(&wasm_instance_delete)>;
|
||||
using EnginePtr = std::unique_ptr<wasm_engine_t, decltype(&wasm_engine_delete)>;
|
||||
using StorePtr = std::unique_ptr<wasm_store_t, decltype(&wasm_store_delete)>;
|
||||
|
||||
using FuncInfo = std::pair<wasm_func_t const*, wasm_functype_t const*>;
|
||||
|
||||
struct InstanceWrapper
|
||||
{
|
||||
wasm_store_t* store_ = nullptr;
|
||||
WasmExternVec exports_;
|
||||
mutable int memIdx_ = -1;
|
||||
InstancePtr instance_;
|
||||
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
|
||||
|
||||
private:
|
||||
static InstancePtr
|
||||
init(
|
||||
StorePtr& s,
|
||||
ModulePtr& m,
|
||||
WasmExternVec& expt,
|
||||
WasmExternVec const& imports,
|
||||
beast::Journal j);
|
||||
|
||||
public:
|
||||
InstanceWrapper();
|
||||
|
||||
InstanceWrapper(InstanceWrapper&& o);
|
||||
|
||||
InstanceWrapper&
|
||||
operator=(InstanceWrapper&& o);
|
||||
|
||||
InstanceWrapper(StorePtr& s, ModulePtr& m, WasmExternVec const& imports, beast::Journal j);
|
||||
|
||||
~InstanceWrapper() = default;
|
||||
|
||||
operator bool() const;
|
||||
|
||||
FuncInfo
|
||||
getFunc(std::string_view funcName, WasmExporttypeVec const& exportTypes) const;
|
||||
|
||||
wmem
|
||||
getMem() const;
|
||||
|
||||
std::int64_t
|
||||
getGas() const;
|
||||
|
||||
std::int64_t
|
||||
setGas(std::int64_t) const;
|
||||
};
|
||||
|
||||
struct ModuleWrapper
|
||||
{
|
||||
ModulePtr module_;
|
||||
InstanceWrapper instanceWrap_;
|
||||
WasmExporttypeVec exportTypes_;
|
||||
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
|
||||
|
||||
private:
|
||||
static ModulePtr
|
||||
init(StorePtr& s, Bytes const& wasmBin, beast::Journal j);
|
||||
|
||||
public:
|
||||
ModuleWrapper();
|
||||
ModuleWrapper(ModuleWrapper&& o);
|
||||
ModuleWrapper&
|
||||
operator=(ModuleWrapper&& o);
|
||||
ModuleWrapper(
|
||||
StorePtr& s,
|
||||
Bytes const& wasmBin,
|
||||
bool instantiate,
|
||||
ImportVec const& imports,
|
||||
beast::Journal j);
|
||||
~ModuleWrapper() = default;
|
||||
|
||||
operator bool() const;
|
||||
|
||||
FuncInfo
|
||||
getFunc(std::string_view funcName) const;
|
||||
|
||||
wasm_functype_t*
|
||||
getFuncType(std::string_view funcName) const;
|
||||
|
||||
wmem
|
||||
getMem() const;
|
||||
|
||||
InstanceWrapper const&
|
||||
getInstance(int i = 0) const;
|
||||
|
||||
int
|
||||
addInstance(StorePtr& s, WasmExternVec const& imports);
|
||||
|
||||
std::int64_t
|
||||
getGas() const;
|
||||
|
||||
private:
|
||||
WasmExternVec
|
||||
buildImports(StorePtr& s, ImportVec const& imports) const;
|
||||
};
|
||||
|
||||
class WasmiEngine
|
||||
{
|
||||
EnginePtr engine_;
|
||||
StorePtr store_;
|
||||
std::unique_ptr<ModuleWrapper> moduleWrap_;
|
||||
beast::Journal j_ = beast::Journal(beast::Journal::getNullSink());
|
||||
|
||||
std::mutex m_; // 1 instance mutex
|
||||
|
||||
public:
|
||||
WasmiEngine();
|
||||
~WasmiEngine() = default;
|
||||
|
||||
static EnginePtr
|
||||
init();
|
||||
|
||||
Expected<WasmResult<int32_t>, TER>
|
||||
run(Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
int64_t gas,
|
||||
std::string_view funcName,
|
||||
std::vector<WasmParam> const& params,
|
||||
ImportVec const& imports,
|
||||
beast::Journal j);
|
||||
|
||||
NotTEC
|
||||
check(
|
||||
Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
std::string_view funcName,
|
||||
std::vector<WasmParam> const& params,
|
||||
ImportVec const& imports,
|
||||
beast::Journal j);
|
||||
|
||||
std::int64_t
|
||||
getGas() const;
|
||||
|
||||
// Host functions helper functionality
|
||||
wasm_trap_t*
|
||||
newTrap(std::string const& msg);
|
||||
|
||||
beast::Journal
|
||||
getJournal() const;
|
||||
|
||||
private:
|
||||
InstanceWrapper const&
|
||||
getRT(int m = 0, int i = 0) const;
|
||||
|
||||
wmem
|
||||
getMem() const;
|
||||
|
||||
Expected<WasmResult<int32_t>, TER>
|
||||
runHlp(
|
||||
Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
int64_t gas,
|
||||
std::string_view funcName,
|
||||
std::vector<WasmParam> const& params,
|
||||
ImportVec const& imports);
|
||||
|
||||
NotTEC
|
||||
checkHlp(
|
||||
Bytes const& wasmCode,
|
||||
HostFunctions& hfs,
|
||||
std::string_view funcName,
|
||||
std::vector<WasmParam> const& params,
|
||||
ImportVec const& imports);
|
||||
|
||||
int
|
||||
addModule(Bytes const& wasmCode, bool instantiate, ImportVec const& imports, int64_t gas);
|
||||
void
|
||||
clearModules();
|
||||
|
||||
// int addInstance();
|
||||
|
||||
int32_t
|
||||
runFunc(std::string_view const funcName, int32_t p);
|
||||
|
||||
int32_t
|
||||
makeModule(Bytes const& wasmCode, WasmExternVec const& imports = {});
|
||||
|
||||
FuncInfo
|
||||
getFunc(std::string_view funcName) const;
|
||||
|
||||
static std::vector<wasm_val_t>
|
||||
convertParams(std::vector<WasmParam> const& params);
|
||||
|
||||
static int
|
||||
compareParamTypes(wasm_valtype_vec_t const* ftp, std::vector<wasm_val_t> const& p);
|
||||
|
||||
static void
|
||||
add_param(std::vector<wasm_val_t>& in, int32_t p);
|
||||
static void
|
||||
add_param(std::vector<wasm_val_t>& in, int64_t p);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(std::string_view func, Types&&... args);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(FuncInfo const& f, Types&&... args);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(FuncInfo const& f, std::vector<wasm_val_t>& in);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(FuncInfo const& f, std::vector<wasm_val_t>& in, std::int32_t p, Types&&... args);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(FuncInfo const& f, std::vector<wasm_val_t>& in, std::int64_t p, Types&&... args);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(
|
||||
FuncInfo const& f,
|
||||
std::vector<wasm_val_t>& in,
|
||||
uint8_t const* d,
|
||||
int32_t sz,
|
||||
Types&&... args);
|
||||
|
||||
template <int NR, class... Types>
|
||||
inline WasmiResult
|
||||
call(FuncInfo const& f, std::vector<wasm_val_t>& in, Bytes const& p, Types&&... args);
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -945,81 +945,6 @@ power(Number const& f, unsigned n)
|
||||
return r;
|
||||
}
|
||||
|
||||
// Series expansion method approximation of ln(x)
|
||||
static Number
|
||||
ln(Number const& x, int iterations = 50)
|
||||
{
|
||||
static Number const N0(0);
|
||||
static Number const N2(2, 0);
|
||||
static Number const N05(5, -1);
|
||||
static Number const LN2(693'147'180'559'945'309ll, -18);
|
||||
|
||||
if (x <= 0)
|
||||
{
|
||||
throw std::runtime_error("Not a positive value");
|
||||
}
|
||||
if (x == 1)
|
||||
{
|
||||
return N0;
|
||||
}
|
||||
|
||||
int exponent = 0;
|
||||
Number mantissa = x;
|
||||
|
||||
while (mantissa >= N2)
|
||||
{
|
||||
mantissa /= 2;
|
||||
exponent += 1;
|
||||
}
|
||||
while (mantissa < N05)
|
||||
{
|
||||
mantissa *= 2;
|
||||
exponent -= 1;
|
||||
}
|
||||
|
||||
Number z = (mantissa - 1) / (mantissa + 1);
|
||||
Number const zz = z * z;
|
||||
Number sum;
|
||||
|
||||
for (int i = 1; i <= iterations; ++i)
|
||||
{
|
||||
sum = sum + z / ((2 * i) - 1);
|
||||
z = z * zz;
|
||||
}
|
||||
|
||||
return 2 * sum + exponent * LN2;
|
||||
}
|
||||
|
||||
Number
|
||||
log10(Number const& x, int iterations)
|
||||
{
|
||||
static Number const N0(0);
|
||||
static Number const LN10(2'302'585'092'994'046ll, -15);
|
||||
|
||||
if (x <= 0)
|
||||
{
|
||||
throw std::runtime_error("Not a positive value");
|
||||
}
|
||||
if (x == 1)
|
||||
{
|
||||
return N0;
|
||||
}
|
||||
|
||||
if (x <= Number(10))
|
||||
{
|
||||
auto const r = ln(x, iterations) / LN10;
|
||||
return r;
|
||||
}
|
||||
|
||||
// (1 <= normalX < 10)
|
||||
// ln(x) = ln(normalX * 10^norm) = ln(normalX) + norm * ln(10)
|
||||
int const diffExp = 15 + x.exponent();
|
||||
Number const normalX = x / Number(1, diffExp);
|
||||
auto const lnX = ln(normalX, iterations) + diffExp * LN10;
|
||||
auto const lgX = lnX / LN10;
|
||||
return lgX;
|
||||
}
|
||||
|
||||
// Returns f^(1/d)
|
||||
// Uses Newton–Raphson iterations until the result stops changing
|
||||
// to find the non-negative root of the polynomial g(x) = x^d - f
|
||||
|
||||
@@ -89,8 +89,6 @@ ApplyStateTable::apply(
|
||||
TER ter,
|
||||
std::optional<STAmount> const& deliver,
|
||||
std::optional<uint256 const> const& parentBatchId,
|
||||
std::optional<std::uint32_t> const& gasUsed,
|
||||
std::optional<std::int32_t> const& wasmReturnCode,
|
||||
bool isDryRun,
|
||||
beast::Journal j)
|
||||
{
|
||||
@@ -105,8 +103,6 @@ ApplyStateTable::apply(
|
||||
|
||||
meta.setDeliveredAmount(deliver);
|
||||
meta.setParentBatchID(parentBatchId);
|
||||
meta.setGasUsed(gasUsed);
|
||||
meta.setWasmReturnCode(wasmReturnCode);
|
||||
|
||||
Mods newMod;
|
||||
for (auto& item : items_)
|
||||
|
||||
@@ -15,8 +15,7 @@ ApplyViewImpl::apply(
|
||||
bool isDryRun,
|
||||
beast::Journal j)
|
||||
{
|
||||
return items_.apply(
|
||||
to, tx, ter, deliver_, parentBatchId, gasUsed_, wasmReturnCode_, isDryRun, j);
|
||||
return items_.apply(to, tx, ter, deliver_, parentBatchId, isDryRun, j);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
|
||||
@@ -169,12 +169,6 @@ Ledger::Ledger(
|
||||
sle->at(sfReserveIncrement) = *f;
|
||||
sle->at(sfReferenceFeeUnits) = FEE_UNITS_DEPRECATED;
|
||||
}
|
||||
if (std::find(amendments.begin(), amendments.end(), featureSmartEscrow) != amendments.end())
|
||||
{
|
||||
sle->at(sfExtensionComputeLimit) = fees.extensionComputeLimit;
|
||||
sle->at(sfExtensionSizeLimit) = fees.extensionSizeLimit;
|
||||
sle->at(sfGasPrice) = fees.gasPrice;
|
||||
}
|
||||
rawInsert(sle);
|
||||
}
|
||||
|
||||
@@ -558,7 +552,6 @@ Ledger::setup()
|
||||
{
|
||||
bool oldFees = false;
|
||||
bool newFees = false;
|
||||
bool extensionFees = false;
|
||||
{
|
||||
auto const baseFee = sle->at(~sfBaseFee);
|
||||
auto const reserveBase = sle->at(~sfReserveBase);
|
||||
@@ -575,7 +568,6 @@ 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)
|
||||
{
|
||||
@@ -594,22 +586,6 @@ Ledger::setup()
|
||||
assign(fees_.increment, reserveIncrementXRP);
|
||||
newFees = baseFeeXRP || reserveBaseXRP || reserveIncrementXRP;
|
||||
}
|
||||
{
|
||||
auto const extensionComputeLimit = sle->at(~sfExtensionComputeLimit);
|
||||
auto const extensionSizeLimit = sle->at(~sfExtensionSizeLimit);
|
||||
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_.extensionComputeLimit, extensionComputeLimit);
|
||||
assign(fees_.extensionSizeLimit, extensionSizeLimit);
|
||||
assign(fees_.gasPrice, gasPrice);
|
||||
extensionFees = extensionComputeLimit || extensionSizeLimit || gasPrice;
|
||||
}
|
||||
if (oldFees && newFees)
|
||||
{
|
||||
// Should be all of one or the other, but not both
|
||||
@@ -620,12 +596,6 @@ 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&)
|
||||
|
||||
@@ -443,271 +443,6 @@ doWithdraw(
|
||||
return accountSend(view, sourceAcct, dstAcct, amount, j, WaiveTransferFee::Yes);
|
||||
}
|
||||
|
||||
static TER
|
||||
canTransferIOU(
|
||||
ReadView const& view,
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
STAmount const& amount,
|
||||
beast::Journal j,
|
||||
SendIssuerHandling issuerHandling,
|
||||
SendEscrowHandling escrowHandling,
|
||||
SendAuthHandling authHandling,
|
||||
SendFreezeHandling freezeHandling,
|
||||
SendTransferHandling transferHandling,
|
||||
SendBalanceHandling balanceHandling)
|
||||
{
|
||||
AccountID issuer = amount.getIssuer();
|
||||
// If the issuer is the same as the sender
|
||||
if (issuerHandling == SendIssuerHandling::ihSENDER_NOT_ALLOWED && issuer == sender)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the issuer is the same as the receiver
|
||||
if (issuerHandling == SendIssuerHandling::ihRECEIVER_NOT_ALLOWED && issuer == receiver)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the lsfAllowTrustLineLocking is not enabled
|
||||
auto const sleIssuer = view.read(keylet::account(issuer));
|
||||
if (!sleIssuer)
|
||||
return tecNO_ISSUER;
|
||||
|
||||
if (issuerHandling != SendIssuerHandling::ihSENDER_NOT_ALLOWED &&
|
||||
issuerHandling != SendIssuerHandling::ihRECEIVER_NOT_ALLOWED &&
|
||||
!sleIssuer->isFlag(lsfDefaultRipple))
|
||||
return terNO_RIPPLE;
|
||||
|
||||
if (escrowHandling == SendEscrowHandling::ehCHECK &&
|
||||
!sleIssuer->isFlag(lsfAllowTrustLineLocking))
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the sender does not have a trustline to the issuer
|
||||
auto const sleRippleState = view.read(keylet::line(sender, issuer, amount.getCurrency()));
|
||||
|
||||
if (!sleRippleState)
|
||||
return tecNO_LINE;
|
||||
|
||||
STAmount const balance = (*sleRippleState)[sfBalance];
|
||||
|
||||
// If balance is positive, issuer must have higher address than sender
|
||||
if (balance > beast::zero && issuer < sender)
|
||||
return tecNO_PERMISSION; // LCOV_EXCL_LINE
|
||||
|
||||
// If balance is negative, issuer must have lower address than sender
|
||||
if (balance < beast::zero && issuer > sender)
|
||||
return tecNO_PERMISSION; // LCOV_EXCL_LINE
|
||||
|
||||
// // If the account trustline has no-ripple set for the issuer
|
||||
// if (auto const ter = requireNoRipple(ctx.view, amount.issue(), account);
|
||||
// ter != tesSUCCESS)
|
||||
// return ter;
|
||||
|
||||
// // If the dest trustline has no-ripple set for the issuer
|
||||
// if (auto const ter = requireNoRipple(ctx.view, amount.issue(), dest);
|
||||
// ter != tesSUCCESS)
|
||||
// return ter;
|
||||
|
||||
// If the issuer has requireAuth set, check if the sender is authorized
|
||||
if (authHandling == SendAuthHandling::ahCHECK_SENDER ||
|
||||
authHandling == SendAuthHandling::ahBOTH)
|
||||
{
|
||||
if (auto const ter = requireAuth(view, amount.issue(), sender); ter != tesSUCCESS)
|
||||
return ter;
|
||||
}
|
||||
|
||||
// If the issuer has requireAuth set, check if the receiver is authorized
|
||||
if (authHandling == SendAuthHandling::ahCHECK_RECEIVER ||
|
||||
authHandling == SendAuthHandling::ahBOTH)
|
||||
{
|
||||
if (auto const ter = requireAuth(view, amount.issue(), receiver); ter != tesSUCCESS)
|
||||
return ter;
|
||||
}
|
||||
|
||||
// If the issuer has frozen the sender
|
||||
if ((freezeHandling == SendFreezeHandling::fhCHECK_SENDER ||
|
||||
freezeHandling == SendFreezeHandling::fhBOTH) &&
|
||||
isFrozen(view, sender, amount.issue()))
|
||||
return tecFROZEN;
|
||||
|
||||
// If the issuer has frozen the receiver
|
||||
if ((freezeHandling == SendFreezeHandling::fhCHECK_RECEIVER ||
|
||||
freezeHandling == SendFreezeHandling::fhBOTH) &&
|
||||
isFrozen(view, receiver, amount.issue()))
|
||||
return tecFROZEN;
|
||||
|
||||
if (balanceHandling == SendBalanceHandling::bhIGNORE)
|
||||
return tesSUCCESS;
|
||||
|
||||
STAmount const spendableAmount = accountHolds(
|
||||
view,
|
||||
sender,
|
||||
amount.get<Issue>(),
|
||||
fhIGNORE_FREEZE, // already checked freeze above
|
||||
ahIGNORE_AUTH, // already checked auth above
|
||||
j);
|
||||
|
||||
// If the balance is less than or equal to 0
|
||||
if (spendableAmount <= beast::zero)
|
||||
return tecINSUFFICIENT_FUNDS;
|
||||
|
||||
// If the spendable amount is less than the amount
|
||||
if (spendableAmount < amount)
|
||||
return tecINSUFFICIENT_FUNDS;
|
||||
|
||||
// If the amount is not addable to the balance
|
||||
if (!canAdd(spendableAmount, amount))
|
||||
return tecPRECISION_LOSS;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
static TER
|
||||
canTransferMPT(
|
||||
ReadView const& view,
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
STAmount const& amount,
|
||||
beast::Journal j,
|
||||
SendIssuerHandling issuerHandling,
|
||||
SendEscrowHandling escrowHandling,
|
||||
SendAuthHandling authHandling,
|
||||
SendFreezeHandling freezeHandling,
|
||||
SendTransferHandling transferHandling,
|
||||
SendBalanceHandling balanceHandling)
|
||||
{
|
||||
AccountID issuer = amount.getIssuer();
|
||||
// If the issuer is the same as the sender
|
||||
if (issuerHandling == SendIssuerHandling::ihSENDER_NOT_ALLOWED && issuer == sender)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the issuer is the same as the receiver
|
||||
if (issuerHandling == SendIssuerHandling::ihRECEIVER_NOT_ALLOWED && issuer == receiver)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the mpt does not exist
|
||||
auto const issuanceKey = keylet::mptIssuance(amount.get<MPTIssue>().getMptID());
|
||||
auto const sleIssuance = view.read(issuanceKey);
|
||||
if (!sleIssuance)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
// If the lsfMPTCanEscrow is not enabled
|
||||
if (escrowHandling == SendEscrowHandling::ehCHECK && !sleIssuance->isFlag(lsfMPTCanEscrow))
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
// If the issuer is not the same as the issuer of the mpt
|
||||
if (sleIssuance->getAccountID(sfIssuer) != issuer)
|
||||
return tecNO_PERMISSION; // LCOV_EXCL_LINE
|
||||
|
||||
// If the sender does not have the mpt
|
||||
if (!view.exists(keylet::mptoken(issuanceKey.key, sender)))
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
|
||||
auto const& mptIssue = amount.get<MPTIssue>();
|
||||
|
||||
// If the issuer has requireAuth set, check if the sender is authorized
|
||||
if (authHandling == SendAuthHandling::ahCHECK_SENDER ||
|
||||
authHandling == SendAuthHandling::ahBOTH)
|
||||
{
|
||||
if (auto const ter = requireAuth(view, mptIssue, sender, AuthType::WeakAuth);
|
||||
ter != tesSUCCESS)
|
||||
return ter;
|
||||
}
|
||||
|
||||
// If the issuer has requireAuth set, check if the receiver is authorized
|
||||
if (authHandling == SendAuthHandling::ahCHECK_RECEIVER ||
|
||||
authHandling == SendAuthHandling::ahBOTH)
|
||||
{
|
||||
if (auto const ter = requireAuth(view, mptIssue, receiver, AuthType::WeakAuth);
|
||||
ter != tesSUCCESS)
|
||||
return ter;
|
||||
}
|
||||
|
||||
// If the issuer has frozen the sender, return tecLOCKED
|
||||
if ((freezeHandling == SendFreezeHandling::fhCHECK_SENDER ||
|
||||
freezeHandling == SendFreezeHandling::fhBOTH) &&
|
||||
isFrozen(view, sender, mptIssue))
|
||||
return tecLOCKED;
|
||||
|
||||
// If the issuer has frozen the receiver, return tecLOCKED
|
||||
if ((freezeHandling == SendFreezeHandling::fhCHECK_RECEIVER ||
|
||||
freezeHandling == SendFreezeHandling::fhBOTH) &&
|
||||
isFrozen(view, receiver, mptIssue))
|
||||
return tecLOCKED;
|
||||
|
||||
// If the mpt cannot be transferred, return tecNO_AUTH
|
||||
if (transferHandling == SendTransferHandling::thCHECK)
|
||||
{
|
||||
if (auto const ter = canTransfer(view, mptIssue, sender, receiver); ter != tesSUCCESS)
|
||||
return ter;
|
||||
}
|
||||
|
||||
if (balanceHandling == SendBalanceHandling::bhIGNORE)
|
||||
return tesSUCCESS;
|
||||
|
||||
STAmount const spendableAmount = accountHolds(
|
||||
view,
|
||||
sender,
|
||||
amount.get<MPTIssue>(),
|
||||
fhIGNORE_FREEZE, // already checked freeze above
|
||||
ahIGNORE_AUTH, // already checked auth above
|
||||
j);
|
||||
|
||||
// If the balance is less than or equal to 0, return tecINSUFFICIENT_FUNDS
|
||||
if (spendableAmount <= beast::zero)
|
||||
return tecINSUFFICIENT_FUNDS;
|
||||
|
||||
// If the spendable amount is less than the amount, return
|
||||
// tecINSUFFICIENT_FUNDS
|
||||
if (spendableAmount < amount)
|
||||
return tecINSUFFICIENT_FUNDS;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
canTransferFT(
|
||||
ReadView const& view,
|
||||
AccountID const& sender,
|
||||
AccountID const& receiver,
|
||||
STAmount const& amount,
|
||||
beast::Journal j,
|
||||
SendIssuerHandling issuerHandling = SendIssuerHandling::ihIGNORE,
|
||||
SendEscrowHandling escrowHandling = SendEscrowHandling::ehIGNORE,
|
||||
SendAuthHandling authHandling = SendAuthHandling::ahBOTH,
|
||||
SendFreezeHandling freezeHandling = SendFreezeHandling::fhBOTH,
|
||||
SendTransferHandling transferHandling = SendTransferHandling::thIGNORE,
|
||||
SendBalanceHandling balanceHandling = SendBalanceHandling::bhCHECK)
|
||||
{
|
||||
return std::visit(
|
||||
[&]<ValidIssueType TIss>(TIss const& issue) -> TER {
|
||||
if constexpr (std::is_same_v<TIss, Issue>)
|
||||
return canTransferIOU(
|
||||
view,
|
||||
sender,
|
||||
receiver,
|
||||
amount,
|
||||
j,
|
||||
issuerHandling,
|
||||
escrowHandling,
|
||||
authHandling,
|
||||
freezeHandling,
|
||||
transferHandling,
|
||||
balanceHandling);
|
||||
else
|
||||
return canTransferMPT(
|
||||
view,
|
||||
sender,
|
||||
receiver,
|
||||
amount,
|
||||
j,
|
||||
issuerHandling,
|
||||
escrowHandling,
|
||||
authHandling,
|
||||
freezeHandling,
|
||||
transferHandling,
|
||||
balanceHandling);
|
||||
},
|
||||
amount.asset().value());
|
||||
}
|
||||
TER
|
||||
cleanupOnAccountDelete(
|
||||
ApplyView& view,
|
||||
|
||||
@@ -1,643 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2025 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/ContractUtils.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenUtils.h>
|
||||
#include <xrpl/protocol/st.h>
|
||||
#include <xrpl/server/NetworkOPs.h>
|
||||
|
||||
namespace xrpl {
|
||||
namespace contract {
|
||||
|
||||
struct BlobHash
|
||||
{
|
||||
std::size_t
|
||||
operator()(Blob const& b) const noexcept
|
||||
{
|
||||
if (b.empty())
|
||||
return 0;
|
||||
return std::hash<std::string_view>{}(
|
||||
std::string_view(reinterpret_cast<char const*>(b.data()), b.size()));
|
||||
}
|
||||
};
|
||||
|
||||
int64_t
|
||||
contractCreateFee(uint64_t byteCount)
|
||||
{
|
||||
constexpr uint64_t mul = static_cast<uint64_t>(createByteMultiplier);
|
||||
if (byteCount > std::numeric_limits<uint64_t>::max() / mul)
|
||||
return feeCalculationFailed; // overflow
|
||||
uint64_t uf = byteCount * mul;
|
||||
if (uf > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
|
||||
return feeCalculationFailed;
|
||||
return static_cast<int64_t>(uf);
|
||||
}
|
||||
|
||||
NotTEC
|
||||
preflightFunctions(STTx const& tx, beast::Journal j)
|
||||
{
|
||||
// Functions must be present if ContractCode is present.
|
||||
if (!tx.isFieldPresent(sfContractCode))
|
||||
return tesSUCCESS;
|
||||
|
||||
if (!tx.isFieldPresent(sfFunctions))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: ContractCode present but "
|
||||
"Functions missing.";
|
||||
return temARRAY_EMPTY;
|
||||
}
|
||||
|
||||
auto const& functions = tx.getFieldArray(sfFunctions);
|
||||
|
||||
if (functions.empty())
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Functions array empty.";
|
||||
return temARRAY_EMPTY;
|
||||
}
|
||||
|
||||
// Functions must not exceed n entries.
|
||||
if (functions.size() > contract::maxContractFunctions)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Functions array too large.";
|
||||
return temARRAY_TOO_LARGE;
|
||||
}
|
||||
|
||||
std::unordered_set<Blob, BlobHash> uniqueFunctions;
|
||||
uniqueFunctions.reserve(functions.size());
|
||||
for (auto const& function : functions)
|
||||
{
|
||||
// Functions must be unique by name.
|
||||
auto const& functionName = function.getFieldVL(sfFunctionName);
|
||||
if (!uniqueFunctions.insert(functionName).second)
|
||||
{
|
||||
JLOG(j.trace()) << "Duplicate function name: " << strHex(functionName);
|
||||
return temREDUNDANT;
|
||||
}
|
||||
|
||||
auto const& parameters = function.getFieldArray(sfParameters);
|
||||
|
||||
// Function Parameters must not exceed n entries each.
|
||||
if (parameters.size() > contract::maxContractParams)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Function Parameters "
|
||||
"array is too large.";
|
||||
return temARRAY_TOO_LARGE;
|
||||
}
|
||||
|
||||
std::unordered_set<Blob, BlobHash> uniqueParameters;
|
||||
uniqueParameters.reserve(parameters.size());
|
||||
|
||||
for (auto const& param : parameters)
|
||||
{
|
||||
// Function Parameter must have a flag.
|
||||
if (!param.isFieldPresent(sfParameterFlag))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Function Parameter "
|
||||
"is missing flag.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Function Parameter must have a type.
|
||||
if (!param.isFieldPresent(sfParameterType))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Function Parameter "
|
||||
"is missing type.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Function Parameter flags must be valid.
|
||||
auto const flags = param.getFieldU32(sfParameterFlag);
|
||||
if (flags & tfContractParameterMask)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Invalid parameter "
|
||||
"flag in Function.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
NotTEC
|
||||
preflightInstanceParameters(STTx const& tx, beast::Journal j)
|
||||
{
|
||||
if (!tx.isFieldPresent(sfInstanceParameters))
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const& instanceParameters = tx.getFieldArray(sfInstanceParameters);
|
||||
|
||||
// InstanceParameters must not be empty.
|
||||
if (instanceParameters.empty())
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameters empty array.";
|
||||
return temARRAY_EMPTY;
|
||||
}
|
||||
|
||||
// InstanceParameters must not exceed n entries.
|
||||
if (instanceParameters.size() > contract::maxContractParams)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameters array "
|
||||
"is too large.";
|
||||
return temARRAY_TOO_LARGE;
|
||||
}
|
||||
|
||||
std::unordered_set<Blob, BlobHash> uniqueParameters;
|
||||
uniqueParameters.reserve(instanceParameters.size());
|
||||
for (auto const& param : instanceParameters)
|
||||
{
|
||||
// Instance Parameter must have a flag.
|
||||
if (!param.isFieldPresent(sfParameterFlag))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Instance Parameter is missing flag.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Instance Parameter must have a type.
|
||||
if (!param.isFieldPresent(sfParameterType))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Instance Parameter is missing type.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Instance Parameter flags must be valid.
|
||||
auto const flags = param.getFieldU32(sfParameterFlag);
|
||||
if (flags & tfContractParameterMask)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Invalid parameter "
|
||||
"flag in Instance Parameter.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
validateParameterMapping(STArray const& params, STArray const& values, beast::Journal j)
|
||||
{
|
||||
if (params.size() != values.size())
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameterValues size "
|
||||
"does not match InstanceParameters size.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NotTEC
|
||||
preflightInstanceParameterValues(STTx const& tx, beast::Journal j)
|
||||
{
|
||||
if (!tx.isFieldPresent(sfInstanceParameterValues))
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const& instanceParameterValues = tx.getFieldArray(sfInstanceParameterValues);
|
||||
|
||||
// InstanceParameters must not be empty.
|
||||
if (instanceParameterValues.empty())
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameterValues is missing.";
|
||||
return temARRAY_EMPTY;
|
||||
}
|
||||
|
||||
// InstanceParameterValues must not exceed n entries.
|
||||
if (instanceParameterValues.size() > contract::maxContractParams)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameterValues "
|
||||
"array is too large.";
|
||||
return temARRAY_TOO_LARGE;
|
||||
}
|
||||
|
||||
std::unordered_set<Blob, BlobHash> uniqueParameters;
|
||||
uniqueParameters.reserve(instanceParameterValues.size());
|
||||
for (auto const& param : instanceParameterValues)
|
||||
{
|
||||
// Instance Parameter must have a flag.
|
||||
if (!param.isFieldPresent(sfParameterFlag))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Instance Parameter is missing flag.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Instance Parameter must have a value.
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Instance Parameter is "
|
||||
"missing value.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Instance Parameter flags must be valid.
|
||||
auto const flags = param.getFieldU32(sfParameterFlag);
|
||||
if (flags & tfContractParameterMask)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: Invalid parameter "
|
||||
"flag in Instance Parameter.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
// Only validate the mapping if InstanceParameters are present
|
||||
bool valid = true;
|
||||
if (tx.isFieldPresent(sfInstanceParameters))
|
||||
valid = validateParameterMapping(
|
||||
tx.getFieldArray(sfInstanceParameters), tx.getFieldArray(sfInstanceParameterValues), j);
|
||||
if (!valid)
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameterValues do not match "
|
||||
"InstanceParameters.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
// Validate flags in InstanceParameterValues
|
||||
if (auto const res = preflightFlagParameters(instanceParameterValues, j); !isTesSuccess(res))
|
||||
{
|
||||
JLOG(j.trace()) << "ContractCreate/Modify: InstanceParameterValues flag "
|
||||
"validation failed: "
|
||||
<< transToken(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
isValidParameterFlag(std::uint32_t flags)
|
||||
{
|
||||
return (flags & tfContractParameterMask) == 0;
|
||||
}
|
||||
|
||||
NotTEC
|
||||
preflightFlagParameters(STArray const& parameters, beast::Journal j)
|
||||
{
|
||||
for (auto const& param : parameters)
|
||||
{
|
||||
if (!param.isFieldPresent(sfParameterFlag) ||
|
||||
!isValidParameterFlag(param.getFieldU32(sfParameterFlag)))
|
||||
continue; // Skip invalid flags
|
||||
|
||||
switch (param.getFieldU32(sfParameterFlag))
|
||||
{
|
||||
case tfSendAmount: {
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
return temMALFORMED;
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
STAmount amount = value.getFieldAmount();
|
||||
// Preflight Transfer Amount
|
||||
if (isXRP(amount))
|
||||
{
|
||||
if (amount <= beast::zero)
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
else if (amount.holds<Issue>())
|
||||
{
|
||||
if (amount.native() || amount <= beast::zero)
|
||||
return temBAD_AMOUNT;
|
||||
|
||||
if (badCurrency() == amount.getCurrency())
|
||||
return temBAD_CURRENCY;
|
||||
}
|
||||
else if (amount.holds<MPTIssue>())
|
||||
{
|
||||
if (amount.native() || amount.mpt() > MPTAmount{maxMPTokenAmount} ||
|
||||
amount <= beast::zero)
|
||||
return temBAD_AMOUNT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tfSendNFToken: {
|
||||
break;
|
||||
}
|
||||
case tfAuthorizeToken: {
|
||||
return temDISABLED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
preclaimFlagParameters(
|
||||
ReadView const& view,
|
||||
AccountID const& sourceAccount,
|
||||
AccountID const& contractAccount,
|
||||
STArray const& parameters,
|
||||
beast::Journal j)
|
||||
{
|
||||
for (auto const& param : parameters)
|
||||
{
|
||||
if (!param.isFieldPresent(sfParameterFlag) ||
|
||||
!isValidParameterFlag(param.getFieldU32(sfParameterFlag)))
|
||||
continue; // Skip invalid flags
|
||||
|
||||
switch (param.getFieldU32(sfParameterFlag))
|
||||
{
|
||||
case tfSendAmount: {
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
return tecINTERNAL;
|
||||
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
STAmount amount = value.getFieldAmount();
|
||||
// Preclaim Transfer Amount
|
||||
if (isXRP(amount))
|
||||
{
|
||||
auto const accountSle = view.read(keylet::account(sourceAccount));
|
||||
if (!accountSle)
|
||||
return tecINTERNAL;
|
||||
|
||||
auto const& mSourceBalance = accountSle->getFieldAmount(sfBalance);
|
||||
if (mSourceBalance < amount.xrp())
|
||||
return tecUNFUNDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto ter = canTransferFT(
|
||||
view,
|
||||
sourceAccount,
|
||||
contractAccount,
|
||||
amount,
|
||||
j,
|
||||
SendIssuerHandling::ihIGNORE,
|
||||
SendEscrowHandling::ehIGNORE,
|
||||
SendAuthHandling::ahBOTH,
|
||||
SendFreezeHandling::fhBOTH,
|
||||
SendTransferHandling::thIGNORE,
|
||||
SendBalanceHandling::bhCHECK))
|
||||
{
|
||||
JLOG(j.trace()) << "preclaimFlagParameters: Cannot "
|
||||
"transfer amount: "
|
||||
<< amount;
|
||||
return ter;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tfSendNFToken: {
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
return tecINTERNAL;
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
auto const& nftokenID = value.getFieldH256();
|
||||
// Preclaim Transfer NFT Token
|
||||
if (!nft::findToken(view, sourceAccount, nftokenID))
|
||||
{
|
||||
JLOG(j.trace())
|
||||
<< "preclaimFlagParameters: Cannot transfer NFT token: " << nftokenID;
|
||||
return tecNO_ENTRY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tfAuthorizeToken: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
doApplyFlagParameters(
|
||||
ApplyView& view,
|
||||
STTx const& tx,
|
||||
AccountID const& sourceAccount,
|
||||
AccountID const& contractAccount,
|
||||
STArray const& parameters,
|
||||
XRPAmount const& priorBalance,
|
||||
beast::Journal j)
|
||||
{
|
||||
for (auto const& param : parameters)
|
||||
{
|
||||
if (!param.isFieldPresent(sfParameterFlag) ||
|
||||
!isValidParameterFlag(param.getFieldU32(sfParameterFlag)))
|
||||
continue; // Skip invalid flags
|
||||
|
||||
switch (param.getFieldU32(sfParameterFlag))
|
||||
{
|
||||
case tfSendAmount: {
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
return tecINTERNAL;
|
||||
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
STAmount amount = value.getFieldAmount();
|
||||
if (auto ter = accountSend(
|
||||
view, sourceAccount, contractAccount, amount, j, WaiveTransferFee::No);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
JLOG(j.trace()) << "doApplyFlagParameters: Failed to send amount: " << amount;
|
||||
return ter;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tfSendNFToken: {
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
return tecINTERNAL;
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
auto const& nftokenID = value.getFieldH256();
|
||||
if (auto ter =
|
||||
nft::transferNFToken(view, sourceAccount, contractAccount, nftokenID);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
JLOG(j.trace())
|
||||
<< "doApplyFlagParameters: Failed to send NFT token: " << nftokenID;
|
||||
return ter;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tfAuthorizeToken: {
|
||||
return tecINTERNAL;
|
||||
// if (!param.isFieldPresent(sfParameterValue))
|
||||
// return tecINTERNAL;
|
||||
// // Handle tfAuthorizeToken if needed
|
||||
// auto const& value = param.getFieldData(sfParameterValue);
|
||||
// STAmount limit = value.getFieldAmount();
|
||||
// Asset asset = Asset{limit.issue()};
|
||||
// if (auto ter = canAddHolding(view, asset);
|
||||
// !isTesSuccess(ter))
|
||||
// {
|
||||
// JLOG(j.trace()) << "doApplyFlagParameters: Cannot add "
|
||||
// "holding for asset: "
|
||||
// << to_string(asset);
|
||||
// return ter;
|
||||
// }
|
||||
// // Set the issuer to the contract account for the holding
|
||||
// limit.setIssuer(contractAccount);
|
||||
// if (auto ter = addEmptyHolding(
|
||||
// view, contractAccount, priorBalance, asset, limit,
|
||||
// j);
|
||||
// !isTesSuccess(ter))
|
||||
// {
|
||||
// JLOG(j.trace()) << "doApplyFlagParameters: Failed to add
|
||||
// "
|
||||
// "holding for asset: "
|
||||
// << to_string(asset);
|
||||
// return ter;
|
||||
// }
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
contractDataReserve(uint32_t size)
|
||||
{
|
||||
// Divide by dataByteMultiplier and round up to the nearest whole number
|
||||
return (size + dataByteMultiplier - 1U) / dataByteMultiplier;
|
||||
}
|
||||
|
||||
TER
|
||||
setContractData(
|
||||
ServiceRegistry& registry,
|
||||
ApplyView& view,
|
||||
AccountID const& account,
|
||||
AccountID const& contractAccount,
|
||||
STJson const& data)
|
||||
{
|
||||
auto const j = registry.getJournal("View");
|
||||
auto const sleAccount = view.peek(keylet::account(account));
|
||||
if (!sleAccount)
|
||||
return tefINTERNAL;
|
||||
|
||||
// if the blob is too large don't set it
|
||||
if (data.size() > maxContractDataSize)
|
||||
return temARRAY_TOO_LARGE;
|
||||
|
||||
auto dataKeylet = keylet::contractData(account, contractAccount);
|
||||
auto dataSle = view.peek(dataKeylet);
|
||||
|
||||
// DELETE
|
||||
if (data.size() == 0)
|
||||
{
|
||||
if (!dataSle)
|
||||
return tesSUCCESS;
|
||||
|
||||
uint32_t oldDataReserve = contractDataReserve(dataSle->getFieldJson(sfContractJson).size());
|
||||
|
||||
std::uint64_t const page = (*dataSle)[sfOwnerNode];
|
||||
// Remove the page from the account directory
|
||||
if (!view.dirRemove(keylet::ownerDir(account), page, dataKeylet.key, false))
|
||||
return tefBAD_LEDGER;
|
||||
|
||||
// remove the actual contract data sle
|
||||
view.erase(dataSle);
|
||||
|
||||
// reduce the owner count
|
||||
adjustOwnerCount(view, sleAccount, -oldDataReserve, j);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
std::uint32_t ownerCount{(*sleAccount)[sfOwnerCount]};
|
||||
bool createNew = !dataSle;
|
||||
if (createNew)
|
||||
{
|
||||
// CREATE
|
||||
uint32_t dataReserve = contractDataReserve(data.size());
|
||||
uint32_t newReserve = ownerCount + dataReserve;
|
||||
XRPAmount const newReserveAmount{view.fees().accountReserve(newReserve)};
|
||||
if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserveAmount)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
adjustOwnerCount(view, sleAccount, dataReserve, j);
|
||||
// create an entry
|
||||
dataSle = std::make_shared<SLE>(dataKeylet);
|
||||
dataSle->setFieldJson(sfContractJson, data);
|
||||
dataSle->setAccountID(sfOwner, account);
|
||||
dataSle->setAccountID(sfContractAccount, contractAccount);
|
||||
|
||||
auto const page =
|
||||
view.dirInsert(keylet::ownerDir(account), dataKeylet.key, describeOwnerDir(account));
|
||||
if (!page)
|
||||
return tecDIR_FULL;
|
||||
|
||||
dataSle->setFieldU64(sfOwnerNode, *page);
|
||||
|
||||
// add new data to ledger
|
||||
view.insert(dataSle);
|
||||
}
|
||||
else
|
||||
{
|
||||
// UPDATE
|
||||
uint32_t oldDataReserve = contractDataReserve(dataSle->getFieldJson(sfContractJson).size());
|
||||
uint32_t newDataReserve = contractDataReserve(data.size());
|
||||
if (newDataReserve != oldDataReserve)
|
||||
{
|
||||
// if the reserve changes, we need to adjust the owner count
|
||||
uint32_t newReserve = ownerCount - oldDataReserve + newDataReserve;
|
||||
XRPAmount const newReserveAmount{view.fees().accountReserve(newReserve)};
|
||||
if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserveAmount)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
adjustOwnerCount(view, sleAccount, newReserve, j);
|
||||
}
|
||||
|
||||
// update the data
|
||||
dataSle->setFieldJson(sfContractJson, data);
|
||||
view.update(dataSle);
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
finalizeContractData(
|
||||
ServiceRegistry& registry,
|
||||
ApplyView& view,
|
||||
AccountID const& contractAccount,
|
||||
ContractDataMap const& dataMap,
|
||||
ContractEventMap const& eventMap,
|
||||
uint256 const& txnID)
|
||||
{
|
||||
auto const& j = registry.getJournal("View");
|
||||
uint16_t changeCount = 0;
|
||||
|
||||
for (auto const& [name, data] : eventMap)
|
||||
registry.getOPs().pubContractEvent(name, data);
|
||||
|
||||
for (auto const& accEntry : dataMap)
|
||||
{
|
||||
auto const& acc = accEntry.first;
|
||||
auto const& cacheEntry = accEntry.second;
|
||||
bool is_modified = cacheEntry.first;
|
||||
auto const& jsonData = cacheEntry.second;
|
||||
if (is_modified)
|
||||
{
|
||||
changeCount++;
|
||||
if (changeCount > maxDataModifications)
|
||||
{
|
||||
// overflow
|
||||
JLOG(j.trace()) << "ContractError[TX:" << txnID
|
||||
<< "]: SetContractData failed: Too many data changes";
|
||||
return tecWASM_REJECTED;
|
||||
}
|
||||
|
||||
TER result = setContractData(registry, view, acc, contractAccount, jsonData);
|
||||
if (!isTesSuccess(result))
|
||||
{
|
||||
JLOG(j.warn()) << "ContractError[TX:" << txnID
|
||||
<< "]: SetContractData failed: " << result << " Account: " << acc;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
} // namespace contract
|
||||
} // namespace xrpl
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
// and follow the format described at http://semver.org/
|
||||
//------------------------------------------------------------------------------
|
||||
// clang-format off
|
||||
char const* const versionString = "3.2.0-b0"
|
||||
char const* const versionString = "3.2.0-b3"
|
||||
// clang-format on
|
||||
;
|
||||
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/Emitable.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Permissions.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
Emitable::Emitable()
|
||||
{
|
||||
emitableTx_ = {
|
||||
#pragma push_macro("TRANSACTION")
|
||||
#undef TRANSACTION
|
||||
|
||||
#define TRANSACTION(tag, value, name, delegatable, amendment, permissions, emitable, fields) \
|
||||
{value, emitable},
|
||||
#include <xrpl/protocol/detail/transactions.macro>
|
||||
|
||||
#undef TRANSACTION
|
||||
#pragma pop_macro("TRANSACTION")
|
||||
};
|
||||
|
||||
granularEmitableMap_ = {
|
||||
#pragma push_macro("EMITABLE")
|
||||
#undef EMITABLE
|
||||
|
||||
#define EMITABLE(type, txType, value) {#type, type},
|
||||
|
||||
#include <xrpl/protocol/detail/emitable.macro>
|
||||
|
||||
#undef EMITABLE
|
||||
#pragma pop_macro("EMITABLE")
|
||||
};
|
||||
|
||||
granularNameMap_ = {
|
||||
#pragma push_macro("EMITABLE")
|
||||
#undef EMITABLE
|
||||
|
||||
#define EMITABLE(type, txType, value) {type, #type},
|
||||
|
||||
#include <xrpl/protocol/detail/emitable.macro>
|
||||
|
||||
#undef EMITABLE
|
||||
#pragma pop_macro("EMITABLE")
|
||||
};
|
||||
|
||||
granularTxTypeMap_ = {
|
||||
#pragma push_macro("EMITABLE")
|
||||
#undef EMITABLE
|
||||
|
||||
#define EMITABLE(type, txType, value) {type, txType},
|
||||
|
||||
#include <xrpl/protocol/detail/emitable.macro>
|
||||
|
||||
#undef EMITABLE
|
||||
#pragma pop_macro("EMITABLE")
|
||||
};
|
||||
|
||||
for ([[maybe_unused]] auto const& emitable : granularEmitableMap_)
|
||||
XRPL_ASSERT(
|
||||
emitable.second > UINT16_MAX,
|
||||
"xrpl::Emitable::granularEmitableMap_ : granular emitable "
|
||||
"value must not exceed the maximum uint16_t value.");
|
||||
}
|
||||
|
||||
Emitable const&
|
||||
Emitable::getInstance()
|
||||
{
|
||||
static Emitable const instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
std::optional<std::string>
|
||||
Emitable::getEmitableName(std::uint32_t const value) const
|
||||
{
|
||||
auto const emitableValue = static_cast<GranularEmitableType>(value);
|
||||
if (auto const granular = getGranularName(emitableValue))
|
||||
return *granular;
|
||||
|
||||
// not a granular emitable, check if it maps to a transaction type
|
||||
auto const txType = emitableToTxType(value);
|
||||
if (auto const* item = TxFormats::getInstance().findByType(txType); item != nullptr)
|
||||
return item->getName();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::uint32_t>
|
||||
Emitable::getGranularValue(std::string const& name) const
|
||||
{
|
||||
auto const it = granularEmitableMap_.find(name);
|
||||
if (it != granularEmitableMap_.end())
|
||||
return static_cast<uint32_t>(it->second);
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string>
|
||||
Emitable::getGranularName(GranularEmitableType const& value) const
|
||||
{
|
||||
auto const it = granularNameMap_.find(value);
|
||||
if (it != granularNameMap_.end())
|
||||
return it->second;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<TxType>
|
||||
Emitable::getGranularTxType(GranularEmitableType const& gpType) const
|
||||
{
|
||||
auto const it = granularTxTypeMap_.find(gpType);
|
||||
if (it != granularTxTypeMap_.end())
|
||||
return it->second;
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool
|
||||
Emitable::isEmitable(std::uint32_t const& emitableValue) const
|
||||
{
|
||||
auto const granularEmitable = getGranularName(static_cast<GranularEmitableType>(emitableValue));
|
||||
if (granularEmitable)
|
||||
// granular emitables are always allowed to be delegated
|
||||
return true;
|
||||
|
||||
auto const txType = emitableToTxType(emitableValue);
|
||||
auto const it = emitableTx_.find(txType);
|
||||
|
||||
// if (rules.enabled(fixDelegateV1_1))
|
||||
// {
|
||||
// if (it == delegatableTx_.end())
|
||||
// return false;
|
||||
|
||||
// auto const txFeaturesIt = txFeatureMap_.find(txType);
|
||||
// XRPL_ASSERT(
|
||||
// txFeaturesIt != txFeatureMap_.end(),
|
||||
// "xrpl::Emitables::isDelegatable : tx exists in txFeatureMap_");
|
||||
|
||||
// // fixDelegateV1_1: Delegation is only allowed if the required
|
||||
// amendment
|
||||
// // for the transaction is enabled. For transactions that do not
|
||||
// require
|
||||
// // an amendment, delegation is always allowed.
|
||||
// if (txFeaturesIt->second != uint256{} &&
|
||||
// !rules.enabled(txFeaturesIt->second))
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (it != emitableTx_.end() && it->second == Emittance::notEmitable)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Emitable::txToEmitableType(TxType const& type) const
|
||||
{
|
||||
return static_cast<uint32_t>(type) + 1;
|
||||
}
|
||||
|
||||
TxType
|
||||
Emitable::emitableToTxType(uint32_t const& value) const
|
||||
{
|
||||
return static_cast<TxType>(value - 1);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -79,12 +79,10 @@ enum class LedgerNameSpace : std::uint16_t {
|
||||
VAULT = 'V',
|
||||
LOAN_BROKER = 'l', // lower-case L
|
||||
LOAN = 'L',
|
||||
CONTRACT_SOURCE = 'Z',
|
||||
CONTRACT = 'z',
|
||||
CONTRACT_DATA = 'b',
|
||||
|
||||
// No longer used or supported. Left here to reserve the space
|
||||
// to avoid accidental reuse.
|
||||
CONTRACT [[deprecated]] = 'c',
|
||||
GENERATOR [[deprecated]] = 'g',
|
||||
NICKNAME [[deprecated]] = 'n',
|
||||
};
|
||||
@@ -532,24 +530,6 @@ permissionedDomain(uint256 const& domainID) noexcept
|
||||
return {ltPERMISSIONED_DOMAIN, domainID};
|
||||
}
|
||||
|
||||
Keylet
|
||||
contractSource(uint256 const& contractHash) noexcept
|
||||
{
|
||||
return {ltCONTRACT_SOURCE, indexHash(LedgerNameSpace::CONTRACT_SOURCE, contractHash)};
|
||||
}
|
||||
|
||||
Keylet
|
||||
contract(uint256 const& contractHash, AccountID const& owner, std::uint32_t seq) noexcept
|
||||
{
|
||||
return {ltCONTRACT, indexHash(LedgerNameSpace::CONTRACT, contractHash, owner, seq)};
|
||||
}
|
||||
|
||||
Keylet
|
||||
contractData(AccountID const& owner, AccountID const& contractAccount) noexcept
|
||||
{
|
||||
return {ltCONTRACT_DATA, indexHash(LedgerNameSpace::CONTRACT_DATA, owner, contractAccount)};
|
||||
}
|
||||
|
||||
} // namespace keylet
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -159,35 +159,6 @@ InnerObjectFormats::InnerObjectFormats()
|
||||
{sfTxnSignature, soeOPTIONAL},
|
||||
{sfSigners, soeOPTIONAL},
|
||||
});
|
||||
|
||||
add(sfFunction.jsonName.c_str(),
|
||||
sfFunction.getCode(),
|
||||
{
|
||||
{sfFunctionName, soeREQUIRED},
|
||||
{sfParameters, soeOPTIONAL},
|
||||
});
|
||||
|
||||
add(sfInstanceParameter.jsonName,
|
||||
sfInstanceParameter.getCode(),
|
||||
{
|
||||
{sfParameterFlag, soeREQUIRED},
|
||||
{sfParameterType, soeREQUIRED},
|
||||
});
|
||||
|
||||
add(sfInstanceParameterValue.jsonName,
|
||||
sfInstanceParameterValue.getCode(),
|
||||
{
|
||||
{sfParameterFlag, soeREQUIRED},
|
||||
{sfParameterValue, soeREQUIRED},
|
||||
});
|
||||
|
||||
add(sfParameter.jsonName,
|
||||
sfParameter.getCode(),
|
||||
{
|
||||
{sfParameterFlag, soeOPTIONAL},
|
||||
{sfParameterType, soeOPTIONAL},
|
||||
{sfParameterValue, soeOPTIONAL},
|
||||
});
|
||||
}
|
||||
|
||||
InnerObjectFormats const&
|
||||
|
||||
@@ -1,968 +0,0 @@
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/beast/core/LexicalCast.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/detail/STVar.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename U, typename S>
|
||||
constexpr std::enable_if_t<std::is_unsigned<U>::value && std::is_signed<S>::value, U>
|
||||
to_unsigned(S value)
|
||||
{
|
||||
if (value < 0 || std::numeric_limits<U>::max() < value)
|
||||
Throw<std::runtime_error>("Value out of range");
|
||||
return static_cast<U>(value);
|
||||
}
|
||||
|
||||
template <typename U1, typename U2>
|
||||
constexpr std::enable_if_t<std::is_unsigned<U1>::value && std::is_unsigned<U2>::value, U1>
|
||||
to_unsigned(U2 value)
|
||||
{
|
||||
if (std::numeric_limits<U1>::max() < value)
|
||||
Throw<std::runtime_error>("Value out of range");
|
||||
return static_cast<U1>(value);
|
||||
}
|
||||
|
||||
// TODO
|
||||
STData::STData(SField const& n) : STBase(n), inner_type_(STI_NOTPRESENT), data_(STBase{})
|
||||
{
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, unsigned char v)
|
||||
: STBase(n)
|
||||
, inner_type_(STI_UINT8)
|
||||
, data_(detail::STVar(detail::defaultObject, sfCloseResolution))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt8>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, std::uint16_t v)
|
||||
: STBase(n)
|
||||
, inner_type_(STI_UINT16)
|
||||
, data_(detail::STVar(detail::defaultObject, sfSignerWeight))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt16>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, std::uint32_t v)
|
||||
: STBase(n), inner_type_(STI_UINT32), data_(detail::STVar(detail::defaultObject, sfNetworkID))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt32>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, std::uint64_t v)
|
||||
: STBase(n), inner_type_(STI_UINT64), data_(detail::STVar(detail::defaultObject, sfIndexNext))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt64>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, uint128 const& v)
|
||||
: STBase(n), inner_type_(STI_UINT128), data_(detail::STVar(detail::defaultObject, sfEmailHash))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt128>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, uint160 const& v)
|
||||
: STBase(n)
|
||||
, inner_type_(STI_UINT160)
|
||||
, data_(detail::STVar(detail::defaultObject, sfTakerPaysCurrency))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt160>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, uint192 const& v)
|
||||
: STBase(n)
|
||||
, inner_type_(STI_UINT192)
|
||||
, data_(detail::STVar(detail::defaultObject, sfMPTokenIssuanceID))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt192>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, uint256 const& v)
|
||||
: STBase(n), inner_type_(STI_UINT256), data_(detail::STVar(detail::defaultObject, sfLedgerHash))
|
||||
{
|
||||
setFieldUsingSetValue<STUInt256>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, Blob const& v)
|
||||
: STBase(n), inner_type_(STI_VL), data_(detail::STVar(detail::defaultObject, sfURI))
|
||||
{
|
||||
setFieldUsingSetValue<STBlob>(Buffer(v.data(), v.size()));
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, Slice const& v)
|
||||
: STBase(n), inner_type_(STI_VL), data_(detail::STVar(detail::defaultObject, sfURI))
|
||||
{
|
||||
setFieldUsingSetValue<STBlob>(Buffer(v.data(), v.size()));
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, STAmount const& v)
|
||||
: STBase(n), inner_type_(STI_AMOUNT), data_(detail::STVar(detail::defaultObject, sfAmount))
|
||||
{
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, AccountID const& v)
|
||||
: STBase(n), inner_type_(STI_ACCOUNT), data_(detail::STVar(detail::defaultObject, sfAccount))
|
||||
{
|
||||
setFieldUsingSetValue<STAccount>(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, STIssue const& v)
|
||||
: STBase(n), inner_type_(STI_ISSUE), data_(detail::STVar(detail::defaultObject, sfAsset))
|
||||
{
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, STCurrency const& v)
|
||||
: STBase(n), inner_type_(STI_CURRENCY), data_(detail::STVar(detail::defaultObject, sfBaseAsset))
|
||||
{
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
STData::STData(SField const& n, STNumber const& v)
|
||||
: STBase(n), inner_type_(STI_NUMBER), data_(detail::STVar(detail::defaultObject, sfNumber))
|
||||
{
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
STData::STData(SerialIter& sit, SField const& name) : STBase(name), data_(STBase{})
|
||||
{
|
||||
std::uint16_t stype = SerializedTypeID(sit.get16());
|
||||
inner_type_ = stype;
|
||||
SerializedTypeID s = static_cast<SerializedTypeID>(stype);
|
||||
switch (s)
|
||||
{
|
||||
case STI_UINT8: {
|
||||
data_ = detail::STVar(sit, sfCloseResolution);
|
||||
break;
|
||||
}
|
||||
case STI_UINT16: {
|
||||
data_ = detail::STVar(sit, sfSignerWeight);
|
||||
break;
|
||||
}
|
||||
case STI_UINT32: {
|
||||
data_ = detail::STVar(sit, sfNetworkID);
|
||||
break;
|
||||
}
|
||||
case STI_UINT64: {
|
||||
data_ = detail::STVar(sit, sfIndexNext);
|
||||
break;
|
||||
}
|
||||
case STI_UINT128: {
|
||||
data_ = detail::STVar(sit, sfEmailHash);
|
||||
break;
|
||||
}
|
||||
case STI_UINT160: {
|
||||
data_ = detail::STVar(sit, sfTakerPaysCurrency);
|
||||
break;
|
||||
}
|
||||
case STI_UINT192: {
|
||||
data_ = detail::STVar(sit, sfMPTokenIssuanceID);
|
||||
break;
|
||||
}
|
||||
case STI_UINT256: {
|
||||
data_ = detail::STVar(sit, sfLedgerHash);
|
||||
break;
|
||||
}
|
||||
case STI_VL: {
|
||||
data_ = detail::STVar(sit, sfURI);
|
||||
break;
|
||||
}
|
||||
case STI_AMOUNT: {
|
||||
data_ = detail::STVar(sit, sfAmount);
|
||||
break;
|
||||
}
|
||||
case STI_ACCOUNT: {
|
||||
data_ = detail::STVar(sit, sfAccount);
|
||||
break;
|
||||
}
|
||||
case STI_ISSUE: {
|
||||
data_ = detail::STVar(sit, sfAsset);
|
||||
break;
|
||||
}
|
||||
case STI_CURRENCY: {
|
||||
data_ = detail::STVar(sit, sfBaseAsset);
|
||||
break;
|
||||
}
|
||||
case STI_NUMBER: {
|
||||
data_ = detail::STVar(sit, sfNumber);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Throw<std::runtime_error>("STData: unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
STBase*
|
||||
STData::copy(std::size_t n, void* buf) const
|
||||
{
|
||||
return emplace(n, buf, *this);
|
||||
}
|
||||
|
||||
STBase*
|
||||
STData::move(std::size_t n, void* buf)
|
||||
{
|
||||
return emplace(n, buf, std::move(*this));
|
||||
}
|
||||
|
||||
std::size_t
|
||||
STData::size() const
|
||||
{
|
||||
switch (static_cast<SerializedTypeID>(inner_type_))
|
||||
{
|
||||
case STI_UINT8: {
|
||||
return sizeof(uint8_t);
|
||||
}
|
||||
case STI_UINT16: {
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
case STI_UINT32: {
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
case STI_UINT64: {
|
||||
return sizeof(uint64_t);
|
||||
}
|
||||
case STI_UINT128: {
|
||||
return uint128::size();
|
||||
}
|
||||
case STI_UINT160: {
|
||||
return uint160::size();
|
||||
}
|
||||
case STI_UINT192: {
|
||||
return uint192::size();
|
||||
}
|
||||
case STI_UINT256: {
|
||||
return uint256::size();
|
||||
}
|
||||
case STI_VL: {
|
||||
STBlob const& st_blob = data_.get().downcast<STBlob>();
|
||||
return st_blob.size();
|
||||
}
|
||||
case STI_AMOUNT: {
|
||||
// TODO: STAmount::size()
|
||||
STAmount const& st_amt = data_.get().downcast<STAmount>();
|
||||
return st_amt.native() ? 8 : 48;
|
||||
}
|
||||
case STI_ACCOUNT: {
|
||||
return uint160::size();
|
||||
}
|
||||
case STI_ISSUE: {
|
||||
// const STIssue& st_issue = data_.get().downcast<STIssue>();
|
||||
return 40; // 20 bytes for currency + 20 bytes for account
|
||||
}
|
||||
case STI_CURRENCY: {
|
||||
// const STCurrency& st_currency =
|
||||
// data_.get().downcast<STCurrency>();
|
||||
return 20; // 20 bytes for currency
|
||||
}
|
||||
case STI_NUMBER: {
|
||||
return sizeof(double);
|
||||
}
|
||||
default:
|
||||
Throw<std::runtime_error>("STData: unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
SerializedTypeID
|
||||
STData::getSType() const
|
||||
{
|
||||
return STI_DATA;
|
||||
}
|
||||
|
||||
void
|
||||
STData::add(Serializer& s) const
|
||||
{
|
||||
s.add16(inner_type_);
|
||||
|
||||
switch (static_cast<SerializedTypeID>(inner_type_))
|
||||
{
|
||||
case STI_UINT8: {
|
||||
STUInt8 const& st_uint8 = data_.get().downcast<STUInt8>();
|
||||
st_uint8.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT16: {
|
||||
STUInt16 const& st_uint16 = data_.get().downcast<STUInt16>();
|
||||
st_uint16.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT32: {
|
||||
STUInt32 const& st_uint32 = data_.get().downcast<STUInt32>();
|
||||
st_uint32.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT64: {
|
||||
STUInt64 const& st_uint64 = data_.get().downcast<STUInt64>();
|
||||
st_uint64.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT128: {
|
||||
STUInt128 const& st_uint128 = data_.get().downcast<STUInt128>();
|
||||
st_uint128.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT160: {
|
||||
STUInt160 const& st_uint160 = data_.get().downcast<STUInt160>();
|
||||
st_uint160.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT192: {
|
||||
STUInt192 const& st_uint192 = data_.get().downcast<STUInt192>();
|
||||
st_uint192.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_UINT256: {
|
||||
STUInt256 const& st_uint256 = data_.get().downcast<STUInt256>();
|
||||
st_uint256.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_VL: {
|
||||
STBlob const& st_blob = data_.get().downcast<STBlob>();
|
||||
st_blob.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_AMOUNT: {
|
||||
STAmount const& st_amt = data_.get().downcast<STAmount>();
|
||||
st_amt.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_ACCOUNT: {
|
||||
STAccount const& st_acc = data_.get().downcast<STAccount>();
|
||||
st_acc.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_ISSUE: {
|
||||
STIssue const& st_issue = data_.get().downcast<STIssue>();
|
||||
st_issue.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_CURRENCY: {
|
||||
STCurrency const& st_currency = data_.get().downcast<STCurrency>();
|
||||
st_currency.add(s);
|
||||
break;
|
||||
}
|
||||
case STI_NUMBER: {
|
||||
STNumber const& st_number = data_.get().downcast<STNumber>();
|
||||
st_number.add(s);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Throw<std::runtime_error>("STData: unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
STData::isEquivalent(STBase const& t) const
|
||||
{
|
||||
auto const* const tPtr = dynamic_cast<STData const*>(&t);
|
||||
return tPtr && (default_ == tPtr->default_) && (inner_type_ == tPtr->inner_type_) &&
|
||||
(data_ == tPtr->data_);
|
||||
}
|
||||
|
||||
bool
|
||||
STData::isDefault() const
|
||||
{
|
||||
return default_;
|
||||
}
|
||||
|
||||
std::string
|
||||
STData::getInnerTypeString() const
|
||||
{
|
||||
std::string inner_type_str = "Unknown";
|
||||
switch (static_cast<SerializedTypeID>(inner_type_))
|
||||
{
|
||||
case STI_UINT8:
|
||||
inner_type_str = "UINT8";
|
||||
break;
|
||||
case STI_UINT16:
|
||||
inner_type_str = "UINT16";
|
||||
break;
|
||||
case STI_UINT32:
|
||||
inner_type_str = "UINT32";
|
||||
break;
|
||||
case STI_UINT64:
|
||||
inner_type_str = "UINT64";
|
||||
break;
|
||||
case STI_UINT128:
|
||||
inner_type_str = "UINT128";
|
||||
break;
|
||||
case STI_UINT160:
|
||||
inner_type_str = "UINT160";
|
||||
break;
|
||||
case STI_UINT192:
|
||||
inner_type_str = "UINT192";
|
||||
break;
|
||||
case STI_UINT256:
|
||||
inner_type_str = "UINT256";
|
||||
break;
|
||||
case STI_VL:
|
||||
inner_type_str = "VL";
|
||||
break;
|
||||
case STI_AMOUNT:
|
||||
inner_type_str = "AMOUNT";
|
||||
break;
|
||||
case STI_ACCOUNT:
|
||||
inner_type_str = "ACCOUNT";
|
||||
break;
|
||||
case STI_ISSUE:
|
||||
inner_type_str = "ISSUE";
|
||||
break;
|
||||
case STI_CURRENCY:
|
||||
inner_type_str = "CURRENCY";
|
||||
break;
|
||||
case STI_NUMBER:
|
||||
inner_type_str = "NUMBER";
|
||||
break;
|
||||
// Add other known types as needed
|
||||
default:
|
||||
inner_type_str = std::to_string(inner_type_);
|
||||
}
|
||||
|
||||
return inner_type_str;
|
||||
}
|
||||
|
||||
std::string
|
||||
STData::getText() const
|
||||
{
|
||||
std::string inner_type_str = getInnerTypeString();
|
||||
return "STData{InnerType: " + inner_type_str + ", Data: " + data_.get().getText() + "}";
|
||||
}
|
||||
|
||||
Json::Value
|
||||
STData::getJson(JsonOptions options) const
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
ret[jss::type] = getInnerTypeString();
|
||||
ret[jss::value] = data_.get().getJson(options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STBase*
|
||||
STData::makeFieldPresent()
|
||||
{
|
||||
STBase* f = &data_.get(); // getPIndex(index);
|
||||
|
||||
if (f->getSType() != STI_NOTPRESENT)
|
||||
return f;
|
||||
|
||||
data_ = detail::STVar(detail::nonPresentObject, f->getFName());
|
||||
return &data_.get();
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldU8(unsigned char v)
|
||||
{
|
||||
inner_type_ = STI_UINT8;
|
||||
data_ = detail::STVar(detail::defaultObject, sfCloseResolution);
|
||||
setFieldUsingSetValue<STUInt8>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldU16(std::uint16_t v)
|
||||
{
|
||||
inner_type_ = STI_UINT16;
|
||||
data_ = detail::STVar(detail::defaultObject, sfSignerWeight);
|
||||
setFieldUsingSetValue<STUInt16>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldU32(std::uint32_t v)
|
||||
{
|
||||
inner_type_ = STI_UINT32;
|
||||
data_ = detail::STVar(detail::defaultObject, sfNetworkID);
|
||||
setFieldUsingSetValue<STUInt32>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldU64(std::uint64_t v)
|
||||
{
|
||||
inner_type_ = STI_UINT64;
|
||||
data_ = detail::STVar(detail::defaultObject, sfIndexNext);
|
||||
setFieldUsingSetValue<STUInt64>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldH128(uint128 const& v)
|
||||
{
|
||||
inner_type_ = STI_UINT128;
|
||||
data_ = detail::STVar(detail::defaultObject, sfEmailHash);
|
||||
setFieldUsingSetValue<STUInt128>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldH160(uint160 const& v)
|
||||
{
|
||||
inner_type_ = STI_UINT160;
|
||||
data_ = detail::STVar(detail::defaultObject, sfTakerPaysCurrency);
|
||||
setFieldUsingSetValue<STUInt160>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldH192(uint192 const& v)
|
||||
{
|
||||
inner_type_ = STI_UINT192;
|
||||
data_ = detail::STVar(detail::defaultObject, sfMPTokenIssuanceID);
|
||||
setFieldUsingSetValue<STUInt192>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldH256(uint256 const& v)
|
||||
{
|
||||
inner_type_ = STI_UINT256;
|
||||
data_ = detail::STVar(detail::defaultObject, sfLedgerHash);
|
||||
setFieldUsingSetValue<STUInt256>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldVL(Blob const& v)
|
||||
{
|
||||
inner_type_ = STI_VL;
|
||||
data_ = detail::STVar(detail::defaultObject, sfData);
|
||||
setFieldUsingSetValue<STBlob>(Buffer(v.data(), v.size()));
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldVL(Slice const& s)
|
||||
{
|
||||
inner_type_ = STI_VL;
|
||||
data_ = detail::STVar(detail::defaultObject, sfData);
|
||||
setFieldUsingSetValue<STBlob>(Buffer(s.data(), s.size()));
|
||||
}
|
||||
|
||||
void
|
||||
STData::setAccountID(AccountID const& v)
|
||||
{
|
||||
inner_type_ = STI_ACCOUNT;
|
||||
data_ = detail::STVar(detail::defaultObject, sfAccount);
|
||||
setFieldUsingSetValue<STAccount>(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldAmount(STAmount const& v)
|
||||
{
|
||||
inner_type_ = STI_AMOUNT;
|
||||
data_ = detail::STVar(detail::defaultObject, sfAmount);
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setIssue(STIssue const& v)
|
||||
{
|
||||
inner_type_ = STI_ISSUE;
|
||||
data_ = detail::STVar(detail::defaultObject, sfAsset);
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setCurrency(STCurrency const& v)
|
||||
{
|
||||
inner_type_ = STI_CURRENCY;
|
||||
data_ = detail::STVar(detail::defaultObject, sfBaseAsset);
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
void
|
||||
STData::setFieldNumber(STNumber const& v)
|
||||
{
|
||||
inner_type_ = STI_NUMBER;
|
||||
data_ = detail::STVar(detail::defaultObject, sfNumber);
|
||||
setFieldUsingAssignment(v);
|
||||
}
|
||||
|
||||
unsigned char
|
||||
STData::getFieldU8() const
|
||||
{
|
||||
return getFieldByValue<STUInt8>();
|
||||
}
|
||||
|
||||
std::uint16_t
|
||||
STData::getFieldU16() const
|
||||
{
|
||||
return getFieldByValue<STUInt16>();
|
||||
}
|
||||
|
||||
std::uint32_t
|
||||
STData::getFieldU32() const
|
||||
{
|
||||
return getFieldByValue<STUInt32>();
|
||||
}
|
||||
|
||||
std::uint64_t
|
||||
STData::getFieldU64() const
|
||||
{
|
||||
return getFieldByValue<STUInt64>();
|
||||
}
|
||||
|
||||
uint128
|
||||
STData::getFieldH128() const
|
||||
{
|
||||
return getFieldByValue<STUInt128>();
|
||||
}
|
||||
|
||||
uint160
|
||||
STData::getFieldH160() const
|
||||
{
|
||||
return getFieldByValue<STUInt160>();
|
||||
}
|
||||
|
||||
uint192
|
||||
STData::getFieldH192() const
|
||||
{
|
||||
return getFieldByValue<STUInt192>();
|
||||
}
|
||||
|
||||
uint256
|
||||
STData::getFieldH256() const
|
||||
{
|
||||
return getFieldByValue<STUInt256>();
|
||||
}
|
||||
|
||||
Blob
|
||||
STData::getFieldVL() const
|
||||
{
|
||||
STBlob empty;
|
||||
STBlob const& b = getFieldByConstRef<STBlob>(empty);
|
||||
return Blob(b.data(), b.data() + b.size());
|
||||
}
|
||||
|
||||
AccountID
|
||||
STData::getAccountID() const
|
||||
{
|
||||
return getFieldByValue<STAccount>();
|
||||
}
|
||||
|
||||
STAmount const&
|
||||
STData::getFieldAmount() const
|
||||
{
|
||||
static STAmount const empty{};
|
||||
return getFieldByConstRef<STAmount>(empty);
|
||||
}
|
||||
|
||||
STIssue
|
||||
STData::getFieldIssue() const
|
||||
{
|
||||
static STIssue const empty{};
|
||||
return getFieldByConstRef<STIssue>(empty);
|
||||
}
|
||||
|
||||
STCurrency
|
||||
STData::getFieldCurrency() const
|
||||
{
|
||||
static STCurrency const empty{};
|
||||
return getFieldByConstRef<STCurrency>(empty);
|
||||
}
|
||||
|
||||
STNumber
|
||||
STData::getFieldNumber() const
|
||||
{
|
||||
static STNumber const empty{};
|
||||
return getFieldByConstRef<STNumber>(empty);
|
||||
}
|
||||
|
||||
STData
|
||||
dataFromJson(SField const& field, Json::Value const& v)
|
||||
{
|
||||
Json::Value type;
|
||||
Json::Value value;
|
||||
|
||||
if (!v.isObject())
|
||||
Throw<std::runtime_error>("STData: expected object");
|
||||
|
||||
type = v[jss::type];
|
||||
value = v[jss::value];
|
||||
|
||||
if (type.isNull())
|
||||
Throw<std::runtime_error>("STData: type is null");
|
||||
if (value.isNull())
|
||||
Throw<std::runtime_error>("STData: value is null");
|
||||
|
||||
auto typeStr = type.asString();
|
||||
|
||||
if (typeStr == "UINT8")
|
||||
{
|
||||
STData data(field, static_cast<unsigned char>(value.asUInt()));
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT16")
|
||||
{
|
||||
STData data(field, static_cast<std::uint16_t>(value.asUInt()));
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT32")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (value.isString())
|
||||
{
|
||||
STData data(field, beast::lexicalCastThrow<std::uint32_t>(value.asString()));
|
||||
return data;
|
||||
}
|
||||
else if (value.isInt())
|
||||
{
|
||||
STData data(field, to_unsigned<std::uint32_t>(value.asInt()));
|
||||
return data;
|
||||
}
|
||||
else if (value.isUInt())
|
||||
{
|
||||
STData data(field, safe_cast<std::uint32_t>(value.asUInt()));
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
Throw<std::runtime_error>("bad type for UINT32");
|
||||
}
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("invalid data for UINT32");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "UINT64")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (value.isString())
|
||||
{
|
||||
auto const str = value.asString();
|
||||
|
||||
std::uint64_t val;
|
||||
|
||||
bool const useBase10 = field.shouldMeta(SField::sMD_BaseTen);
|
||||
|
||||
// if the field is amount, serialize as base 10
|
||||
auto [p, ec] =
|
||||
std::from_chars(str.data(), str.data() + str.size(), val, useBase10 ? 10 : 16);
|
||||
|
||||
if (ec != std::errc() || (p != str.data() + str.size()))
|
||||
Throw<std::invalid_argument>("STData: invalid UINT64 data");
|
||||
|
||||
STData data(field, val);
|
||||
return data;
|
||||
}
|
||||
else if (value.isInt())
|
||||
{
|
||||
STData data(field, to_unsigned<std::uint64_t>(value.asInt()));
|
||||
return data;
|
||||
}
|
||||
else if (value.isUInt())
|
||||
{
|
||||
STData data(field, safe_cast<std::uint64_t>(value.asUInt()));
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
Throw<std::runtime_error>("STData: bad type for UINT64");
|
||||
}
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid data for UINT64");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "UINT128")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for UINT128");
|
||||
}
|
||||
|
||||
uint128 num;
|
||||
|
||||
if (auto const s = value.asString(); !num.parseHex(s))
|
||||
{
|
||||
if (!s.empty())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid UINT128 data");
|
||||
}
|
||||
|
||||
num.zero();
|
||||
}
|
||||
|
||||
STData data(field, num);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT192")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for UINT192");
|
||||
}
|
||||
|
||||
uint192 num;
|
||||
|
||||
if (auto const s = value.asString(); !num.parseHex(s))
|
||||
{
|
||||
if (!s.empty())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid UINT192 data");
|
||||
}
|
||||
|
||||
num.zero();
|
||||
}
|
||||
|
||||
STData data(field, num);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT160")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for UINT160");
|
||||
}
|
||||
|
||||
uint160 num;
|
||||
|
||||
if (auto const s = value.asString(); !num.parseHex(s))
|
||||
{
|
||||
if (!s.empty())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid UINT160 data");
|
||||
}
|
||||
|
||||
num.zero();
|
||||
}
|
||||
|
||||
STData data(field, num);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT256")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for UINT256");
|
||||
}
|
||||
|
||||
uint256 num;
|
||||
|
||||
if (auto const s = value.asString(); !num.parseHex(s))
|
||||
{
|
||||
if (!s.empty())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid UINT256 data");
|
||||
}
|
||||
|
||||
num.zero();
|
||||
}
|
||||
STData data(field, num);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "VL")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for VL");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (auto vBlob = strUnHex(value.asString()))
|
||||
{
|
||||
STData data(field, *vBlob);
|
||||
return data;
|
||||
}
|
||||
else
|
||||
{
|
||||
Throw<std::invalid_argument>("invalid data");
|
||||
}
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid data");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "AMOUNT")
|
||||
{
|
||||
try
|
||||
{
|
||||
STData data(field, amountFromJson(field, value));
|
||||
return data;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid data for AMOUNT");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "ACCOUNT")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for ACCOUNT");
|
||||
}
|
||||
|
||||
std::string const strValue = value.asString();
|
||||
|
||||
try
|
||||
{
|
||||
if (AccountID account; account.parseHex(strValue))
|
||||
{
|
||||
STData data(field, account);
|
||||
return data;
|
||||
}
|
||||
|
||||
if (auto result = parseBase58<AccountID>(strValue))
|
||||
{
|
||||
STData data(field, *result);
|
||||
return data;
|
||||
}
|
||||
|
||||
Throw<std::runtime_error>("STData: invalid data for ACCOUNT");
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid data for ACCOUNT");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "ISSUE")
|
||||
{
|
||||
try
|
||||
{
|
||||
STData data(field, issueFromJson(field, value));
|
||||
return data;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid data for ISSUE");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "CURRENCY")
|
||||
{
|
||||
try
|
||||
{
|
||||
STData data(field, currencyFromJson(field, value));
|
||||
return data;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
Throw<std::runtime_error>("STData: invalid data for CURRENCY");
|
||||
}
|
||||
}
|
||||
else if (typeStr == "NUMBER")
|
||||
{
|
||||
if (!value.isString())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected string for NUMBER");
|
||||
}
|
||||
|
||||
STNumber number = numberFromJson(field, value);
|
||||
STData data(field, number);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Handle unknown or unsupported type
|
||||
Throw<std::runtime_error>("STData: unsupported type string: " + typeStr);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,253 +0,0 @@
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STDataType.h>
|
||||
#include <xrpl/protocol/detail/STVar.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// TODO
|
||||
STDataType::STDataType(SField const& n) : STBase(n), inner_type_(STI_NOTPRESENT)
|
||||
{
|
||||
}
|
||||
|
||||
STDataType::STDataType(SField const& n, SerializedTypeID v)
|
||||
: STBase(n), inner_type_(v), default_(false)
|
||||
{
|
||||
}
|
||||
|
||||
STDataType::STDataType(SerialIter& sit, SField const& name)
|
||||
: STBase(name), inner_type_(STI_DATA), default_(false)
|
||||
{
|
||||
std::uint16_t stype = SerializedTypeID(sit.get16());
|
||||
inner_type_ = stype;
|
||||
}
|
||||
|
||||
STBase*
|
||||
STDataType::copy(std::size_t n, void* buf) const
|
||||
{
|
||||
return emplace(n, buf, *this);
|
||||
}
|
||||
|
||||
STBase*
|
||||
STDataType::move(std::size_t n, void* buf)
|
||||
{
|
||||
return emplace(n, buf, std::move(*this));
|
||||
}
|
||||
|
||||
SerializedTypeID
|
||||
STDataType::getSType() const
|
||||
{
|
||||
return STI_DATATYPE;
|
||||
}
|
||||
|
||||
void
|
||||
STDataType::setInnerSType(SerializedTypeID v)
|
||||
{
|
||||
inner_type_ = v;
|
||||
}
|
||||
|
||||
void
|
||||
STDataType::add(Serializer& s) const
|
||||
{
|
||||
s.add16(inner_type_);
|
||||
}
|
||||
|
||||
bool
|
||||
STDataType::isEquivalent(STBase const& t) const
|
||||
{
|
||||
auto const* const tPtr = dynamic_cast<STDataType const*>(&t);
|
||||
return tPtr && (default_ == tPtr->default_) && (inner_type_ == tPtr->inner_type_);
|
||||
}
|
||||
|
||||
bool
|
||||
STDataType::isDefault() const
|
||||
{
|
||||
return default_;
|
||||
}
|
||||
|
||||
std::string
|
||||
STDataType::getInnerTypeString() const
|
||||
{
|
||||
std::string inner_type_str = "Unknown";
|
||||
// Optionally, convert inner_type_ to its string representation if mappings
|
||||
// exist
|
||||
switch (static_cast<SerializedTypeID>(inner_type_))
|
||||
{
|
||||
case STI_UINT8:
|
||||
inner_type_str = "UINT8";
|
||||
break;
|
||||
case STI_UINT16:
|
||||
inner_type_str = "UINT16";
|
||||
break;
|
||||
case STI_UINT32:
|
||||
inner_type_str = "UINT32";
|
||||
break;
|
||||
case STI_UINT64:
|
||||
inner_type_str = "UINT64";
|
||||
break;
|
||||
case STI_UINT128:
|
||||
inner_type_str = "UINT128";
|
||||
break;
|
||||
case STI_UINT160:
|
||||
inner_type_str = "UINT160";
|
||||
break;
|
||||
case STI_UINT192:
|
||||
inner_type_str = "UINT192";
|
||||
break;
|
||||
case STI_UINT256:
|
||||
inner_type_str = "UINT256";
|
||||
break;
|
||||
case STI_VL:
|
||||
inner_type_str = "VL";
|
||||
break;
|
||||
case STI_ACCOUNT:
|
||||
inner_type_str = "ACCOUNT";
|
||||
break;
|
||||
case STI_AMOUNT:
|
||||
inner_type_str = "AMOUNT";
|
||||
break;
|
||||
case STI_ISSUE:
|
||||
inner_type_str = "ISSUE";
|
||||
break;
|
||||
case STI_CURRENCY:
|
||||
inner_type_str = "CURRENCY";
|
||||
break;
|
||||
case STI_NUMBER:
|
||||
inner_type_str = "NUMBER";
|
||||
break;
|
||||
// Add other known types as needed
|
||||
default:
|
||||
inner_type_str = std::to_string(inner_type_);
|
||||
}
|
||||
|
||||
return inner_type_str;
|
||||
}
|
||||
|
||||
std::string
|
||||
STDataType::getText() const
|
||||
{
|
||||
std::string inner_type_str = getInnerTypeString();
|
||||
return "STDataType{InnerType: " + inner_type_str + "}";
|
||||
}
|
||||
|
||||
Json::Value
|
||||
STDataType::getJson(JsonOptions) const
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
ret[jss::type] = getInnerTypeString();
|
||||
return ret;
|
||||
}
|
||||
|
||||
STDataType
|
||||
dataTypeFromJson(SField const& field, Json::Value const& v)
|
||||
{
|
||||
SerializedTypeID typeId = STI_NOTPRESENT;
|
||||
Json::Value type;
|
||||
Json::Value value;
|
||||
|
||||
if (!v.isObject())
|
||||
{
|
||||
Throw<std::runtime_error>("STData: expected object");
|
||||
}
|
||||
|
||||
type = v[jss::type];
|
||||
auto typeStr = type.asString();
|
||||
|
||||
if (typeStr == "UINT8")
|
||||
{
|
||||
typeId = STI_UINT8;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT16")
|
||||
{
|
||||
typeId = STI_UINT16;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT32")
|
||||
{
|
||||
typeId = STI_UINT32;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT64")
|
||||
{
|
||||
typeId = STI_UINT64;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT128")
|
||||
{
|
||||
typeId = STI_UINT128;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT160")
|
||||
{
|
||||
typeId = STI_UINT160;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT192")
|
||||
{
|
||||
typeId = STI_UINT192;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "UINT256")
|
||||
{
|
||||
typeId = STI_UINT256;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "VL")
|
||||
{
|
||||
typeId = STI_VL;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "ACCOUNT")
|
||||
{
|
||||
typeId = STI_ACCOUNT;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "AMOUNT")
|
||||
{
|
||||
typeId = STI_AMOUNT;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "ISSUE")
|
||||
{
|
||||
typeId = STI_ISSUE;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "CURRENCY")
|
||||
{
|
||||
typeId = STI_CURRENCY;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
else if (typeStr == "NUMBER")
|
||||
{
|
||||
typeId = STI_NUMBER;
|
||||
STDataType data(field, typeId);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Handle unknown or unsupported type
|
||||
Throw<std::runtime_error>("STData: unsupported type string: " + typeStr);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -1,758 +0,0 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STDataType.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
STJson::STJson(SField const& name) : STBase{name}, data_{Map{}}
|
||||
{
|
||||
}
|
||||
|
||||
STJson::STJson(SerialIter& sit, SField const& name) : STBase{name}
|
||||
{
|
||||
if (sit.empty())
|
||||
{
|
||||
data_ = Map{};
|
||||
return;
|
||||
}
|
||||
|
||||
int length = sit.getVLDataLength();
|
||||
if (length < 0)
|
||||
Throw<std::runtime_error>("Invalid STJson length");
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
data_ = Map{};
|
||||
return;
|
||||
}
|
||||
|
||||
// Read type byte
|
||||
auto typeByte = sit.get8();
|
||||
JsonType type = static_cast<JsonType>(typeByte);
|
||||
length--; // Account for type byte
|
||||
|
||||
int initialBytesLeft = sit.getBytesLeft();
|
||||
|
||||
if (type == JsonType::Array)
|
||||
{
|
||||
Array array;
|
||||
while (sit.getBytesLeft() > 0 && (initialBytesLeft - sit.getBytesLeft()) < length)
|
||||
{
|
||||
auto valueVL = sit.getVL();
|
||||
if (!valueVL.empty())
|
||||
{
|
||||
SerialIter valueSit(valueVL.data(), valueVL.size());
|
||||
auto value = makeValueFromVLWithType(valueSit);
|
||||
array.push_back(std::move(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
array.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
data_ = std::move(array);
|
||||
}
|
||||
else // JsonType::Object
|
||||
{
|
||||
Map map;
|
||||
while (sit.getBytesLeft() > 0 && (initialBytesLeft - sit.getBytesLeft()) < length)
|
||||
{
|
||||
auto [key, value] = parsePair(sit);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
data_ = std::move(map);
|
||||
}
|
||||
|
||||
int consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
if (consumedBytes != length)
|
||||
Throw<std::runtime_error>("STJson length mismatch");
|
||||
}
|
||||
|
||||
STJson::STJson(Map&& map) : data_(std::move(map))
|
||||
{
|
||||
}
|
||||
|
||||
STJson::STJson(Array&& array) : data_(std::move(array))
|
||||
{
|
||||
}
|
||||
|
||||
SerializedTypeID
|
||||
STJson::getSType() const
|
||||
{
|
||||
return STI_JSON;
|
||||
}
|
||||
|
||||
bool
|
||||
STJson::isArray() const
|
||||
{
|
||||
return std::holds_alternative<Array>(data_);
|
||||
}
|
||||
|
||||
bool
|
||||
STJson::isObject() const
|
||||
{
|
||||
return std::holds_alternative<Map>(data_);
|
||||
}
|
||||
|
||||
STJson::JsonType
|
||||
STJson::getType() const
|
||||
{
|
||||
return isArray() ? JsonType::Array : JsonType::Object;
|
||||
}
|
||||
|
||||
int
|
||||
STJson::getDepth() const
|
||||
{
|
||||
if (isArray())
|
||||
{
|
||||
auto const& array = std::get<Array>(data_);
|
||||
for (auto const& value : array)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
auto nested = std::dynamic_pointer_cast<STJson>(value);
|
||||
if (nested)
|
||||
return 1 + nested->getDepth();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else // isObject()
|
||||
{
|
||||
auto const& map = std::get<Map>(data_);
|
||||
for (auto const& [key, value] : map)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
auto nested = std::dynamic_pointer_cast<STJson>(value);
|
||||
if (nested)
|
||||
return 1 + nested->getDepth();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
STJson::validateDepth(Value const& value, int currentDepth) const
|
||||
{
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
auto nested = std::dynamic_pointer_cast<STJson>(value);
|
||||
if (!nested)
|
||||
return;
|
||||
|
||||
int valueDepth = nested->getDepth();
|
||||
if (currentDepth + valueDepth > 1)
|
||||
Throw<std::runtime_error>("STJson nesting depth exceeds maximum of 1");
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setObjectField(Key const& key, Value const& value)
|
||||
{
|
||||
if (!isObject())
|
||||
Throw<std::runtime_error>("STJson::setObjectField called on non-object");
|
||||
validateDepth(value, 0);
|
||||
std::get<Map>(data_)[key] = value;
|
||||
}
|
||||
|
||||
std::shared_ptr<STJson>
|
||||
STJson::fromBlob(void const* data, std::size_t size)
|
||||
{
|
||||
SerialIter sit(static_cast<uint8_t const*>(data), size);
|
||||
return fromSerialIter(sit);
|
||||
}
|
||||
|
||||
std::shared_ptr<STJson>
|
||||
STJson::fromSerialIter(SerialIter& sit)
|
||||
{
|
||||
if (sit.empty())
|
||||
return nullptr;
|
||||
|
||||
int length = sit.getVLDataLength();
|
||||
if (length < 0)
|
||||
Throw<std::runtime_error>("Invalid STJson length");
|
||||
|
||||
if (length == 0)
|
||||
return std::make_shared<STJson>(Map{});
|
||||
|
||||
// Read type byte
|
||||
auto typeByte = sit.get8();
|
||||
JsonType type = static_cast<JsonType>(typeByte);
|
||||
length--; // Account for type byte
|
||||
|
||||
int initialBytesLeft = sit.getBytesLeft();
|
||||
|
||||
if (type == JsonType::Array)
|
||||
{
|
||||
Array array;
|
||||
while (sit.getBytesLeft() > 0 && (initialBytesLeft - sit.getBytesLeft()) < length)
|
||||
{
|
||||
auto valueVL = sit.getVL();
|
||||
if (!valueVL.empty())
|
||||
{
|
||||
SerialIter valueSit(valueVL.data(), valueVL.size());
|
||||
auto value = makeValueFromVLWithType(valueSit);
|
||||
array.push_back(std::move(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
array.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
int consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
if (consumedBytes != length)
|
||||
Throw<std::runtime_error>("STJson length mismatch");
|
||||
|
||||
return std::make_shared<STJson>(std::move(array));
|
||||
}
|
||||
else // JsonType::Object
|
||||
{
|
||||
Map map;
|
||||
while (sit.getBytesLeft() > 0 && (initialBytesLeft - sit.getBytesLeft()) < length)
|
||||
{
|
||||
auto [key, value] = parsePair(sit);
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
|
||||
int consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
if (consumedBytes != length)
|
||||
Throw<std::runtime_error>("STJson length mismatch");
|
||||
|
||||
return std::make_shared<STJson>(std::move(map));
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<STJson::Key, STJson::Value>
|
||||
STJson::parsePair(SerialIter& sit)
|
||||
{
|
||||
auto keyBlob = sit.getVL();
|
||||
std::string key(reinterpret_cast<char const*>(keyBlob.data()), keyBlob.size());
|
||||
auto valueVL = sit.getVL();
|
||||
if (valueVL.empty())
|
||||
return {std::move(key), nullptr};
|
||||
|
||||
SerialIter valueSit(valueVL.data(), valueVL.size());
|
||||
auto value = makeValueFromVLWithType(valueSit);
|
||||
|
||||
return {std::move(key), std::move(value)};
|
||||
}
|
||||
|
||||
STJson::Array
|
||||
STJson::parseArray(SerialIter& sit, int length)
|
||||
{
|
||||
Array array;
|
||||
int initialBytesLeft = sit.getBytesLeft();
|
||||
|
||||
while (sit.getBytesLeft() > 0 && (initialBytesLeft - sit.getBytesLeft()) < length)
|
||||
{
|
||||
auto valueVL = sit.getVL();
|
||||
if (!valueVL.empty())
|
||||
{
|
||||
SerialIter valueSit(valueVL.data(), valueVL.size());
|
||||
auto value = makeValueFromVLWithType(valueSit);
|
||||
array.push_back(std::move(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
array.push_back(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
STJson::Value
|
||||
STJson::makeValueFromVLWithType(SerialIter& sit)
|
||||
{
|
||||
if (sit.getBytesLeft() == 0)
|
||||
return nullptr;
|
||||
|
||||
// Read SType marker (1 byte)
|
||||
auto typeCode = sit.get8();
|
||||
SerializedTypeID stype = static_cast<SerializedTypeID>(typeCode);
|
||||
|
||||
// Dispatch to correct SType
|
||||
switch (stype)
|
||||
{
|
||||
case STI_UINT8:
|
||||
return std::make_shared<STUInt8>(sfCloseResolution, sit.get8());
|
||||
case STI_UINT16:
|
||||
return std::make_shared<STUInt16>(sfSignerWeight, sit.get16());
|
||||
case STI_UINT32:
|
||||
return std::make_shared<STUInt32>(sfNetworkID, sit.get32());
|
||||
case STI_UINT64:
|
||||
return std::make_shared<STUInt64>(sfIndexNext, sit.get64());
|
||||
case STI_UINT128:
|
||||
return std::make_shared<STUInt128>(sfEmailHash, sit.get128());
|
||||
case STI_UINT160:
|
||||
return std::make_shared<STUInt160>(sfTakerPaysCurrency, sit.get160());
|
||||
case STI_UINT192:
|
||||
return std::make_shared<STUInt192>(sfMPTokenIssuanceID, sit.get192());
|
||||
case STI_UINT256:
|
||||
return std::make_shared<STUInt256>(sfLedgerHash, sit.get256());
|
||||
case STI_VL: {
|
||||
auto blob = sit.getVL();
|
||||
return std::make_shared<STBlob>(sfData, blob.data(), blob.size());
|
||||
}
|
||||
case STI_ACCOUNT:
|
||||
return std::make_shared<STAccount>(sit, sfAccount);
|
||||
case STI_AMOUNT:
|
||||
return std::make_shared<STAmount>(sit, sfAmount);
|
||||
// case STI_NUMBER:
|
||||
// return std::make_shared<STNumber>(sit, sfNumber);
|
||||
case STI_ISSUE:
|
||||
return std::make_shared<STIssue>(sit, sfAsset);
|
||||
case STI_CURRENCY:
|
||||
return std::make_shared<STCurrency>(sit, sfBaseAsset);
|
||||
case STI_JSON:
|
||||
return std::make_shared<STJson>(sit, sfContractJson);
|
||||
case STI_OBJECT:
|
||||
case STI_ARRAY:
|
||||
case STI_PATHSET:
|
||||
case STI_VECTOR256:
|
||||
default:
|
||||
// Unknown type, treat as blob
|
||||
{
|
||||
auto blob = sit.getSlice(sit.getBytesLeft());
|
||||
return std::make_shared<STBlob>(sfData, blob.data(), blob.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<STJson::Value>
|
||||
STJson::getObjectField(Key const& key) const
|
||||
{
|
||||
if (!isObject())
|
||||
return std::nullopt;
|
||||
|
||||
auto const& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
if (it == map.end() || !it->second)
|
||||
return std::nullopt;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setNestedObjectField(Key const& key, Key const& nestedKey, Value const& value)
|
||||
{
|
||||
if (!isObject())
|
||||
Throw<std::runtime_error>("STJson::setNestedObjectField called on non-object");
|
||||
|
||||
validateDepth(value, 1); // We're at depth 1 (nested)
|
||||
|
||||
auto& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
std::shared_ptr<STJson> nested;
|
||||
if (it == map.end() || !it->second)
|
||||
{
|
||||
// Create new nested STJson
|
||||
nested = std::make_shared<STJson>();
|
||||
map[key] = nested;
|
||||
}
|
||||
else
|
||||
{
|
||||
nested = std::dynamic_pointer_cast<STJson>(it->second);
|
||||
if (!nested)
|
||||
{
|
||||
// Overwrite with new STJson if not an STJson
|
||||
nested = std::make_shared<STJson>();
|
||||
map[key] = nested;
|
||||
}
|
||||
}
|
||||
nested->setObjectField(nestedKey, value);
|
||||
}
|
||||
|
||||
std::optional<STJson::Value>
|
||||
STJson::getNestedObjectField(Key const& key, Key const& nestedKey) const
|
||||
{
|
||||
if (!isObject())
|
||||
return std::nullopt;
|
||||
|
||||
auto const& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
if (it == map.end() || !it->second)
|
||||
return std::nullopt;
|
||||
auto nested = std::dynamic_pointer_cast<STJson>(it->second);
|
||||
if (!nested)
|
||||
return std::nullopt;
|
||||
return nested->getObjectField(nestedKey);
|
||||
}
|
||||
|
||||
STJson::Map const&
|
||||
STJson::getMap() const
|
||||
{
|
||||
if (!isObject())
|
||||
Throw<std::runtime_error>("STJson::getMap called on non-object");
|
||||
return std::get<Map>(data_);
|
||||
}
|
||||
|
||||
STJson::Array const&
|
||||
STJson::getArray() const
|
||||
{
|
||||
if (!isArray())
|
||||
Throw<std::runtime_error>("STJson::getArray called on non-array");
|
||||
return std::get<Array>(data_);
|
||||
}
|
||||
|
||||
void
|
||||
STJson::pushArrayElement(Value const& value)
|
||||
{
|
||||
if (!isArray())
|
||||
Throw<std::runtime_error>("STJson::pushArrayElement called on non-array");
|
||||
validateDepth(value, 0);
|
||||
std::get<Array>(data_).push_back(value);
|
||||
}
|
||||
|
||||
std::optional<STJson::Value>
|
||||
STJson::getArrayElement(size_t index) const
|
||||
{
|
||||
if (!isArray())
|
||||
return std::nullopt;
|
||||
|
||||
auto const& array = std::get<Array>(data_);
|
||||
if (index >= array.size())
|
||||
return std::nullopt;
|
||||
|
||||
return array[index];
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setArrayElement(size_t index, Value const& value)
|
||||
{
|
||||
if (!isArray())
|
||||
Throw<std::runtime_error>("STJson::setArrayElement called on non-array");
|
||||
validateDepth(value, 0);
|
||||
|
||||
auto& array = std::get<Array>(data_);
|
||||
// Auto-resize with nulls if needed
|
||||
if (index >= array.size())
|
||||
array.resize(index + 1, nullptr);
|
||||
|
||||
array[index] = value;
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setArrayElementField(size_t index, Key const& key, Value const& value)
|
||||
{
|
||||
if (!isArray())
|
||||
Throw<std::runtime_error>("STJson::setArrayElementField called on non-array");
|
||||
|
||||
validateDepth(value, 1); // We're at depth 1 (inside array element)
|
||||
|
||||
auto& array = std::get<Array>(data_);
|
||||
// Auto-resize with nulls if needed
|
||||
if (index >= array.size())
|
||||
array.resize(index + 1, nullptr);
|
||||
|
||||
// Get or create STJson object at index
|
||||
std::shared_ptr<STJson> element;
|
||||
if (!array[index])
|
||||
{
|
||||
element = std::make_shared<STJson>(Map{});
|
||||
array[index] = element;
|
||||
}
|
||||
else
|
||||
{
|
||||
element = std::dynamic_pointer_cast<STJson>(array[index]);
|
||||
if (!element)
|
||||
{
|
||||
// Replace with new STJson if not an STJson
|
||||
element = std::make_shared<STJson>(Map{});
|
||||
array[index] = element;
|
||||
}
|
||||
}
|
||||
|
||||
element->setObjectField(key, value);
|
||||
}
|
||||
|
||||
std::optional<STJson::Value>
|
||||
STJson::getArrayElementField(size_t index, Key const& key) const
|
||||
{
|
||||
if (!isArray())
|
||||
return std::nullopt;
|
||||
|
||||
auto const& array = std::get<Array>(data_);
|
||||
if (index >= array.size())
|
||||
return std::nullopt;
|
||||
|
||||
auto element = std::dynamic_pointer_cast<STJson>(array[index]);
|
||||
if (!element)
|
||||
return std::nullopt;
|
||||
|
||||
return element->getObjectField(key);
|
||||
}
|
||||
|
||||
size_t
|
||||
STJson::arraySize() const
|
||||
{
|
||||
if (!isArray())
|
||||
return 0;
|
||||
return std::get<Array>(data_).size();
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setNestedArrayElement(Key const& key, size_t index, Value const& value)
|
||||
{
|
||||
if (!isObject())
|
||||
Throw<std::runtime_error>("STJson::setNestedArrayElement called on non-object");
|
||||
|
||||
validateDepth(value, 1); // We're at depth 1 (nested array)
|
||||
|
||||
auto& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
std::shared_ptr<STJson> arrayJson;
|
||||
|
||||
if (it == map.end() || !it->second)
|
||||
{
|
||||
// Create new nested STJson array
|
||||
arrayJson = std::make_shared<STJson>(Array{});
|
||||
map[key] = arrayJson;
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayJson = std::dynamic_pointer_cast<STJson>(it->second);
|
||||
if (!arrayJson)
|
||||
{
|
||||
// Replace with new STJson array if not an STJson
|
||||
arrayJson = std::make_shared<STJson>(Array{});
|
||||
map[key] = arrayJson;
|
||||
}
|
||||
else if (!arrayJson->isArray())
|
||||
{
|
||||
// Replace with array if not an array
|
||||
arrayJson = std::make_shared<STJson>(Array{});
|
||||
map[key] = arrayJson;
|
||||
}
|
||||
}
|
||||
|
||||
arrayJson->setArrayElement(index, value);
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setNestedArrayElementField(
|
||||
Key const& key,
|
||||
size_t index,
|
||||
Key const& nestedKey,
|
||||
Value const& value)
|
||||
{
|
||||
if (!isObject())
|
||||
Throw<std::runtime_error>("STJson::setNestedArrayElementField called on non-object");
|
||||
|
||||
validateDepth(value, 1); // We're at depth 1 (nested array element field -
|
||||
// still counts as depth 1)
|
||||
|
||||
auto& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
std::shared_ptr<STJson> arrayJson;
|
||||
|
||||
if (it == map.end() || !it->second)
|
||||
{
|
||||
// Create new nested STJson array
|
||||
arrayJson = std::make_shared<STJson>(Array{});
|
||||
map[key] = arrayJson;
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayJson = std::dynamic_pointer_cast<STJson>(it->second);
|
||||
if (!arrayJson)
|
||||
{
|
||||
// Replace with new STJson array if not an STJson
|
||||
arrayJson = std::make_shared<STJson>(Array{});
|
||||
map[key] = arrayJson;
|
||||
}
|
||||
else if (!arrayJson->isArray())
|
||||
{
|
||||
// Replace with array if not an array
|
||||
arrayJson = std::make_shared<STJson>(Array{});
|
||||
map[key] = arrayJson;
|
||||
}
|
||||
}
|
||||
|
||||
arrayJson->setArrayElementField(index, nestedKey, value);
|
||||
}
|
||||
|
||||
std::optional<STJson::Value>
|
||||
STJson::getNestedArrayElement(Key const& key, size_t index) const
|
||||
{
|
||||
if (!isObject())
|
||||
return std::nullopt;
|
||||
|
||||
auto const& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
if (it == map.end() || !it->second)
|
||||
return std::nullopt;
|
||||
|
||||
auto arrayJson = std::dynamic_pointer_cast<STJson>(it->second);
|
||||
if (!arrayJson || !arrayJson->isArray())
|
||||
return std::nullopt;
|
||||
|
||||
return arrayJson->getArrayElement(index);
|
||||
}
|
||||
|
||||
std::optional<STJson::Value>
|
||||
STJson::getNestedArrayElementField(Key const& key, size_t index, Key const& nestedKey) const
|
||||
{
|
||||
if (!isObject())
|
||||
return std::nullopt;
|
||||
|
||||
auto const& map = std::get<Map>(data_);
|
||||
auto it = map.find(key);
|
||||
if (it == map.end() || !it->second)
|
||||
return std::nullopt;
|
||||
|
||||
auto arrayJson = std::dynamic_pointer_cast<STJson>(it->second);
|
||||
if (!arrayJson || !arrayJson->isArray())
|
||||
return std::nullopt;
|
||||
|
||||
return arrayJson->getArrayElementField(index, nestedKey);
|
||||
}
|
||||
|
||||
void
|
||||
STJson::addVLKey(Serializer& s, std::string const& str)
|
||||
{
|
||||
s.addVL(str.data(), str.size());
|
||||
}
|
||||
|
||||
void
|
||||
STJson::addVLValue(Serializer& s, std::shared_ptr<STBase> const& value)
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
s.addVL(nullptr, 0);
|
||||
return;
|
||||
}
|
||||
Serializer tmp;
|
||||
tmp.add8(static_cast<uint8_t>(value->getSType()));
|
||||
value->add(tmp);
|
||||
s.addVL(tmp.peekData().data(), tmp.peekData().size());
|
||||
}
|
||||
|
||||
void
|
||||
STJson::add(Serializer& s) const
|
||||
{
|
||||
Serializer inner;
|
||||
|
||||
// Add type byte
|
||||
inner.add8(static_cast<uint8_t>(getType()));
|
||||
|
||||
if (isArray())
|
||||
{
|
||||
auto const& array = std::get<Array>(data_);
|
||||
for (auto const& value : array)
|
||||
{
|
||||
addVLValue(inner, value);
|
||||
}
|
||||
}
|
||||
else // isObject()
|
||||
{
|
||||
auto const& map = std::get<Map>(data_);
|
||||
for (auto const& [key, value] : map)
|
||||
{
|
||||
addVLKey(inner, key);
|
||||
addVLValue(inner, value);
|
||||
}
|
||||
}
|
||||
|
||||
s.addVL(inner.peekData().data(), inner.peekData().size());
|
||||
}
|
||||
|
||||
Json::Value
|
||||
STJson::getJson(JsonOptions options) const
|
||||
{
|
||||
if (isArray())
|
||||
{
|
||||
Json::Value arr(Json::arrayValue);
|
||||
auto const& array = std::get<Array>(data_);
|
||||
for (auto const& value : array)
|
||||
{
|
||||
if (value)
|
||||
arr.append(value->getJson(options));
|
||||
else
|
||||
arr.append(Json::nullValue);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
else // isObject()
|
||||
{
|
||||
Json::Value obj(Json::objectValue);
|
||||
auto const& map = std::get<Map>(data_);
|
||||
for (auto const& [key, value] : map)
|
||||
{
|
||||
if (value)
|
||||
obj[key] = value->getJson(options);
|
||||
else
|
||||
obj[key] = Json::nullValue;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
STJson::isEquivalent(STBase const& t) const
|
||||
{
|
||||
auto const* const tPtr = dynamic_cast<STJson const*>(&t);
|
||||
return tPtr && (data_ == tPtr->data_);
|
||||
}
|
||||
|
||||
bool
|
||||
STJson::isDefault() const
|
||||
{
|
||||
return default_;
|
||||
}
|
||||
|
||||
Blob
|
||||
STJson::toBlob() const
|
||||
{
|
||||
Serializer s;
|
||||
add(s);
|
||||
return s.peekData();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
STJson::size() const
|
||||
{
|
||||
Serializer s;
|
||||
add(s);
|
||||
return s.size();
|
||||
}
|
||||
|
||||
void
|
||||
STJson::setValue(STJson const& v)
|
||||
{
|
||||
data_ = v.data_;
|
||||
}
|
||||
|
||||
STBase*
|
||||
STJson::copy(std::size_t n, void* buf) const
|
||||
{
|
||||
return emplace(n, buf, *this);
|
||||
}
|
||||
|
||||
STBase*
|
||||
STJson::move(std::size_t n, void* buf)
|
||||
{
|
||||
return emplace(n, buf, std::move(*this));
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -19,11 +19,8 @@
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STDataType.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
@@ -640,20 +637,6 @@ STObject::getAccountID(SField const& field) const
|
||||
return getFieldByValue<STAccount>(field);
|
||||
}
|
||||
|
||||
STData
|
||||
STObject::getFieldData(SField const& field) const
|
||||
{
|
||||
static STData const empty{field};
|
||||
return getFieldByConstRef<STData>(field, empty);
|
||||
}
|
||||
|
||||
STDataType
|
||||
STObject::getFieldDataType(SField const& field) const
|
||||
{
|
||||
static STDataType const empty{field};
|
||||
return getFieldByConstRef<STDataType>(field, empty);
|
||||
}
|
||||
|
||||
Blob
|
||||
STObject::getFieldVL(SField const& field) const
|
||||
{
|
||||
@@ -714,13 +697,6 @@ STObject::getFieldNumber(SField const& field) const
|
||||
return getFieldByConstRef<STNumber>(field, empty);
|
||||
}
|
||||
|
||||
STJson const&
|
||||
STObject::getFieldJson(SField const& field) const
|
||||
{
|
||||
static STJson const empty{field};
|
||||
return getFieldByConstRef<STJson>(field, empty);
|
||||
}
|
||||
|
||||
void
|
||||
STObject::set(std::unique_ptr<STBase> v)
|
||||
{
|
||||
@@ -743,69 +719,6 @@ STObject::set(STBase&& v)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
STObject::addFieldFromSlice(SField const& sfield, Slice const& data)
|
||||
{
|
||||
SerialIter sit(data.data(), data.size());
|
||||
std::unique_ptr<STBase> element;
|
||||
|
||||
switch (sfield.fieldType)
|
||||
{
|
||||
case STI_AMOUNT:
|
||||
element = std::make_unique<STAmount>(sit, sfield);
|
||||
break;
|
||||
case STI_ACCOUNT:
|
||||
element = std::make_unique<STAccount>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT8:
|
||||
element = std::make_unique<STUInt8>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT16:
|
||||
element = std::make_unique<STUInt16>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT32:
|
||||
element = std::make_unique<STUInt32>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT64:
|
||||
element = std::make_unique<STUInt64>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT128:
|
||||
element = std::make_unique<STUInt128>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT160:
|
||||
element = std::make_unique<STUInt160>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT256:
|
||||
element = std::make_unique<STUInt256>(sit, sfield);
|
||||
break;
|
||||
case STI_VECTOR256:
|
||||
element = std::make_unique<STVector256>(sit, sfield);
|
||||
break;
|
||||
case STI_VL:
|
||||
element = std::make_unique<STBlob>(sit, sfield);
|
||||
break;
|
||||
case STI_CURRENCY:
|
||||
element = std::make_unique<STCurrency>(sit, sfield);
|
||||
break;
|
||||
case STI_ISSUE:
|
||||
element = std::make_unique<STIssue>(sit, sfield);
|
||||
break;
|
||||
case STI_PATHSET:
|
||||
element = std::make_unique<STPathSet>(sit, sfield);
|
||||
break;
|
||||
case STI_ARRAY:
|
||||
element = std::make_unique<STArray>(sit, sfield);
|
||||
break;
|
||||
case STI_OBJECT:
|
||||
element = std::make_unique<STObject>(sit, sfield, 0);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unsupported SField type");
|
||||
}
|
||||
|
||||
this->set(std::move(element));
|
||||
}
|
||||
|
||||
void
|
||||
STObject::setFieldU8(SField const& field, unsigned char v)
|
||||
{
|
||||
@@ -914,12 +827,6 @@ STObject::setFieldObject(SField const& field, STObject const& v)
|
||||
setFieldUsingAssignment(field, v);
|
||||
}
|
||||
|
||||
void
|
||||
STObject::setFieldJson(SField const& field, STJson const& v)
|
||||
{
|
||||
setFieldUsingAssignment(field, v);
|
||||
}
|
||||
|
||||
Json::Value
|
||||
STObject::getJson(JsonOptions options) const
|
||||
{
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STDataType.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
@@ -905,52 +903,6 @@ parseLeaf(
|
||||
}
|
||||
break;
|
||||
|
||||
case STI_DATA: {
|
||||
try
|
||||
{
|
||||
ret = detail::make_stvar<STData>(dataFromJson(field, value));
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
std::cout << "STI_DATA failed for field: " << fieldName
|
||||
<< " in object: " << json_name << "\n";
|
||||
error = invalid_data(json_name, fieldName);
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case STI_DATATYPE: {
|
||||
try
|
||||
{
|
||||
ret = detail::make_stvar<STDataType>(dataTypeFromJson(field, value));
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
std::cout << "STI_DATATYPE failed for field: " << fieldName
|
||||
<< " in object: " << json_name << "\n";
|
||||
error = invalid_data(json_name, fieldName);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STI_JSON:
|
||||
Throw<std::runtime_error>("STI_JSON is not supported");
|
||||
// try
|
||||
// {
|
||||
// ret = detail::make_stvar<STDataType>(
|
||||
// dataTypeFromJson(field, value));
|
||||
// }
|
||||
// catch (std::exception const&)
|
||||
// {
|
||||
// std::cout << "STI_DATATYPE failed for field: " << fieldName
|
||||
// << " in object: " << json_name << "\n";
|
||||
// error = invalid_data(json_name, fieldName);
|
||||
// return ret;
|
||||
// }
|
||||
break;
|
||||
|
||||
default:
|
||||
error = bad_type(json_name, fieldName);
|
||||
return ret;
|
||||
|
||||
@@ -58,10 +58,6 @@ STValidation::validationFormat()
|
||||
{sfBaseFeeDrops, soeOPTIONAL},
|
||||
{sfReserveBaseDrops, soeOPTIONAL},
|
||||
{sfReserveIncrementDrops, soeOPTIONAL},
|
||||
// featureSmartEscrow
|
||||
{sfExtensionComputeLimit, soeOPTIONAL},
|
||||
{sfExtensionSizeLimit, soeOPTIONAL},
|
||||
{sfGasPrice, soeOPTIONAL},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
#include <xrpl/protocol/STBitString.h>
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STCurrency.h>
|
||||
#include <xrpl/protocol/STData.h>
|
||||
#include <xrpl/protocol/STDataType.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/STJson.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
@@ -225,15 +222,6 @@ STVar::constructST(SerializedTypeID id, int depth, Args&&... args)
|
||||
case STI_CURRENCY:
|
||||
construct<STCurrency>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_DATA:
|
||||
construct<STData>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_DATATYPE:
|
||||
construct<STDataType>(std::forward<Args>(args)...);
|
||||
return;
|
||||
case STI_JSON:
|
||||
construct<STJson>(std::forward<Args>(args)...);
|
||||
return;
|
||||
default:
|
||||
Throw<std::runtime_error>("Unknown object type");
|
||||
}
|
||||
|
||||
@@ -106,8 +106,6 @@ transResults()
|
||||
MAKE_ERROR(tecLIMIT_EXCEEDED, "Limit exceeded."),
|
||||
MAKE_ERROR(tecPSEUDO_ACCOUNT, "This operation is not allowed against a pseudo-account."),
|
||||
MAKE_ERROR(tecPRECISION_LOSS, "The amounts used by the transaction cannot interact."),
|
||||
MAKE_ERROR(tecWASM_REJECTED, "The custom WASM code that was run rejected your transaction."),
|
||||
MAKE_ERROR(tecINVALID_PARAMETERS, "Contract parameters do not match the expected ABI."),
|
||||
|
||||
MAKE_ERROR(tefALREADY, "The exact transaction was already in this ledger."),
|
||||
MAKE_ERROR(tefBAD_ADD_AUTH, "Not authorized to add account."),
|
||||
@@ -131,8 +129,6 @@ transResults()
|
||||
MAKE_ERROR(tefNO_TICKET, "Ticket is not in ledger."),
|
||||
MAKE_ERROR(tefNFTOKEN_IS_NOT_TRANSFERABLE, "The specified NFToken is not transferable."),
|
||||
MAKE_ERROR(tefINVALID_LEDGER_FIX_TYPE, "The LedgerFixType field has an invalid value."),
|
||||
MAKE_ERROR(tefNO_WASM, "There is no WASM code to run, but a WASM-specific field was included."),
|
||||
MAKE_ERROR(tefWASM_FIELD_NOT_INCLUDED, "WASM code requires a field to be included that was not included."),
|
||||
|
||||
MAKE_ERROR(telLOCAL_ERROR, "Local failure."),
|
||||
MAKE_ERROR(telBAD_DOMAIN, "Domain too long."),
|
||||
@@ -202,8 +198,6 @@ transResults()
|
||||
MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."),
|
||||
MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."),
|
||||
MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."),
|
||||
MAKE_ERROR(temBAD_WASM, "Malformed: Provided WASM code is invalid."),
|
||||
MAKE_ERROR(temTEMP_DISABLED, "The transaction requires logic that is currently temporarily disabled."),
|
||||
|
||||
MAKE_ERROR(terRETRY, "Retry transaction."),
|
||||
MAKE_ERROR(terFUNDS_SPENT, "DEPRECATED."),
|
||||
|
||||
@@ -40,7 +40,7 @@ TxFormats::TxFormats()
|
||||
#undef TRANSACTION
|
||||
|
||||
#define UNWRAP(...) __VA_ARGS__
|
||||
#define TRANSACTION(tag, value, name, delegatable, amendment, privileges, emitable, fields) \
|
||||
#define TRANSACTION(tag, value, name, delegable, amendment, privileges, fields) \
|
||||
add(jss::name, tag, UNWRAP fields, getCommonFields());
|
||||
|
||||
#include <xrpl/protocol/detail/transactions.macro>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user