mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-28 17:40:25 +00:00
Fix STJson and multiple emitted transactions (#6724)
This commit is contained in:
@@ -10,6 +10,7 @@ libxrpl.ledger > xrpl.basics
|
||||
libxrpl.ledger > xrpl.json
|
||||
libxrpl.ledger > xrpl.ledger
|
||||
libxrpl.ledger > xrpl.protocol
|
||||
libxrpl.ledger > xrpl.server
|
||||
libxrpl.net > xrpl.basics
|
||||
libxrpl.net > xrpl.net
|
||||
libxrpl.nodestore > xrpl.basics
|
||||
@@ -188,6 +189,7 @@ xrpl.core > xrpl.json
|
||||
xrpl.core > xrpl.protocol
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
xrpl.ledger > xrpl.core
|
||||
xrpl.ledger > xrpl.protocol
|
||||
xrpl.ledger > xrpl.server
|
||||
xrpl.ledger > xrpl.shamap
|
||||
|
||||
@@ -48,7 +48,7 @@ int64_t constexpr feeCalculationFailed = 0x7FFFFFFFFFFFFFFFLL;
|
||||
std::size_t constexpr maxContractParams = 8;
|
||||
|
||||
/** The maximum number of contract functions that can be in a transaction. */
|
||||
std::size_t constexpr maxContractFunctions = 8;
|
||||
std::size_t constexpr maxContractFunctions = 32;
|
||||
|
||||
int64_t
|
||||
contractCreateFee(uint64_t byteCount);
|
||||
|
||||
@@ -193,7 +193,7 @@ STData::getFieldByValue() const
|
||||
// if (!rf)
|
||||
// throwFieldNotFound(getFName());
|
||||
|
||||
SerializedTypeID id = rf->getSType();
|
||||
SerializedTypeID const id = rf->getSType();
|
||||
|
||||
if (id == STI_NOTPRESENT)
|
||||
Throw<std::runtime_error>("Field not present");
|
||||
@@ -220,7 +220,7 @@ STData::getFieldByConstRef(V const& empty) const
|
||||
// if (!rf)
|
||||
// throwFieldNotFound(field);
|
||||
|
||||
SerializedTypeID id = rf->getSType();
|
||||
SerializedTypeID const id = rf->getSType();
|
||||
|
||||
if (id == STI_NOTPRESENT)
|
||||
return empty; // optional field not present
|
||||
|
||||
@@ -246,7 +246,7 @@ flow(
|
||||
EitherAmount stepIn(*strand[0]->cachedIn());
|
||||
for (auto i = 0; i < s; ++i)
|
||||
{
|
||||
bool valid;
|
||||
bool valid = false;
|
||||
std::tie(valid, stepIn) = strand[i]->validFwd(checkSB, checkAfView, stepIn);
|
||||
if (!valid)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/ledger/Sandbox.h>
|
||||
#include <xrpl/ledger/OpenView.h>
|
||||
#include <xrpl/ledger/helpers/ContractUtils.h>
|
||||
#include <xrpl/protocol/st.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
@@ -67,6 +67,25 @@ struct ContractContext
|
||||
uint32_t generation = 0; // generation of the contract being executed
|
||||
uint64_t burden = 0; // computational burden used
|
||||
ContractResult result;
|
||||
|
||||
/// Persistent view used to track cumulative state from emitted
|
||||
/// transactions so that successive emits within the same WASM
|
||||
/// execution see the correct sequence numbers, balances, etc.
|
||||
std::optional<OpenView> emitView;
|
||||
|
||||
/// Return the emit view, lazily creating it on first use.
|
||||
/// The view is layered on top of the transactor's ApplyViewImpl
|
||||
/// (applyCtx.view()) so that reads automatically fall through to
|
||||
/// the transactor's pending state (e.g. the tfSendAmount balance
|
||||
/// transfer, consumed sequence number, paid fee) without needing
|
||||
/// to manually copy SLE changes.
|
||||
OpenView&
|
||||
getEmitView()
|
||||
{
|
||||
if (!emitView)
|
||||
emitView.emplace(static_cast<ReadView const*>(&applyCtx.view()));
|
||||
return *emitView;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -457,7 +457,7 @@ canTransferIOU(
|
||||
SendTransferHandling transferHandling,
|
||||
SendBalanceHandling balanceHandling)
|
||||
{
|
||||
AccountID issuer = amount.getIssuer();
|
||||
AccountID const issuer = amount.getIssuer();
|
||||
// If the issuer is the same as the sender
|
||||
if (issuerHandling == SendIssuerHandling::ihSENDER_NOT_ALLOWED && issuer == sender)
|
||||
return tecNO_PERMISSION;
|
||||
@@ -574,7 +574,7 @@ canTransferMPT(
|
||||
SendTransferHandling transferHandling,
|
||||
SendBalanceHandling balanceHandling)
|
||||
{
|
||||
AccountID issuer = amount.getIssuer();
|
||||
AccountID const issuer = amount.getIssuer();
|
||||
// If the issuer is the same as the sender
|
||||
if (issuerHandling == SendIssuerHandling::ihSENDER_NOT_ALLOWED && issuer == sender)
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
@@ -1,22 +1,3 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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>
|
||||
@@ -46,7 +27,7 @@ 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;
|
||||
uint64_t const uf = byteCount * mul;
|
||||
if (uf > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
|
||||
return feeCalculationFailed;
|
||||
return static_cast<int64_t>(uf);
|
||||
@@ -299,7 +280,7 @@ preflightFlagParameters(STArray const& parameters, beast::Journal j)
|
||||
if (!param.isFieldPresent(sfParameterValue))
|
||||
return temMALFORMED;
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
STAmount amount = value.getFieldAmount();
|
||||
STAmount const amount = value.getFieldAmount();
|
||||
// Preflight Transfer Amount
|
||||
if (isXRP(amount))
|
||||
{
|
||||
@@ -355,7 +336,7 @@ preclaimFlagParameters(
|
||||
return tecINTERNAL;
|
||||
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
STAmount amount = value.getFieldAmount();
|
||||
STAmount const amount = value.getFieldAmount();
|
||||
// Preclaim Transfer Amount
|
||||
if (isXRP(amount))
|
||||
{
|
||||
@@ -435,7 +416,7 @@ doApplyFlagParameters(
|
||||
return tecINTERNAL;
|
||||
|
||||
auto const& value = param.getFieldData(sfParameterValue);
|
||||
STAmount amount = value.getFieldAmount();
|
||||
STAmount const amount = value.getFieldAmount();
|
||||
if (auto ter = accountSend(
|
||||
view, sourceAccount, contractAccount, amount, j, WaiveTransferFee::No);
|
||||
!isTesSuccess(ter))
|
||||
@@ -529,7 +510,8 @@ setContractData(
|
||||
if (!dataSle)
|
||||
return tesSUCCESS;
|
||||
|
||||
uint32_t oldDataReserve = contractDataReserve(dataSle->getFieldJson(sfContractJson).size());
|
||||
uint32_t const oldDataReserve =
|
||||
contractDataReserve(dataSle->getFieldJson(sfContractJson).size());
|
||||
|
||||
std::uint64_t const page = (*dataSle)[sfOwnerNode];
|
||||
// Remove the page from the account directory
|
||||
@@ -544,13 +526,13 @@ setContractData(
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
std::uint32_t ownerCount{(*sleAccount)[sfOwnerCount]};
|
||||
bool createNew = !dataSle;
|
||||
std::uint32_t const ownerCount{(*sleAccount)[sfOwnerCount]};
|
||||
bool const createNew = !dataSle;
|
||||
if (createNew)
|
||||
{
|
||||
// CREATE
|
||||
uint32_t dataReserve = contractDataReserve(data.size());
|
||||
uint32_t newReserve = ownerCount + dataReserve;
|
||||
uint32_t const dataReserve = contractDataReserve(data.size());
|
||||
uint32_t const newReserve = ownerCount + dataReserve;
|
||||
XRPAmount const newReserveAmount{view.fees().accountReserve(newReserve)};
|
||||
if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserveAmount)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
@@ -575,12 +557,13 @@ setContractData(
|
||||
else
|
||||
{
|
||||
// UPDATE
|
||||
uint32_t oldDataReserve = contractDataReserve(dataSle->getFieldJson(sfContractJson).size());
|
||||
uint32_t newDataReserve = contractDataReserve(data.size());
|
||||
uint32_t const oldDataReserve =
|
||||
contractDataReserve(dataSle->getFieldJson(sfContractJson).size());
|
||||
uint32_t const newDataReserve = contractDataReserve(data.size());
|
||||
if (newDataReserve != oldDataReserve)
|
||||
{
|
||||
// if the reserve changes, we need to adjust the owner count
|
||||
uint32_t newReserve = ownerCount - oldDataReserve + newDataReserve;
|
||||
uint32_t const newReserve = ownerCount - oldDataReserve + newDataReserve;
|
||||
XRPAmount const newReserveAmount{view.fees().accountReserve(newReserve)};
|
||||
if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserveAmount)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
@@ -614,7 +597,7 @@ finalizeContractData(
|
||||
{
|
||||
auto const& acc = accEntry.first;
|
||||
auto const& cacheEntry = accEntry.second;
|
||||
bool is_modified = cacheEntry.first;
|
||||
bool const is_modified = cacheEntry.first;
|
||||
auto const& jsonData = cacheEntry.second;
|
||||
if (is_modified)
|
||||
{
|
||||
|
||||
@@ -1119,7 +1119,7 @@ transferNFToken(
|
||||
if (!tokenAndPage)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto const ret = nft::removeToken(view, seller, nftokenID, std::move(tokenAndPage->page));
|
||||
if (auto const ret = nft::removeToken(view, seller, nftokenID, tokenAndPage->page);
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ Emitable::getEmitableName(std::uint32_t const value) const
|
||||
{
|
||||
auto const emitableValue = static_cast<GranularEmitableType>(value);
|
||||
if (auto const granular = getGranularName(emitableValue))
|
||||
return *granular;
|
||||
return granular;
|
||||
|
||||
// not a granular emitable, check if it maps to a transaction type
|
||||
auto const txType = emitableToTxType(value);
|
||||
|
||||
@@ -140,9 +140,9 @@ STData::STData(SField const& n, STNumber const& v)
|
||||
|
||||
STData::STData(SerialIter& sit, SField const& name) : STBase(name), data_(STBase{})
|
||||
{
|
||||
std::uint16_t stype = SerializedTypeID(sit.get16());
|
||||
std::uint16_t const stype = SerializedTypeID(sit.get16());
|
||||
inner_type_ = stype;
|
||||
SerializedTypeID s = static_cast<SerializedTypeID>(stype);
|
||||
SerializedTypeID const s = static_cast<SerializedTypeID>(stype);
|
||||
switch (s)
|
||||
{
|
||||
case STI_UINT8: {
|
||||
@@ -437,7 +437,7 @@ STData::getInnerTypeString() const
|
||||
std::string
|
||||
STData::getText() const
|
||||
{
|
||||
std::string inner_type_str = getInnerTypeString();
|
||||
std::string const inner_type_str = getInnerTypeString();
|
||||
return "STData{InnerType: " + inner_type_str + ", Data: " + data_.get().getText() + "}";
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ STData::getJson(JsonOptions options) const
|
||||
STBase*
|
||||
STData::makeFieldPresent()
|
||||
{
|
||||
STBase* f = &data_.get(); // getPIndex(index);
|
||||
STBase const* f = &data_.get(); // getPIndex(index);
|
||||
|
||||
if (f->getSType() != STI_NOTPRESENT)
|
||||
return f;
|
||||
@@ -633,7 +633,7 @@ STData::getFieldH256() const
|
||||
Blob
|
||||
STData::getFieldVL() const
|
||||
{
|
||||
STBlob empty;
|
||||
STBlob const empty;
|
||||
STBlob const& b = getFieldByConstRef<STBlob>(empty);
|
||||
return Blob(b.data(), b.data() + b.size());
|
||||
}
|
||||
@@ -738,7 +738,7 @@ dataFromJson(SField const& field, Json::Value const& v)
|
||||
{
|
||||
auto const str = value.asString();
|
||||
|
||||
std::uint64_t val;
|
||||
std::uint64_t val = 0;
|
||||
|
||||
bool const useBase10 = field.shouldMeta(SField::sMD_BaseTen);
|
||||
|
||||
@@ -956,7 +956,7 @@ dataFromJson(SField const& field, Json::Value const& v)
|
||||
Throw<std::runtime_error>("STData: expected string for NUMBER");
|
||||
}
|
||||
|
||||
STNumber number = numberFromJson(field, value);
|
||||
STNumber const number = numberFromJson(field, value);
|
||||
STData data(field, number);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ STDataType::STDataType(SField const& n, SerializedTypeID v)
|
||||
STDataType::STDataType(SerialIter& sit, SField const& name)
|
||||
: STBase(name), inner_type_(STI_DATA), default_(false)
|
||||
{
|
||||
std::uint16_t stype = SerializedTypeID(sit.get16());
|
||||
std::uint16_t const stype = SerializedTypeID(sit.get16());
|
||||
inner_type_ = stype;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ STDataType::getInnerTypeString() const
|
||||
std::string
|
||||
STDataType::getText() const
|
||||
{
|
||||
std::string inner_type_str = getInnerTypeString();
|
||||
std::string const inner_type_str = getInnerTypeString();
|
||||
return "STDataType{InnerType: " + inner_type_str + "}";
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ dataTypeFromJson(SField const& field, Json::Value const& v)
|
||||
{
|
||||
SerializedTypeID typeId = STI_NOTPRESENT;
|
||||
Json::Value type;
|
||||
Json::Value value;
|
||||
Json::Value const value;
|
||||
|
||||
if (!v.isObject())
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAccount.h>
|
||||
@@ -46,10 +47,10 @@ STJson::STJson(SerialIter& sit, SField const& name) : STBase{name}
|
||||
|
||||
// Read type byte
|
||||
auto typeByte = sit.get8();
|
||||
JsonType type = static_cast<JsonType>(typeByte);
|
||||
JsonType const type = static_cast<JsonType>(typeByte);
|
||||
length--; // Account for type byte
|
||||
|
||||
int initialBytesLeft = sit.getBytesLeft();
|
||||
int const initialBytesLeft = sit.getBytesLeft();
|
||||
|
||||
if (type == JsonType::Array)
|
||||
{
|
||||
@@ -81,7 +82,7 @@ STJson::STJson(SerialIter& sit, SField const& name) : STBase{name}
|
||||
data_ = std::move(map);
|
||||
}
|
||||
|
||||
int consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
int const consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
if (consumedBytes != length)
|
||||
Throw<std::runtime_error>("STJson length mismatch");
|
||||
}
|
||||
@@ -161,9 +162,14 @@ STJson::validateDepth(Value const& value, int currentDepth) const
|
||||
if (!nested)
|
||||
return;
|
||||
|
||||
int valueDepth = nested->getDepth();
|
||||
if (currentDepth + valueDepth > 1)
|
||||
// Adding an STJson value increases depth by 1
|
||||
int const totalDepth = currentDepth + 1 + nested->getDepth();
|
||||
if (totalDepth > 1)
|
||||
Throw<std::runtime_error>("STJson nesting depth exceeds maximum of 1");
|
||||
|
||||
// Arrays cannot contain arrays
|
||||
if (isArray() && nested->isArray())
|
||||
Throw<std::runtime_error>("STJson arrays cannot contain arrays");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -197,10 +203,10 @@ STJson::fromSerialIter(SerialIter& sit)
|
||||
|
||||
// Read type byte
|
||||
auto typeByte = sit.get8();
|
||||
JsonType type = static_cast<JsonType>(typeByte);
|
||||
JsonType const type = static_cast<JsonType>(typeByte);
|
||||
length--; // Account for type byte
|
||||
|
||||
int initialBytesLeft = sit.getBytesLeft();
|
||||
int const initialBytesLeft = sit.getBytesLeft();
|
||||
|
||||
if (type == JsonType::Array)
|
||||
{
|
||||
@@ -220,7 +226,7 @@ STJson::fromSerialIter(SerialIter& sit)
|
||||
}
|
||||
}
|
||||
|
||||
int consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
int const consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
if (consumedBytes != length)
|
||||
Throw<std::runtime_error>("STJson length mismatch");
|
||||
|
||||
@@ -235,7 +241,7 @@ STJson::fromSerialIter(SerialIter& sit)
|
||||
map.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
|
||||
int consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
int const consumedBytes = initialBytesLeft - sit.getBytesLeft();
|
||||
if (consumedBytes != length)
|
||||
Throw<std::runtime_error>("STJson length mismatch");
|
||||
|
||||
@@ -262,7 +268,7 @@ STJson::Array
|
||||
STJson::parseArray(SerialIter& sit, int length)
|
||||
{
|
||||
Array array;
|
||||
int initialBytesLeft = sit.getBytesLeft();
|
||||
int const initialBytesLeft = sit.getBytesLeft();
|
||||
|
||||
while (sit.getBytesLeft() > 0 && (initialBytesLeft - sit.getBytesLeft()) < length)
|
||||
{
|
||||
@@ -290,7 +296,7 @@ STJson::makeValueFromVLWithType(SerialIter& sit)
|
||||
|
||||
// Read SType marker (1 byte)
|
||||
auto typeCode = sit.get8();
|
||||
SerializedTypeID stype = static_cast<SerializedTypeID>(typeCode);
|
||||
SerializedTypeID const stype = static_cast<SerializedTypeID>(typeCode);
|
||||
|
||||
// Dispatch to correct SType
|
||||
switch (stype)
|
||||
@@ -699,10 +705,11 @@ STJson::getJson(JsonOptions options) const
|
||||
auto const& map = std::get<Map>(data_);
|
||||
for (auto const& [key, value] : map)
|
||||
{
|
||||
auto const hexKey = strHex(key);
|
||||
if (value)
|
||||
obj[key] = value->getJson(options);
|
||||
obj[hexKey] = value->getJson(options);
|
||||
else
|
||||
obj[key] = Json::nullValue;
|
||||
obj[hexKey] = Json::nullValue;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -775,6 +775,9 @@ STObject::addFieldFromSlice(SField const& sfield, Slice const& data)
|
||||
case STI_UINT160:
|
||||
element = std::make_unique<STUInt160>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT192:
|
||||
element = std::make_unique<STUInt192>(sit, sfield);
|
||||
break;
|
||||
case STI_UINT256:
|
||||
element = std::make_unique<STUInt256>(sit, sfield);
|
||||
break;
|
||||
|
||||
@@ -93,7 +93,7 @@ ContractCall::preclaim(PreclaimContext const& ctx)
|
||||
auto it = std::find_if(
|
||||
functions.begin(), functions.end(), [&functionNameHexStr](STObject const& func) {
|
||||
auto const funcName = func.getFieldVL(sfFunctionName);
|
||||
std::string functionNameDefHexStr(funcName.begin(), funcName.end());
|
||||
std::string const functionNameDefHexStr(funcName.begin(), funcName.end());
|
||||
return functionNameDefHexStr == functionNameHexStr;
|
||||
});
|
||||
|
||||
@@ -178,9 +178,9 @@ ContractCall::doApply()
|
||||
|
||||
// WASM execution
|
||||
auto const wasmStr = contractSourceSle->getFieldVL(sfContractCode);
|
||||
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
|
||||
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
|
||||
auto const functionName = ctx_.tx.getFieldVL(sfFunctionName);
|
||||
std::string funcName(functionName.begin(), functionName.end());
|
||||
std::string const funcName(functionName.begin(), functionName.end());
|
||||
|
||||
auto const contractFunctions = contractSle->isFieldPresent(sfFunctions)
|
||||
? contractSle->getFieldArray(sfFunctions)
|
||||
@@ -229,8 +229,8 @@ ContractCall::doApply()
|
||||
return tecINVALID_PARAMETERS;
|
||||
}
|
||||
|
||||
xrpl::ContractDataMap dataMap;
|
||||
xrpl::ContractEventMap eventMap;
|
||||
xrpl::ContractDataMap const dataMap;
|
||||
xrpl::ContractEventMap const eventMap;
|
||||
ContractContext contractCtx = {
|
||||
.applyCtx = ctx_,
|
||||
.instanceParameters = instanceParameters,
|
||||
@@ -255,6 +255,7 @@ ContractCall::doApply()
|
||||
.eventMap = eventMap,
|
||||
.changedDataCount = 0,
|
||||
},
|
||||
.emitView = std::nullopt,
|
||||
};
|
||||
|
||||
ContractHostFunctionsImpl ledgerDataProvider(contractCtx);
|
||||
@@ -265,7 +266,7 @@ ContractCall::doApply()
|
||||
return tefINTERNAL;
|
||||
}
|
||||
|
||||
std::uint32_t allowance = ctx_.tx[sfComputationAllowance];
|
||||
std::uint32_t const allowance = ctx_.tx[sfComputationAllowance];
|
||||
auto re = runEscrowWasm(wasm, ledgerDataProvider, allowance, funcName, {});
|
||||
|
||||
// Wasm Result
|
||||
@@ -291,7 +292,7 @@ ContractCall::doApply()
|
||||
auto ret = re.value().result;
|
||||
if (ret < 0)
|
||||
{
|
||||
JLOG(j_.trace()) << "WASM Execution Failed: " << contractCtx.result.exitReason;
|
||||
JLOG(j_.trace()) << "WASM Execution Failed: " << ret;
|
||||
ctx_.setWasmReturnCode(ret);
|
||||
// ctx_.setWasmReturnStr(contractCtx.result.exitReason);
|
||||
return tecWASM_REJECTED;
|
||||
|
||||
@@ -55,7 +55,7 @@ ContractDelete::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
std::uint32_t flags = contractSle->getFlags();
|
||||
std::uint32_t const flags = contractSle->getFlags();
|
||||
|
||||
// Check if the contract is undeletable.
|
||||
if (flags & tfUndeletable)
|
||||
|
||||
@@ -103,7 +103,7 @@ ContractModify::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
std::uint32_t flags = contractSle->getFlags();
|
||||
std::uint32_t const flags = contractSle->getFlags();
|
||||
|
||||
// Check if the contract is immutable.
|
||||
if (flags & tfImmutable)
|
||||
|
||||
@@ -2262,10 +2262,6 @@ buildTxn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
|
||||
auto* hf = getHF(env);
|
||||
auto const* rt = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
int index = 0;
|
||||
if (params->data[1].of.i32 > maxWasmDataLength)
|
||||
{
|
||||
return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE);
|
||||
}
|
||||
|
||||
auto const txnType = getDataInt32(rt, params, index);
|
||||
if (!txnType)
|
||||
@@ -2314,10 +2310,6 @@ emitBuiltTxn_wrap(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* resul
|
||||
auto* hf = getHF(env);
|
||||
auto const* rt = reinterpret_cast<InstanceWrapper const*>(hf->getRT());
|
||||
int index = 0;
|
||||
if (params->data[1].of.i32 > maxWasmDataLength)
|
||||
{
|
||||
return hfResult(results, HostFunctionError::DATA_FIELD_TOO_LARGE);
|
||||
}
|
||||
|
||||
auto const txnIndex = getDataInt32(rt, params, index);
|
||||
if (!txnIndex)
|
||||
|
||||
@@ -35,10 +35,10 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
uint256 const& contractHash = uint256{1})
|
||||
{
|
||||
using namespace jtx;
|
||||
xrpl::ContractDataMap dataMap;
|
||||
xrpl::ContractEventMap eventMap;
|
||||
std::vector<xrpl::ParameterValueVec> instanceParameters;
|
||||
std::vector<xrpl::ParameterValueVec> functionParameters;
|
||||
xrpl::ContractDataMap const dataMap;
|
||||
xrpl::ContractEventMap const eventMap;
|
||||
std::vector<xrpl::ParameterValueVec> const instanceParameters;
|
||||
std::vector<xrpl::ParameterValueVec> const functionParameters;
|
||||
|
||||
uint256 const& txId = uint256{2};
|
||||
|
||||
@@ -69,6 +69,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
.eventMap = eventMap,
|
||||
.changedDataCount = 0,
|
||||
},
|
||||
.emitView = std::nullopt,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -412,7 +413,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Add test function parameters (same as instance parameters for
|
||||
// testing) [Similar parameter setup as instanceParam test...]
|
||||
|
||||
ContractHostFunctionsImpl cfs(contractCtx);
|
||||
ContractHostFunctionsImpl const cfs(contractCtx);
|
||||
|
||||
// [Similar tests as instanceParam but using functionParam method...]
|
||||
}
|
||||
@@ -513,14 +514,14 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Test multiple keys for same account
|
||||
{
|
||||
auto value1 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'v', 'a', 'l', 'u', 'e', '1'};
|
||||
Blob const data = {'v', 'a', 'l', 'u', 'e', '1'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult1 = cfs.setDataObjectField(alice.id(), "field1", value1);
|
||||
BEAST_EXPECT(!setResult1.has_value());
|
||||
|
||||
auto value2 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'v', 'a', 'l', 'u', 'e', '2'};
|
||||
Blob const data = {'v', 'a', 'l', 'u', 'e', '2'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult2 = cfs.setDataObjectField(alice.id(), "field2", value2);
|
||||
@@ -566,28 +567,26 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Test setDataNestedObjectField
|
||||
{
|
||||
auto value = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'A', 'l', 'i', 'c', 'e'};
|
||||
Blob const data = {'A', 'l', 'i', 'c', 'e'};
|
||||
s.addVL(data);
|
||||
});
|
||||
|
||||
auto setResult =
|
||||
cfs.setDataNestedObjectField(alice.id(), "profile", "firstName", value);
|
||||
BEAST_EXPECT(!setResult.has_value());
|
||||
if (!setResult.has_value())
|
||||
BEAST_EXPECT(setResult.error() == HostFunctionError::INTERNAL);
|
||||
BEAST_EXPECT(setResult.has_value());
|
||||
|
||||
// Add more nested fields
|
||||
auto value2 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'S', 'm', 'i', 't', 'h'};
|
||||
Blob const data = {'S', 'm', 'i', 't', 'h'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult2 =
|
||||
cfs.setDataNestedObjectField(alice.id(), "profile", "lastName", value2);
|
||||
BEAST_EXPECT(!setResult2.has_value());
|
||||
BEAST_EXPECT(setResult2.has_value());
|
||||
|
||||
auto value3 = createJsonValue(STI_UINT32, [](Serializer& s) { s.add32(25); });
|
||||
auto setResult3 = cfs.setDataNestedObjectField(alice.id(), "profile", "age", value3);
|
||||
BEAST_EXPECT(!setResult3.has_value());
|
||||
BEAST_EXPECT(setResult3.has_value());
|
||||
|
||||
// Retrieve nested fields
|
||||
auto getResult1 = cfs.getDataNestedObjectField(alice.id(), "profile", "firstName");
|
||||
@@ -603,26 +602,26 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Test nested objects with different parent keys
|
||||
{
|
||||
auto value1 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'d', 'a', 'r', 'k'};
|
||||
Blob const data = {'d', 'a', 'r', 'k'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult1 = cfs.setDataNestedObjectField(alice.id(), "settings", "theme", value1);
|
||||
BEAST_EXPECT(!setResult1.has_value());
|
||||
BEAST_EXPECT(setResult1.has_value());
|
||||
|
||||
auto value2 = createJsonValue(STI_UINT8, [](Serializer& s) {
|
||||
s.add8(1); // true
|
||||
});
|
||||
auto setResult2 =
|
||||
cfs.setDataNestedObjectField(alice.id(), "settings", "notifications", value2);
|
||||
BEAST_EXPECT(!setResult2.has_value());
|
||||
BEAST_EXPECT(setResult2.has_value());
|
||||
|
||||
auto value3 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'e', 'n'};
|
||||
Blob const data = {'e', 'n'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult3 =
|
||||
cfs.setDataNestedObjectField(alice.id(), "preferences", "language", value3);
|
||||
BEAST_EXPECT(!setResult3.has_value());
|
||||
BEAST_EXPECT(setResult3.has_value());
|
||||
|
||||
// Verify nested data retrieval
|
||||
auto getResult1 = cfs.getDataNestedObjectField(alice.id(), "settings", "theme");
|
||||
@@ -652,11 +651,11 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
{
|
||||
auto value1 = createJsonValue(STI_UINT32, [](Serializer& s) { s.add32(100); });
|
||||
auto setResult1 = cfs.setDataNestedObjectField(bob.id(), "stats", "score", value1);
|
||||
BEAST_EXPECT(!setResult1.has_value());
|
||||
BEAST_EXPECT(setResult1.has_value());
|
||||
|
||||
auto value2 = createJsonValue(STI_UINT32, [](Serializer& s) { s.add32(150); });
|
||||
auto setResult2 = cfs.setDataNestedObjectField(bob.id(), "stats", "score", value2);
|
||||
BEAST_EXPECT(!setResult2.has_value());
|
||||
BEAST_EXPECT(setResult2.has_value());
|
||||
|
||||
auto getResult = cfs.getDataNestedObjectField(bob.id(), "stats", "score");
|
||||
BEAST_EXPECT(getResult.has_value());
|
||||
@@ -687,28 +686,26 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Test setDataNestedObjectField
|
||||
{
|
||||
auto value = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'A', 'l', 'i', 'c', 'e'};
|
||||
Blob const data = {'A', 'l', 'i', 'c', 'e'};
|
||||
s.addVL(data);
|
||||
});
|
||||
|
||||
auto setResult =
|
||||
cfs.setDataNestedObjectField(alice.id(), "profile", "firstName", value);
|
||||
BEAST_EXPECT(!setResult.has_value());
|
||||
if (!setResult.has_value())
|
||||
BEAST_EXPECT(setResult.error() == HostFunctionError::INTERNAL);
|
||||
BEAST_EXPECT(setResult.has_value());
|
||||
|
||||
// Add more nested fields
|
||||
auto value2 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'S', 'm', 'i', 't', 'h'};
|
||||
Blob const data = {'S', 'm', 'i', 't', 'h'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult2 =
|
||||
cfs.setDataNestedObjectField(alice.id(), "profile", "lastName", value2);
|
||||
BEAST_EXPECT(!setResult2.has_value());
|
||||
BEAST_EXPECT(setResult2.has_value());
|
||||
|
||||
auto value3 = createJsonValue(STI_UINT32, [](Serializer& s) { s.add32(25); });
|
||||
auto setResult3 = cfs.setDataNestedObjectField(alice.id(), "profile", "age", value3);
|
||||
BEAST_EXPECT(!setResult3.has_value());
|
||||
BEAST_EXPECT(setResult3.has_value());
|
||||
|
||||
// Retrieve nested fields
|
||||
auto getResult1 = cfs.getDataNestedObjectField(alice.id(), "profile", "firstName");
|
||||
@@ -724,26 +721,26 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Test nested objects with different parent keys
|
||||
{
|
||||
auto value1 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'d', 'a', 'r', 'k'};
|
||||
Blob const data = {'d', 'a', 'r', 'k'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult1 = cfs.setDataNestedObjectField(alice.id(), "settings", "theme", value1);
|
||||
BEAST_EXPECT(!setResult1.has_value());
|
||||
BEAST_EXPECT(setResult1.has_value());
|
||||
|
||||
auto value2 = createJsonValue(STI_UINT8, [](Serializer& s) {
|
||||
s.add8(1); // true
|
||||
});
|
||||
auto setResult2 =
|
||||
cfs.setDataNestedObjectField(alice.id(), "settings", "notifications", value2);
|
||||
BEAST_EXPECT(!setResult2.has_value());
|
||||
BEAST_EXPECT(setResult2.has_value());
|
||||
|
||||
auto value3 = createJsonValue(STI_VL, [](Serializer& s) {
|
||||
Blob data = {'e', 'n'};
|
||||
Blob const data = {'e', 'n'};
|
||||
s.addVL(data);
|
||||
});
|
||||
auto setResult3 =
|
||||
cfs.setDataNestedObjectField(alice.id(), "preferences", "language", value3);
|
||||
BEAST_EXPECT(!setResult3.has_value());
|
||||
BEAST_EXPECT(setResult3.has_value());
|
||||
|
||||
// Verify nested data retrieval
|
||||
auto getResult1 = cfs.getDataNestedObjectField(alice.id(), "settings", "theme");
|
||||
@@ -773,11 +770,11 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
{
|
||||
auto value1 = createJsonValue(STI_UINT32, [](Serializer& s) { s.add32(100); });
|
||||
auto setResult1 = cfs.setDataNestedObjectField(bob.id(), "stats", "score", value1);
|
||||
BEAST_EXPECT(!setResult1.has_value());
|
||||
BEAST_EXPECT(setResult1.has_value());
|
||||
|
||||
auto value2 = createJsonValue(STI_UINT32, [](Serializer& s) { s.add32(150); });
|
||||
auto setResult2 = cfs.setDataNestedObjectField(bob.id(), "stats", "score", value2);
|
||||
BEAST_EXPECT(!setResult2.has_value());
|
||||
BEAST_EXPECT(setResult2.has_value());
|
||||
|
||||
auto getResult = cfs.getDataNestedObjectField(bob.id(), "stats", "score");
|
||||
BEAST_EXPECT(getResult.has_value());
|
||||
@@ -911,7 +908,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
if (!buildResult.has_value())
|
||||
return;
|
||||
|
||||
uint32_t txIndex = buildResult.value();
|
||||
uint32_t const txIndex = buildResult.value();
|
||||
|
||||
// Test adding Destination (AccountID) with 0x14 prefix
|
||||
{
|
||||
@@ -935,7 +932,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
// Test adding Amount (STAmount - XRP)
|
||||
{
|
||||
STAmount amount{XRP(1000)};
|
||||
STAmount const amount{XRP(1000)};
|
||||
Serializer s;
|
||||
amount.add(s);
|
||||
auto result = cfs.addTxnField(txIndex, sfAmount, s.slice());
|
||||
@@ -952,7 +949,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
// Test adding SendMax (STAmount - IOU)
|
||||
{
|
||||
auto const USD = alice["USD"];
|
||||
STAmount sendMax{USD.issue(), 500};
|
||||
STAmount const sendMax{USD.issue(), 500};
|
||||
Serializer s;
|
||||
sendMax.add(s);
|
||||
auto result = cfs.addTxnField(txIndex, sfSendMax, s.slice());
|
||||
@@ -968,7 +965,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
// Test adding DestinationTag (UInt32)
|
||||
{
|
||||
uint32_t tag = 12345;
|
||||
uint32_t const tag = 12345;
|
||||
Serializer s;
|
||||
s.add32(tag);
|
||||
auto result = cfs.addTxnField(txIndex, sfDestinationTag, s.slice());
|
||||
@@ -987,12 +984,12 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(trustBuildResult.has_value());
|
||||
if (trustBuildResult.has_value())
|
||||
{
|
||||
uint32_t trustIndex = trustBuildResult.value();
|
||||
uint32_t const trustIndex = trustBuildResult.value();
|
||||
|
||||
// Test adding LimitAmount (STAmount for TrustSet)
|
||||
{
|
||||
auto const EUR = alice["EUR"];
|
||||
STAmount limit{EUR.issue(), 10000};
|
||||
STAmount const limit{EUR.issue(), 10000};
|
||||
Serializer s;
|
||||
limit.add(s);
|
||||
auto result = cfs.addTxnField(trustIndex, sfLimitAmount, s.slice());
|
||||
@@ -1008,7 +1005,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
// Test adding QualityIn (UInt32)
|
||||
{
|
||||
uint32_t quality = 1000000;
|
||||
uint32_t const quality = 1000000;
|
||||
Serializer s;
|
||||
s.add32(quality);
|
||||
auto result = cfs.addTxnField(trustIndex, sfQualityIn, s.slice());
|
||||
@@ -1028,11 +1025,11 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(accSetResult.has_value());
|
||||
if (accSetResult.has_value())
|
||||
{
|
||||
uint32_t accSetIndex = accSetResult.value();
|
||||
uint32_t const accSetIndex = accSetResult.value();
|
||||
|
||||
// Test adding Domain (Blob/VL)
|
||||
{
|
||||
Blob domain = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'};
|
||||
Blob const domain = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'};
|
||||
Serializer s;
|
||||
s.addVL(domain);
|
||||
auto result = cfs.addTxnField(accSetIndex, sfDomain, s.slice());
|
||||
@@ -1048,7 +1045,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
// Test adding TransferRate (UInt32)
|
||||
{
|
||||
uint32_t fee = 500;
|
||||
uint32_t const fee = 500;
|
||||
Serializer s;
|
||||
s.add32(fee);
|
||||
auto result = cfs.addTxnField(accSetIndex, sfTransferRate, s.slice());
|
||||
@@ -1064,7 +1061,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
// Test adding SetFlag (UInt32)
|
||||
{
|
||||
uint32_t flag = 8; // asfRequireAuth
|
||||
uint32_t const flag = 8; // asfRequireAuth
|
||||
Serializer s;
|
||||
s.add32(flag);
|
||||
auto result = cfs.addTxnField(accSetIndex, sfSetFlag, s.slice());
|
||||
@@ -1143,7 +1140,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
if (!buildResult.has_value())
|
||||
return;
|
||||
|
||||
uint32_t txIndex = buildResult.value();
|
||||
uint32_t const txIndex = buildResult.value();
|
||||
|
||||
// Add required fields for Payment
|
||||
AccountID destAccount = bob.id();
|
||||
@@ -1156,7 +1153,7 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(destResult.has_value());
|
||||
|
||||
// Add Amount field
|
||||
STAmount amount{XRP(100)};
|
||||
STAmount const amount{XRP(100)};
|
||||
Serializer amtSerializer;
|
||||
amount.add(amtSerializer);
|
||||
auto amtResult = cfs.addTxnField(txIndex, sfAmount, amtSerializer.slice());
|
||||
@@ -1171,81 +1168,79 @@ struct ContractHostFuncImpl_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(contractCtx.result.emittedTxns.size() == 1);
|
||||
|
||||
// The result should be a TER code converted to int
|
||||
int32_t terCode = emitResult.value();
|
||||
int32_t const terCode = emitResult.value();
|
||||
// We expect a success code
|
||||
BEAST_EXPECT(terCode == 0);
|
||||
}
|
||||
}
|
||||
|
||||
// // Test emitting multiple transactions
|
||||
// {
|
||||
// // Build first transaction - Payment
|
||||
// auto build1 = cfs.buildTxn(ttPAYMENT);
|
||||
// BEAST_EXPECT(build1.has_value());
|
||||
// if (build1.has_value())
|
||||
// {
|
||||
// uint32_t tx1 = build1.value();
|
||||
// Test emitting multiple transactions
|
||||
{
|
||||
// Build first transaction - Payment
|
||||
auto build1 = cfs.buildTxn(ttPAYMENT);
|
||||
BEAST_EXPECT(build1.has_value());
|
||||
if (build1.has_value())
|
||||
{
|
||||
uint32_t const tx1 = build1.value();
|
||||
|
||||
// // Add fields for first payment
|
||||
// AccountID dest1 = alice.id();
|
||||
// Blob dest1Buf;
|
||||
// dest1Buf.reserve(1 + dest1.size());
|
||||
// dest1Buf.push_back(0x14);
|
||||
// dest1Buf.insert(dest1Buf.end(), dest1.begin(), dest1.end());
|
||||
// auto const result = cfs.addTxnField(
|
||||
// tx1,
|
||||
// sfDestination,
|
||||
// Slice{dest1Buf.data(), dest1Buf.size()});
|
||||
// BEAST_EXPECT(result.has_value());
|
||||
// Add fields for first payment
|
||||
AccountID dest1 = alice.id();
|
||||
Blob dest1Buf;
|
||||
dest1Buf.reserve(1 + dest1.size());
|
||||
dest1Buf.push_back(0x14);
|
||||
dest1Buf.insert(dest1Buf.end(), dest1.begin(), dest1.end());
|
||||
auto const result =
|
||||
cfs.addTxnField(tx1, sfDestination, Slice{dest1Buf.data(), dest1Buf.size()});
|
||||
BEAST_EXPECT(result.has_value());
|
||||
|
||||
// STAmount amt1{XRP(50)};
|
||||
// Serializer amt1Ser;
|
||||
// amt1.add(amt1Ser);
|
||||
// cfs.addTxnField(tx1, sfAmount, amt1Ser.slice());
|
||||
// }
|
||||
STAmount const amt1{XRP(50)};
|
||||
Serializer amt1Ser;
|
||||
amt1.add(amt1Ser);
|
||||
[[maybe_unused]] auto const amt1Result =
|
||||
cfs.addTxnField(tx1, sfAmount, amt1Ser.slice());
|
||||
}
|
||||
|
||||
// // Build second transaction - Another Payment
|
||||
// auto build2 = cfs.buildTxn(ttPAYMENT);
|
||||
// BEAST_EXPECT(build2.has_value());
|
||||
// if (build2.has_value())
|
||||
// {
|
||||
// uint32_t tx2 = build2.value();
|
||||
// Build second transaction - Another Payment
|
||||
auto build2 = cfs.buildTxn(ttPAYMENT);
|
||||
BEAST_EXPECT(build2.has_value());
|
||||
if (build2.has_value())
|
||||
{
|
||||
uint32_t const tx2 = build2.value();
|
||||
|
||||
// // Add fields for second payment
|
||||
// AccountID dest2 = carol.id();
|
||||
// Blob dest2Buf;
|
||||
// dest2Buf.reserve(1 + dest2.size());
|
||||
// dest2Buf.push_back(0x14);
|
||||
// dest2Buf.insert(dest2Buf.end(), dest2.begin(), dest2.end());
|
||||
// auto const result = cfs.addTxnField(
|
||||
// tx2,
|
||||
// sfDestination,
|
||||
// Slice{dest2Buf.data(), dest2Buf.size()});
|
||||
// BEAST_EXPECT(result.has_value());
|
||||
// Add fields for second payment
|
||||
AccountID dest2 = carol.id();
|
||||
Blob dest2Buf;
|
||||
dest2Buf.reserve(1 + dest2.size());
|
||||
dest2Buf.push_back(0x14);
|
||||
dest2Buf.insert(dest2Buf.end(), dest2.begin(), dest2.end());
|
||||
auto const result =
|
||||
cfs.addTxnField(tx2, sfDestination, Slice{dest2Buf.data(), dest2Buf.size()});
|
||||
BEAST_EXPECT(result.has_value());
|
||||
|
||||
// STAmount amt2{XRP(75)};
|
||||
// Serializer amt2Ser;
|
||||
// amt2.add(amt2Ser);
|
||||
// cfs.addTxnField(tx2, sfAmount, amt2Ser.slice());
|
||||
// }
|
||||
STAmount const amt2{XRP(75)};
|
||||
Serializer amt2Ser;
|
||||
amt2.add(amt2Ser);
|
||||
[[maybe_unused]] auto const amt2Result =
|
||||
cfs.addTxnField(tx2, sfAmount, amt2Ser.slice());
|
||||
}
|
||||
|
||||
// // Emit both transactions
|
||||
// if (build1.has_value())
|
||||
// {
|
||||
// auto emit1 = cfs.emitBuiltTxn(build1.value());
|
||||
// BEAST_EXPECT(emit1.has_value());
|
||||
// }
|
||||
// Emit both transactions
|
||||
if (build1.has_value())
|
||||
{
|
||||
auto emit1 = cfs.emitBuiltTxn(build1.value());
|
||||
BEAST_EXPECT(emit1.has_value());
|
||||
}
|
||||
|
||||
// if (build2.has_value())
|
||||
// {
|
||||
// auto emit2 = cfs.emitBuiltTxn(build2.value());
|
||||
// BEAST_EXPECT(emit2.has_value());
|
||||
// }
|
||||
if (build2.has_value())
|
||||
{
|
||||
auto emit2 = cfs.emitBuiltTxn(build2.value());
|
||||
BEAST_EXPECT(emit2.has_value());
|
||||
}
|
||||
|
||||
// // Check that both were added to emitted transactions
|
||||
// // (Note: actual count depends on previous test state)
|
||||
// BEAST_EXPECT(contractCtx.result.emittedTxns.size() >= 2);
|
||||
// }
|
||||
// Check that both were added to emitted transactions
|
||||
// (Note: actual count depends on previous test state)
|
||||
BEAST_EXPECT(contractCtx.result.emittedTxns.size() >= 2);
|
||||
}
|
||||
|
||||
// // Test emitting transaction with invalid index
|
||||
// {
|
||||
|
||||
@@ -310,11 +310,15 @@ class Contract_test : public beast::unit_test::suite
|
||||
|
||||
auto const wasmBytes = strUnHex(jt.jv[sfContractCode.jsonName].asString());
|
||||
// std::cout << "WASM Size: " << wasmBytes->size() << std::endl;
|
||||
if (!wasmBytes || wasmBytes->empty())
|
||||
return std::make_tuple(jtx::Account{"invalid"}, uint256{}, jt.jv);
|
||||
uint256 const contractHash =
|
||||
xrpl::sha512Half_s(xrpl::Slice(wasmBytes->data(), wasmBytes->size()));
|
||||
auto const accountID = parseBase58<AccountID>(jt.jv[sfAccount].asString());
|
||||
auto const [contractKey, sle] = contractKeyAndSle(
|
||||
*env.current(), contractHash, *accountID, jt.jv[sfSequence.jsonName].asUInt());
|
||||
if (!sle)
|
||||
return std::make_tuple(jtx::Account{"invalid"}, contractHash, jt.jv);
|
||||
jtx::Account const contractAccount{
|
||||
"Contract pseudo-account", sle->getAccountID(sfContractAccount)};
|
||||
return std::make_tuple(contractAccount, contractHash, jt.jv);
|
||||
@@ -1434,8 +1438,8 @@ class Contract_test : public beast::unit_test::suite
|
||||
loadContractWasmStr(std::string const& contract_name = "")
|
||||
{
|
||||
std::string const& dir = "e2e-tests";
|
||||
std::string name = "/Users/darkmatter/projects/ledger-works/xrpl-wasm-std/" + dir + "/" +
|
||||
contract_name + "/target/wasm32v1-none/release/" + contract_name + ".wasm";
|
||||
std::string const name = "/Users/darkmatter/projects/ledger-works/xrpl-wasm-std/" + dir +
|
||||
"/" + contract_name + "/target/wasm32v1-none/release/" + contract_name + ".wasm";
|
||||
if (!boost::filesystem::exists(name))
|
||||
{
|
||||
std::cout << "File does not exist: " << name << "\n";
|
||||
@@ -1451,7 +1455,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
// Read the file into a vector
|
||||
std::vector<char> buffer(
|
||||
std::vector<char> const buffer(
|
||||
(std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
// Check if the buffer is empty
|
||||
@@ -1478,7 +1482,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
std::string const contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1513,7 +1517,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
std::string const contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1548,7 +1552,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
std::string const contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1583,7 +1587,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
std::string const contractDataWasmHex = loadContractWasmStr("contract_data");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1623,7 +1627,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
// Test Instance Parameter (1 of 2)
|
||||
// uint8, uint16, uint32, uint64, uint128, uint160, uint192, uint256
|
||||
{
|
||||
std::string wasmHex = loadContractWasmStr("instance_params_uint");
|
||||
std::string const wasmHex = loadContractWasmStr("instance_params_uint");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1667,7 +1671,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
{
|
||||
// Test Instance Parameter (2 of 2)
|
||||
// vl, account, amount (XRP), amount (IOU), number, currency, issue
|
||||
std::string wasmHex = loadContractWasmStr("instance_params_other");
|
||||
std::string const wasmHex = loadContractWasmStr("instance_params_other");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1714,7 +1718,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string wasmHex = loadContractWasmStr("function_params");
|
||||
std::string const wasmHex = loadContractWasmStr("function_params");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1804,7 +1808,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string emitTxWasmHex = loadContractWasmStr("emit_txn");
|
||||
std::string const emitTxWasmHex = loadContractWasmStr("emit_txn");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1862,7 +1866,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(jv[jss::result][jss::status] == "success");
|
||||
}
|
||||
|
||||
std::string eventsWasmHex = loadContractWasmStr("events");
|
||||
std::string const eventsWasmHex = loadContractWasmStr("events");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
@@ -1943,7 +1947,7 @@ class Contract_test : public beast::unit_test::suite
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
std::string wasmHex = loadContractWasmStr("easymode");
|
||||
std::string const wasmHex = loadContractWasmStr("easymode");
|
||||
auto const [contractAccount, contractHash, _] = setContract(
|
||||
env,
|
||||
tesSUCCESS,
|
||||
|
||||
@@ -1816,10 +1816,10 @@ class Delegate_test : public beast::unit_test::suite
|
||||
#pragma push_macro("TRANSACTION")
|
||||
#undef TRANSACTION
|
||||
|
||||
#define TRANSACTION(tag, value, name, delegable, ...) \
|
||||
if (delegable == xrpl::delegable) \
|
||||
{ \
|
||||
delegableCount++; \
|
||||
#define TRANSACTION(tag, value, name, delegationStatus, ...) \
|
||||
if (delegationStatus == Delegation::delegable) \
|
||||
{ \
|
||||
delegableCount++; \
|
||||
}
|
||||
|
||||
#include <xrpl/protocol/detail/transactions.macro>
|
||||
@@ -1845,7 +1845,7 @@ class Delegate_test : public beast::unit_test::suite
|
||||
// DO NOT modify expectedDelegableCount unless all scenarios, including
|
||||
// edge cases, have been fully tested and verified.
|
||||
// ====================================================================
|
||||
std::size_t const expectedDelegableCount = 75;
|
||||
std::size_t const expectedDelegableCount = 57;
|
||||
|
||||
BEAST_EXPECTS(
|
||||
delegableCount == expectedDelegableCount,
|
||||
|
||||
@@ -16,7 +16,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test default constructor
|
||||
{
|
||||
STDataType dt1(sf);
|
||||
STDataType const dt1(sf);
|
||||
BEAST_EXPECT(dt1.getInnerSType() == STI_NOTPRESENT);
|
||||
BEAST_EXPECT(dt1.getSType() == STI_DATATYPE);
|
||||
BEAST_EXPECT(dt1.getFName() == sf);
|
||||
@@ -24,7 +24,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test constructor with SerializedTypeID
|
||||
{
|
||||
STDataType dt2(sf, STI_UINT32);
|
||||
STDataType const dt2(sf, STI_UINT32);
|
||||
BEAST_EXPECT(dt2.getInnerSType() == STI_UINT32);
|
||||
BEAST_EXPECT(!dt2.isDefault());
|
||||
}
|
||||
@@ -34,7 +34,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
Serializer s;
|
||||
s.add16(STI_UINT64);
|
||||
SerialIter sit(s.slice());
|
||||
STDataType dt3(sit, sf);
|
||||
STDataType const dt3(sit, sf);
|
||||
BEAST_EXPECT(dt3.getInnerSType() == STI_UINT64);
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test copy
|
||||
{
|
||||
STDataType original(sf, STI_UINT32);
|
||||
STDataType const original(sf, STI_UINT32);
|
||||
|
||||
// Use aligned storage for placement new
|
||||
alignas(STDataType) char buffer[sizeof(STDataType)];
|
||||
@@ -96,7 +96,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
std::string expectedHex;
|
||||
};
|
||||
|
||||
TypeTest tests[] = {
|
||||
TypeTest const tests[] = {
|
||||
{STI_UINT16, "0001"},
|
||||
{STI_UINT32, "0002"},
|
||||
{STI_UINT64, "0003"},
|
||||
@@ -137,22 +137,22 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test equivalent objects
|
||||
{
|
||||
STDataType dt1(sf1, STI_UINT32);
|
||||
STDataType dt2(sf1, STI_UINT32);
|
||||
STDataType const dt1(sf1, STI_UINT32);
|
||||
STDataType const dt2(sf1, STI_UINT32);
|
||||
BEAST_EXPECT(dt1.isEquivalent(dt2));
|
||||
}
|
||||
|
||||
// Test non-equivalent objects (different inner types)
|
||||
{
|
||||
STDataType dt1(sf1, STI_UINT32);
|
||||
STDataType dt2(sf1, STI_UINT64);
|
||||
STDataType const dt1(sf1, STI_UINT32);
|
||||
STDataType const dt2(sf1, STI_UINT64);
|
||||
BEAST_EXPECT(!dt1.isEquivalent(dt2));
|
||||
}
|
||||
|
||||
// Test non-equivalent objects (different default states)
|
||||
{
|
||||
STDataType dt1(sf1);
|
||||
STDataType dt2(sf1, STI_NOTPRESENT);
|
||||
STDataType const dt1(sf1);
|
||||
STDataType const dt2(sf1, STI_NOTPRESENT);
|
||||
// dt1 has default_ = true (implicit from first constructor)
|
||||
// dt2 has default_ = false (set in second constructor)
|
||||
BEAST_EXPECT(!dt1.isEquivalent(dt2));
|
||||
@@ -160,7 +160,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test with non-STDataType object
|
||||
{
|
||||
STDataType dt1(sf1, STI_UINT32);
|
||||
STDataType const dt1(sf1, STI_UINT32);
|
||||
// Create a dummy STBase-derived object for comparison
|
||||
// Since we can't easily create other STBase types here,
|
||||
// we'll test that isEquivalent returns false for nullptr cast
|
||||
@@ -199,7 +199,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
DummySTBase dummy;
|
||||
DummySTBase const dummy;
|
||||
BEAST_EXPECT(!dt1.isEquivalent(dummy));
|
||||
}
|
||||
}
|
||||
@@ -213,14 +213,14 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test default state
|
||||
{
|
||||
STDataType dt1(sf);
|
||||
STDataType const dt1(sf);
|
||||
// First constructor doesn't set default_ explicitly,
|
||||
// so it should be true (member initialization)
|
||||
BEAST_EXPECT(dt1.isDefault());
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt2(sf, STI_UINT32);
|
||||
STDataType const dt2(sf, STI_UINT32);
|
||||
BEAST_EXPECT(!dt2.isDefault());
|
||||
}
|
||||
}
|
||||
@@ -234,78 +234,78 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test known types
|
||||
{
|
||||
STDataType dt(sf, STI_UINT8);
|
||||
STDataType const dt(sf, STI_UINT8);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT8}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT16);
|
||||
STDataType const dt(sf, STI_UINT16);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT16}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT32);
|
||||
STDataType const dt(sf, STI_UINT32);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT32}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT64);
|
||||
STDataType const dt(sf, STI_UINT64);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT64}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT128);
|
||||
STDataType const dt(sf, STI_UINT128);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT128}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT160);
|
||||
STDataType const dt(sf, STI_UINT160);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT160}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT192);
|
||||
STDataType const dt(sf, STI_UINT192);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT192}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_UINT256);
|
||||
STDataType const dt(sf, STI_UINT256);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: UINT256}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_VL);
|
||||
STDataType const dt(sf, STI_VL);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: VL}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_ACCOUNT);
|
||||
STDataType const dt(sf, STI_ACCOUNT);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: ACCOUNT}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_AMOUNT);
|
||||
STDataType const dt(sf, STI_AMOUNT);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: AMOUNT}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_ISSUE);
|
||||
STDataType const dt(sf, STI_ISSUE);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: ISSUE}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_CURRENCY);
|
||||
STDataType const dt(sf, STI_CURRENCY);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: CURRENCY}");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_NUMBER);
|
||||
STDataType const dt(sf, STI_NUMBER);
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: NUMBER}");
|
||||
}
|
||||
|
||||
// Test unknown type (should return numeric string)
|
||||
{
|
||||
STDataType dt(sf, static_cast<SerializedTypeID>(999));
|
||||
STDataType const dt(sf, static_cast<SerializedTypeID>(999));
|
||||
BEAST_EXPECT(dt.getText() == "STDataType{InnerType: 999}");
|
||||
}
|
||||
}
|
||||
@@ -319,21 +319,21 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test JSON output for various types
|
||||
{
|
||||
STDataType dt(sf, STI_UINT32);
|
||||
STDataType const dt(sf, STI_UINT32);
|
||||
Json::Value json = dt.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json.isObject());
|
||||
BEAST_EXPECT(json[jss::type].asString() == "UINT32");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_AMOUNT);
|
||||
STDataType const dt(sf, STI_AMOUNT);
|
||||
Json::Value json = dt.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json.isObject());
|
||||
BEAST_EXPECT(json[jss::type].asString() == "AMOUNT");
|
||||
}
|
||||
|
||||
{
|
||||
STDataType dt(sf, STI_ACCOUNT);
|
||||
STDataType const dt(sf, STI_ACCOUNT);
|
||||
Json::Value json = dt.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json.isObject());
|
||||
BEAST_EXPECT(json[jss::type].asString() == "ACCOUNT");
|
||||
@@ -341,7 +341,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Test unknown type
|
||||
{
|
||||
STDataType dt(sf, static_cast<SerializedTypeID>(999));
|
||||
STDataType const dt(sf, static_cast<SerializedTypeID>(999));
|
||||
Json::Value json = dt.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json.isObject());
|
||||
BEAST_EXPECT(json[jss::type].asString() == "999");
|
||||
@@ -359,98 +359,98 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT8";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT8);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT16";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT16);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT32";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT32);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT64";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT64);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT128";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT128);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT160";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT160);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT192";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT192);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "UINT256";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_UINT256);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "VL";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_VL);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "ACCOUNT";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_ACCOUNT);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "AMOUNT";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_AMOUNT);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "ISSUE";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_ISSUE);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "CURRENCY";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_CURRENCY);
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value v;
|
||||
v[jss::type] = "NUMBER";
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(dt.getInnerSType() == STI_NUMBER);
|
||||
}
|
||||
|
||||
@@ -458,10 +458,10 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Non-object JSON should throw
|
||||
{
|
||||
Json::Value v = "not an object";
|
||||
Json::Value const v = "not an object";
|
||||
try
|
||||
{
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(false); // Should not reach here
|
||||
}
|
||||
catch (std::runtime_error const& e)
|
||||
@@ -476,7 +476,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
v[jss::type] = "UNKNOWN_TYPE";
|
||||
try
|
||||
{
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(false); // Should not reach here
|
||||
}
|
||||
catch (std::runtime_error const& e)
|
||||
@@ -492,7 +492,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
v[jss::type] = "";
|
||||
try
|
||||
{
|
||||
STDataType dt = dataTypeFromJson(sf, v);
|
||||
STDataType const dt = dataTypeFromJson(sf, v);
|
||||
BEAST_EXPECT(false); // Should not reach here
|
||||
}
|
||||
catch (std::runtime_error const& e)
|
||||
@@ -527,7 +527,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
STI_NUMBER})
|
||||
{
|
||||
// Create original
|
||||
STDataType original(sf, typeId);
|
||||
STDataType const original(sf, typeId);
|
||||
|
||||
// Serialize
|
||||
Serializer s;
|
||||
@@ -535,7 +535,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
// Deserialize
|
||||
SerialIter sit(s.slice());
|
||||
STDataType deserialized(sit, sf);
|
||||
STDataType const deserialized(sit, sf);
|
||||
|
||||
// Compare
|
||||
BEAST_EXPECT(deserialized.getInnerSType() == typeId);
|
||||
@@ -550,7 +550,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
auto const& sf = sfParameterType;
|
||||
|
||||
std::vector<std::string> typeStrings = {
|
||||
std::vector<std::string> const typeStrings = {
|
||||
"UINT8",
|
||||
"UINT16",
|
||||
"UINT32",
|
||||
@@ -571,7 +571,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
// Create from JSON
|
||||
Json::Value input;
|
||||
input[jss::type] = typeStr;
|
||||
STDataType dt = dataTypeFromJson(sf, input);
|
||||
STDataType const dt = dataTypeFromJson(sf, input);
|
||||
|
||||
// Convert back to JSON
|
||||
Json::Value output = dt.getJson(JsonOptions::none);
|
||||
@@ -594,7 +594,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
std::string expected;
|
||||
};
|
||||
|
||||
TypeStringTest tests[] = {
|
||||
TypeStringTest const tests[] = {
|
||||
{STI_UINT8, "UINT8"},
|
||||
{STI_UINT16, "UINT16"},
|
||||
{STI_UINT32, "UINT32"},
|
||||
@@ -614,7 +614,7 @@ struct STDataType_test : public beast::unit_test::suite
|
||||
|
||||
for (auto const& test : tests)
|
||||
{
|
||||
STDataType dt(sf, test.type);
|
||||
STDataType const dt(sf, test.type);
|
||||
BEAST_EXPECT(dt.getInnerTypeString() == test.expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
// Default constructor
|
||||
{
|
||||
STData data(sf);
|
||||
STData const data(sf);
|
||||
BEAST_EXPECT(data.getSType() == STI_DATA);
|
||||
BEAST_EXPECT(data.isDefault());
|
||||
}
|
||||
@@ -25,82 +25,82 @@ struct STData_test : public beast::unit_test::suite
|
||||
// Type-specific constructors
|
||||
{
|
||||
// UINT8
|
||||
STData data_u8(sf, static_cast<std::uint8_t>(8));
|
||||
STData const data_u8(sf, static_cast<std::uint8_t>(8));
|
||||
BEAST_EXPECT(data_u8.getFieldU8() == 8);
|
||||
BEAST_EXPECT(data_u8.getInnerTypeString() == "UINT8");
|
||||
BEAST_EXPECT(data_u8.isDefault());
|
||||
|
||||
// UINT16
|
||||
STData data_u16(sf, static_cast<std::uint16_t>(16));
|
||||
STData const data_u16(sf, static_cast<std::uint16_t>(16));
|
||||
BEAST_EXPECT(data_u16.getFieldU16() == 16);
|
||||
BEAST_EXPECT(data_u16.getInnerTypeString() == "UINT16");
|
||||
|
||||
// UINT32
|
||||
STData data_u32(sf, static_cast<std::uint32_t>(32));
|
||||
STData const data_u32(sf, static_cast<std::uint32_t>(32));
|
||||
BEAST_EXPECT(data_u32.getFieldU32() == 32);
|
||||
BEAST_EXPECT(data_u32.getInnerTypeString() == "UINT32");
|
||||
|
||||
// UINT64
|
||||
STData data_u64(sf, static_cast<std::uint64_t>(64));
|
||||
STData const data_u64(sf, static_cast<std::uint64_t>(64));
|
||||
BEAST_EXPECT(data_u64.getFieldU64() == 64);
|
||||
BEAST_EXPECT(data_u64.getInnerTypeString() == "UINT64");
|
||||
|
||||
// UINT128
|
||||
uint128 val128 = uint128(1);
|
||||
STData data_u128(sf, val128);
|
||||
uint128 const val128 = uint128(1);
|
||||
STData const data_u128(sf, val128);
|
||||
BEAST_EXPECT(data_u128.getFieldH128() == val128);
|
||||
BEAST_EXPECT(data_u128.getInnerTypeString() == "UINT128");
|
||||
|
||||
// UINT160
|
||||
uint160 val160 = uint160(1);
|
||||
STData data_u160(sf, val160);
|
||||
uint160 const val160 = uint160(1);
|
||||
STData const data_u160(sf, val160);
|
||||
BEAST_EXPECT(data_u160.getFieldH160() == val160);
|
||||
BEAST_EXPECT(data_u160.getInnerTypeString() == "UINT160");
|
||||
|
||||
// UINT192
|
||||
uint192 val192 = uint192(1);
|
||||
STData data_u192(sf, val192);
|
||||
uint192 const val192 = uint192(1);
|
||||
STData const data_u192(sf, val192);
|
||||
BEAST_EXPECT(data_u192.getFieldH192() == val192);
|
||||
BEAST_EXPECT(data_u192.getInnerTypeString() == "UINT192");
|
||||
|
||||
// UINT256
|
||||
uint256 val256 = uint256(1);
|
||||
STData data_u256(sf, val256);
|
||||
uint256 const val256 = uint256(1);
|
||||
STData const data_u256(sf, val256);
|
||||
BEAST_EXPECT(data_u256.getFieldH256() == val256);
|
||||
BEAST_EXPECT(data_u256.getInnerTypeString() == "UINT256");
|
||||
|
||||
// Blob
|
||||
Blob blob = strUnHex("DEADBEEFCAFEBABE").value();
|
||||
STData data_blob(sf, blob);
|
||||
Blob const blob = strUnHex("DEADBEEFCAFEBABE").value();
|
||||
STData const data_blob(sf, blob);
|
||||
BEAST_EXPECT(data_blob.getFieldVL() == blob);
|
||||
BEAST_EXPECT(data_blob.getInnerTypeString() == "VL");
|
||||
|
||||
// Slice
|
||||
std::string test_str = "Hello World";
|
||||
Slice slice(test_str.data(), test_str.size());
|
||||
STData data_slice(sf, slice);
|
||||
Blob expected_blob(test_str.begin(), test_str.end());
|
||||
Slice const slice(test_str.data(), test_str.size());
|
||||
STData const data_slice(sf, slice);
|
||||
Blob const expected_blob(test_str.begin(), test_str.end());
|
||||
BEAST_EXPECT(data_slice.getFieldVL() == expected_blob);
|
||||
|
||||
// AccountID
|
||||
AccountID account(0x123456789ABCDEF0);
|
||||
STData data_account(sf, account);
|
||||
AccountID const account(0x123456789ABCDEF0);
|
||||
STData const data_account(sf, account);
|
||||
BEAST_EXPECT(data_account.getAccountID() == account);
|
||||
BEAST_EXPECT(data_account.getInnerTypeString() == "ACCOUNT");
|
||||
|
||||
// STAmount (Native)
|
||||
STAmount amount_native(1000);
|
||||
STData data_amount_native(sf, amount_native);
|
||||
STAmount const amount_native(1000);
|
||||
STData const data_amount_native(sf, amount_native);
|
||||
BEAST_EXPECT(data_amount_native.getFieldAmount() == amount_native);
|
||||
BEAST_EXPECT(data_amount_native.getInnerTypeString() == "AMOUNT");
|
||||
|
||||
// STAmount (IOU)
|
||||
IOUAmount iou_amount(5000);
|
||||
IOUAmount const iou_amount(5000);
|
||||
Issue const usd(
|
||||
Currency(0x5553440000000000),
|
||||
parseBase58<AccountID>("rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn").value());
|
||||
STAmount amount_iou(iou_amount, usd);
|
||||
STData data_amount_iou(sf, amount_iou);
|
||||
STAmount const amount_iou(iou_amount, usd);
|
||||
STData const data_amount_iou(sf, amount_iou);
|
||||
BEAST_EXPECT(data_amount_iou.getFieldAmount() == amount_iou);
|
||||
}
|
||||
}
|
||||
@@ -115,14 +115,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
// Test each type's serialization and deserialization round-trip
|
||||
{
|
||||
// UINT8
|
||||
std::uint8_t original_u8 = 8;
|
||||
STData data_u8(sf, original_u8);
|
||||
std::uint8_t const original_u8 = 8;
|
||||
STData const data_u8(sf, original_u8);
|
||||
|
||||
Serializer s;
|
||||
data_u8.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u8(sit, sf);
|
||||
STData const deserialized_u8(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u8.getFieldU8() == original_u8);
|
||||
BEAST_EXPECT(deserialized_u8.getInnerTypeString() == "UINT8");
|
||||
@@ -130,14 +130,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT16
|
||||
std::uint16_t original_u16 = 16;
|
||||
STData data_u16(sf, original_u16);
|
||||
std::uint16_t const original_u16 = 16;
|
||||
STData const data_u16(sf, original_u16);
|
||||
|
||||
Serializer s;
|
||||
data_u16.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u16(sit, sf);
|
||||
STData const deserialized_u16(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u16.getFieldU16() == original_u16);
|
||||
BEAST_EXPECT(deserialized_u16.getInnerTypeString() == "UINT16");
|
||||
@@ -145,14 +145,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT32
|
||||
std::uint32_t original_u32 = 32;
|
||||
STData data_u32(sf, original_u32);
|
||||
std::uint32_t const original_u32 = 32;
|
||||
STData const data_u32(sf, original_u32);
|
||||
|
||||
Serializer s;
|
||||
data_u32.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u32(sit, sf);
|
||||
STData const deserialized_u32(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u32.getFieldU32() == original_u32);
|
||||
BEAST_EXPECT(deserialized_u32.getInnerTypeString() == "UINT32");
|
||||
@@ -160,14 +160,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT64
|
||||
std::uint64_t original_u64 = 64;
|
||||
STData data_u64(sf, original_u64);
|
||||
std::uint64_t const original_u64 = 64;
|
||||
STData const data_u64(sf, original_u64);
|
||||
|
||||
Serializer s;
|
||||
data_u64.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u64(sit, sf);
|
||||
STData const deserialized_u64(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u64.getFieldU64() == original_u64);
|
||||
BEAST_EXPECT(deserialized_u64.getInnerTypeString() == "UINT64");
|
||||
@@ -175,14 +175,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT128
|
||||
uint128 original_u128 = uint128(1);
|
||||
STData data_u128(sf, original_u128);
|
||||
uint128 const original_u128 = uint128(1);
|
||||
STData const data_u128(sf, original_u128);
|
||||
|
||||
Serializer s;
|
||||
data_u128.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u128(sit, sf);
|
||||
STData const deserialized_u128(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u128.getFieldH128() == original_u128);
|
||||
BEAST_EXPECT(deserialized_u128.getInnerTypeString() == "UINT128");
|
||||
@@ -190,14 +190,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT160
|
||||
uint160 original_u160 = uint160(1);
|
||||
STData data_u160(sf, original_u160);
|
||||
uint160 const original_u160 = uint160(1);
|
||||
STData const data_u160(sf, original_u160);
|
||||
|
||||
Serializer s;
|
||||
data_u160.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u160(sit, sf);
|
||||
STData const deserialized_u160(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u160.getFieldH160() == original_u160);
|
||||
BEAST_EXPECT(deserialized_u160.getInnerTypeString() == "UINT160");
|
||||
@@ -205,14 +205,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT192
|
||||
uint192 original_u192 = uint192(1);
|
||||
STData data_u192(sf, original_u192);
|
||||
uint192 const original_u192 = uint192(1);
|
||||
STData const data_u192(sf, original_u192);
|
||||
|
||||
Serializer s;
|
||||
data_u192.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u192(sit, sf);
|
||||
STData const deserialized_u192(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u192.getFieldH192() == original_u192);
|
||||
BEAST_EXPECT(deserialized_u192.getInnerTypeString() == "UINT192");
|
||||
@@ -220,14 +220,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT256
|
||||
uint256 original_u256 = uint256(1);
|
||||
STData data_u256(sf, original_u256);
|
||||
uint256 const original_u256 = uint256(1);
|
||||
STData const data_u256(sf, original_u256);
|
||||
|
||||
Serializer s;
|
||||
data_u256.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_u256(sit, sf);
|
||||
STData const deserialized_u256(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_u256.getFieldH256() == original_u256);
|
||||
BEAST_EXPECT(deserialized_u256.getInnerTypeString() == "UINT256");
|
||||
@@ -235,14 +235,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// VL (Variable Length)
|
||||
Blob original_blob = strUnHex("DEADBEEFCAFEBABE1234567890ABCDEF").value();
|
||||
STData data_vl(sf, original_blob);
|
||||
Blob const original_blob = strUnHex("DEADBEEFCAFEBABE1234567890ABCDEF").value();
|
||||
STData const data_vl(sf, original_blob);
|
||||
|
||||
Serializer s;
|
||||
data_vl.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_vl(sit, sf);
|
||||
STData const deserialized_vl(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_vl.getFieldVL() == original_blob);
|
||||
BEAST_EXPECT(deserialized_vl.getInnerTypeString() == "VL");
|
||||
@@ -250,14 +250,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// ACCOUNT
|
||||
AccountID original_account(0xFEDCBA9876543210);
|
||||
STData data_account(sf, original_account);
|
||||
AccountID const original_account(0xFEDCBA9876543210);
|
||||
STData const data_account(sf, original_account);
|
||||
|
||||
Serializer s;
|
||||
data_account.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_account(sit, sf);
|
||||
STData const deserialized_account(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_account.getAccountID() == original_account);
|
||||
BEAST_EXPECT(deserialized_account.getInnerTypeString() == "ACCOUNT");
|
||||
@@ -265,14 +265,14 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// AMOUNT (Native)
|
||||
STAmount original_amount(99999);
|
||||
STData data_amount(sf, original_amount);
|
||||
STAmount const original_amount(99999);
|
||||
STData const data_amount(sf, original_amount);
|
||||
|
||||
Serializer s;
|
||||
data_amount.add(s);
|
||||
|
||||
SerialIter sit(s.slice());
|
||||
STData deserialized_amount(sit, sf);
|
||||
STData const deserialized_amount(sit, sf);
|
||||
|
||||
BEAST_EXPECT(deserialized_amount.getFieldAmount() == original_amount);
|
||||
BEAST_EXPECT(deserialized_amount.getInnerTypeString() == "AMOUNT");
|
||||
@@ -302,7 +302,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
// Test all setter/getter combinations
|
||||
{
|
||||
// UINT8
|
||||
unsigned char val_u8 = 8;
|
||||
unsigned char const val_u8 = 8;
|
||||
data.setFieldU8(val_u8);
|
||||
BEAST_EXPECT(data.getFieldU8() == val_u8);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT8");
|
||||
@@ -310,7 +310,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT16
|
||||
std::uint16_t val_u16 = 16;
|
||||
std::uint16_t const val_u16 = 16;
|
||||
data.setFieldU16(val_u16);
|
||||
BEAST_EXPECT(data.getFieldU16() == val_u16);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT16");
|
||||
@@ -318,7 +318,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT32
|
||||
std::uint32_t val_u32 = 32;
|
||||
std::uint32_t const val_u32 = 32;
|
||||
data.setFieldU32(val_u32);
|
||||
BEAST_EXPECT(data.getFieldU32() == val_u32);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT32");
|
||||
@@ -326,7 +326,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT64
|
||||
std::uint64_t val_u64 = 64;
|
||||
std::uint64_t const val_u64 = 64;
|
||||
data.setFieldU64(val_u64);
|
||||
BEAST_EXPECT(data.getFieldU64() == val_u64);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT64");
|
||||
@@ -334,7 +334,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT128
|
||||
uint128 val_u128 = uint128(1);
|
||||
uint128 const val_u128 = uint128(1);
|
||||
data.setFieldH128(val_u128);
|
||||
BEAST_EXPECT(data.getFieldH128() == val_u128);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT128");
|
||||
@@ -342,7 +342,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT160
|
||||
uint160 val_u160 = uint160(1);
|
||||
uint160 const val_u160 = uint160(1);
|
||||
data.setFieldH160(val_u160);
|
||||
BEAST_EXPECT(data.getFieldH160() == val_u160);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT160");
|
||||
@@ -350,7 +350,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT192
|
||||
uint192 val_u192 = uint192(1);
|
||||
uint192 const val_u192 = uint192(1);
|
||||
data.setFieldH192(val_u192);
|
||||
BEAST_EXPECT(data.getFieldH192() == val_u192);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT192");
|
||||
@@ -358,7 +358,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT256
|
||||
uint256 val_u256 = uint256(1);
|
||||
uint256 const val_u256 = uint256(1);
|
||||
data.setFieldH256(val_u256);
|
||||
BEAST_EXPECT(data.getFieldH256() == val_u256);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "UINT256");
|
||||
@@ -366,7 +366,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// VL (Variable Length) - Blob
|
||||
Blob val_blob = strUnHex("0102030405060708090A0B0C0D0E0F10").value();
|
||||
Blob const val_blob = strUnHex("0102030405060708090A0B0C0D0E0F10").value();
|
||||
data.setFieldVL(val_blob);
|
||||
BEAST_EXPECT(data.getFieldVL() == val_blob);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "VL");
|
||||
@@ -375,16 +375,16 @@ struct STData_test : public beast::unit_test::suite
|
||||
{
|
||||
// VL (Variable Length) - Slice
|
||||
std::string test_str = "Test String for Slice";
|
||||
Slice val_slice(test_str.data(), test_str.size());
|
||||
Slice const val_slice(test_str.data(), test_str.size());
|
||||
data.setFieldVL(val_slice);
|
||||
Blob expected_blob(test_str.begin(), test_str.end());
|
||||
Blob const expected_blob(test_str.begin(), test_str.end());
|
||||
BEAST_EXPECT(data.getFieldVL() == expected_blob);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "VL");
|
||||
}
|
||||
|
||||
{
|
||||
// ACCOUNT
|
||||
AccountID val_account(0x123456789ABCDEF0);
|
||||
AccountID const val_account(0x123456789ABCDEF0);
|
||||
data.setAccountID(val_account);
|
||||
BEAST_EXPECT(data.getAccountID() == val_account);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "ACCOUNT");
|
||||
@@ -392,7 +392,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// AMOUNT
|
||||
STAmount val_amount(777777);
|
||||
STAmount const val_amount(777777);
|
||||
data.setFieldAmount(val_amount);
|
||||
BEAST_EXPECT(data.getFieldAmount() == val_amount);
|
||||
BEAST_EXPECT(data.getInnerTypeString() == "AMOUNT");
|
||||
@@ -421,7 +421,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
// Test JSON serialization for each type
|
||||
{
|
||||
// UINT8
|
||||
STData data_u8(sf, static_cast<unsigned char>(8));
|
||||
STData const data_u8(sf, static_cast<unsigned char>(8));
|
||||
Json::Value json_u8 = data_u8.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u8[jss::type].asString() == "UINT8");
|
||||
BEAST_EXPECT(json_u8[jss::value].asUInt() == 8);
|
||||
@@ -429,7 +429,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT16
|
||||
STData data_u16(sf, static_cast<std::uint16_t>(16));
|
||||
STData const data_u16(sf, static_cast<std::uint16_t>(16));
|
||||
Json::Value json_u16 = data_u16.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u16[jss::type].asString() == "UINT16");
|
||||
BEAST_EXPECT(json_u16[jss::value].asUInt() == 16);
|
||||
@@ -437,7 +437,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT32
|
||||
STData data_u32(sf, static_cast<std::uint32_t>(32));
|
||||
STData const data_u32(sf, static_cast<std::uint32_t>(32));
|
||||
Json::Value json_u32 = data_u32.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u32[jss::type].asString() == "UINT32");
|
||||
BEAST_EXPECT(json_u32[jss::value].asUInt() == 32);
|
||||
@@ -445,7 +445,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT64
|
||||
STData data_u64(sf, static_cast<std::uint64_t>(64));
|
||||
STData const data_u64(sf, static_cast<std::uint64_t>(64));
|
||||
Json::Value json_u64 = data_u64.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u64[jss::type].asString() == "UINT64");
|
||||
BEAST_EXPECT(json_u64[jss::value].asString() == "40");
|
||||
@@ -453,8 +453,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT128
|
||||
uint128 val_u128 = uint128(1);
|
||||
STData data_u128(sf, val_u128);
|
||||
uint128 const val_u128 = uint128(1);
|
||||
STData const data_u128(sf, val_u128);
|
||||
Json::Value json_u128 = data_u128.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u128[jss::type].asString() == "UINT128");
|
||||
BEAST_EXPECT(json_u128[jss::value].asString() == "00000000000000000000000000000001");
|
||||
@@ -462,8 +462,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT160
|
||||
uint160 val_u160 = uint160(1);
|
||||
STData data_u160(sf, val_u160);
|
||||
uint160 const val_u160 = uint160(1);
|
||||
STData const data_u160(sf, val_u160);
|
||||
Json::Value json_u160 = data_u160.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u160[jss::type].asString() == "UINT160");
|
||||
BEAST_EXPECT(
|
||||
@@ -472,8 +472,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT192
|
||||
uint192 val_u192 = uint192(1);
|
||||
STData data_u192(sf, val_u192);
|
||||
uint192 const val_u192 = uint192(1);
|
||||
STData const data_u192(sf, val_u192);
|
||||
Json::Value json_u192 = data_u192.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u192[jss::type].asString() == "UINT192");
|
||||
BEAST_EXPECT(
|
||||
@@ -483,8 +483,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// UINT256
|
||||
uint256 val_u256 = uint256(1);
|
||||
STData data_u256(sf, val_u256);
|
||||
uint256 const val_u256 = uint256(1);
|
||||
STData const data_u256(sf, val_u256);
|
||||
Json::Value json_u256 = data_u256.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_u256[jss::type].asString() == "UINT256");
|
||||
BEAST_EXPECT(
|
||||
@@ -495,8 +495,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// VL
|
||||
Blob blob = strUnHex("DEADBEEF").value();
|
||||
STData data_vl(sf, blob);
|
||||
Blob const blob = strUnHex("DEADBEEF").value();
|
||||
STData const data_vl(sf, blob);
|
||||
Json::Value json_vl = data_vl.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_vl[jss::type].asString() == "VL");
|
||||
BEAST_EXPECT(json_vl[jss::value].asString() == "DEADBEEF");
|
||||
@@ -504,8 +504,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// ACCOUNT
|
||||
AccountID account(0x123456789ABCDEF0);
|
||||
STData data_account(sf, account);
|
||||
AccountID const account(0x123456789ABCDEF0);
|
||||
STData const data_account(sf, account);
|
||||
Json::Value json_account = data_account.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_account[jss::type].asString() == "ACCOUNT");
|
||||
BEAST_EXPECT(json_account[jss::value].asString() == "rrrrrrrrrrrrrLveWzSkxhcH3hGw6");
|
||||
@@ -513,8 +513,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
// AMOUNT
|
||||
STAmount amount(1000);
|
||||
STData data_amount(sf, amount);
|
||||
STAmount const amount(1000);
|
||||
STData const data_amount(sf, amount);
|
||||
Json::Value json_amount = data_amount.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(json_amount[jss::type].asString() == "AMOUNT");
|
||||
BEAST_EXPECT(json_amount[jss::value].asString() == "1000");
|
||||
@@ -547,7 +547,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_u8[jss::type] = "UINT8";
|
||||
json_u8[jss::value] = 8;
|
||||
|
||||
STData data_u8 = dataFromJson(sf, json_u8);
|
||||
STData const data_u8 = dataFromJson(sf, json_u8);
|
||||
BEAST_EXPECT(data_u8.getFieldU8() == 8);
|
||||
BEAST_EXPECT(data_u8.getInnerTypeString() == "UINT8");
|
||||
}
|
||||
@@ -558,7 +558,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_u16[jss::type] = "UINT16";
|
||||
json_u16[jss::value] = 16;
|
||||
|
||||
STData data_u16 = dataFromJson(sf, json_u16);
|
||||
STData const data_u16 = dataFromJson(sf, json_u16);
|
||||
BEAST_EXPECT(data_u16.getFieldU16() == 16);
|
||||
BEAST_EXPECT(data_u16.getInnerTypeString() == "UINT16");
|
||||
}
|
||||
@@ -569,7 +569,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_u32[jss::type] = "UINT32";
|
||||
json_u32[jss::value] = 32;
|
||||
|
||||
STData data_u32 = dataFromJson(sf, json_u32);
|
||||
STData const data_u32 = dataFromJson(sf, json_u32);
|
||||
BEAST_EXPECT(data_u32.getFieldU32() == 32);
|
||||
BEAST_EXPECT(data_u32.getInnerTypeString() == "UINT32");
|
||||
}
|
||||
@@ -579,7 +579,7 @@ struct STData_test : public beast::unit_test::suite
|
||||
Json::Value json_u64(Json::objectValue);
|
||||
json_u64[jss::type] = "UINT64";
|
||||
json_u64[jss::value] = 64;
|
||||
STData data_u64 = dataFromJson(sf, json_u64);
|
||||
STData const data_u64 = dataFromJson(sf, json_u64);
|
||||
BEAST_EXPECT(data_u64.getFieldU64() == 64);
|
||||
BEAST_EXPECT(data_u64.getInnerTypeString() == "UINT64");
|
||||
}
|
||||
@@ -589,9 +589,9 @@ struct STData_test : public beast::unit_test::suite
|
||||
Json::Value json_u128(Json::objectValue);
|
||||
json_u128[jss::type] = "UINT128";
|
||||
json_u128[jss::value] = "00000000000000000000000000000001";
|
||||
STData data_u128 = dataFromJson(sf, json_u128);
|
||||
STData const data_u128 = dataFromJson(sf, json_u128);
|
||||
uint128 expected;
|
||||
bool ok = expected.parseHex("00000000000000000000000000000001");
|
||||
bool const ok = expected.parseHex("00000000000000000000000000000001");
|
||||
BEAST_EXPECT(ok);
|
||||
BEAST_EXPECT(data_u128.getFieldH128() == expected);
|
||||
BEAST_EXPECT(data_u128.getInnerTypeString() == "UINT128");
|
||||
@@ -602,9 +602,9 @@ struct STData_test : public beast::unit_test::suite
|
||||
Json::Value json_u160(Json::objectValue);
|
||||
json_u160[jss::type] = "UINT160";
|
||||
json_u160[jss::value] = "0000000000000000000000000000000000000001";
|
||||
STData data_u160 = dataFromJson(sf, json_u160);
|
||||
STData const data_u160 = dataFromJson(sf, json_u160);
|
||||
uint160 expected;
|
||||
bool ok = expected.parseHex("0000000000000000000000000000000000000001");
|
||||
bool const ok = expected.parseHex("0000000000000000000000000000000000000001");
|
||||
BEAST_EXPECT(ok);
|
||||
BEAST_EXPECT(data_u160.getFieldH160() == expected);
|
||||
BEAST_EXPECT(data_u160.getInnerTypeString() == "UINT160");
|
||||
@@ -615,9 +615,9 @@ struct STData_test : public beast::unit_test::suite
|
||||
Json::Value json_u192(Json::objectValue);
|
||||
json_u192[jss::type] = "UINT192";
|
||||
json_u192[jss::value] = "000000000000000000000000000000000000000000000001";
|
||||
STData data_u192 = dataFromJson(sf, json_u192);
|
||||
STData const data_u192 = dataFromJson(sf, json_u192);
|
||||
uint192 expected;
|
||||
bool ok = expected.parseHex("000000000000000000000000000000000000000000000001");
|
||||
bool const ok = expected.parseHex("000000000000000000000000000000000000000000000001");
|
||||
BEAST_EXPECT(ok);
|
||||
BEAST_EXPECT(data_u192.getFieldH192() == expected);
|
||||
BEAST_EXPECT(data_u192.getInnerTypeString() == "UINT192");
|
||||
@@ -630,9 +630,9 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_u256[jss::value] =
|
||||
"00000000000000000000000000000000000000000000000000000000000000"
|
||||
"01";
|
||||
STData data_u256 = dataFromJson(sf, json_u256);
|
||||
STData const data_u256 = dataFromJson(sf, json_u256);
|
||||
uint256 expected;
|
||||
bool ok = expected.parseHex(
|
||||
bool const ok = expected.parseHex(
|
||||
"00000000000000000000000000000000000000000000000000000000000000"
|
||||
"01");
|
||||
BEAST_EXPECT(ok);
|
||||
@@ -646,8 +646,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_vl[jss::type] = "VL";
|
||||
json_vl[jss::value] = "DEADBEEFCAFEBABE";
|
||||
|
||||
STData data_vl = dataFromJson(sf, json_vl);
|
||||
Blob expected_blob = strUnHex("DEADBEEFCAFEBABE").value();
|
||||
STData const data_vl = dataFromJson(sf, json_vl);
|
||||
Blob const expected_blob = strUnHex("DEADBEEFCAFEBABE").value();
|
||||
BEAST_EXPECT(data_vl.getFieldVL() == expected_blob);
|
||||
BEAST_EXPECT(data_vl.getInnerTypeString() == "VL");
|
||||
}
|
||||
@@ -658,8 +658,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_account[jss::type] = "ACCOUNT";
|
||||
json_account[jss::value] = "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn";
|
||||
|
||||
STData data_account = dataFromJson(sf, json_account);
|
||||
AccountID expected_account =
|
||||
STData const data_account = dataFromJson(sf, json_account);
|
||||
AccountID const expected_account =
|
||||
parseBase58<AccountID>("rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn").value();
|
||||
BEAST_EXPECT(data_account.getAccountID() == expected_account);
|
||||
BEAST_EXPECT(data_account.getInnerTypeString() == "ACCOUNT");
|
||||
@@ -671,8 +671,8 @@ struct STData_test : public beast::unit_test::suite
|
||||
json_amount[jss::type] = "AMOUNT";
|
||||
json_amount[jss::value] = "1000";
|
||||
|
||||
STData data_amount = dataFromJson(sf, json_amount);
|
||||
STAmount expected_amount(1000);
|
||||
STData const data_amount = dataFromJson(sf, json_amount);
|
||||
STAmount const expected_amount(1000);
|
||||
BEAST_EXPECT(data_amount.getFieldAmount() == expected_amount);
|
||||
BEAST_EXPECT(data_amount.getInnerTypeString() == "AMOUNT");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -32,7 +33,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
testDefaultConstructor()
|
||||
{
|
||||
testcase("Default constructor");
|
||||
STJson json;
|
||||
STJson const json;
|
||||
BEAST_EXPECT(json.isObject());
|
||||
BEAST_EXPECT(!json.isArray());
|
||||
BEAST_EXPECT(json.getMap().empty());
|
||||
@@ -62,7 +63,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
testcase("Move constructor (Object)");
|
||||
STJson::Map map;
|
||||
map["bar"] = std::make_shared<STUInt16>(sfTransactionType, 42);
|
||||
STJson json(std::move(map));
|
||||
STJson const json(std::move(map));
|
||||
BEAST_EXPECT(json.isObject());
|
||||
BEAST_EXPECT(json.getMap().size() == 1);
|
||||
BEAST_EXPECT(std::dynamic_pointer_cast<STUInt16>(json.getMap().at("bar"))->value() == 42);
|
||||
@@ -76,7 +77,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
arr.push_back(std::make_shared<STUInt32>(sfNetworkID, 100));
|
||||
arr.push_back(std::make_shared<STUInt32>(sfNetworkID, 200));
|
||||
|
||||
STJson json(std::move(arr));
|
||||
STJson const json(std::move(arr));
|
||||
BEAST_EXPECT(json.isArray());
|
||||
BEAST_EXPECT(!json.isObject());
|
||||
BEAST_EXPECT(json.arraySize() == 2);
|
||||
@@ -90,12 +91,12 @@ struct STJson_test : public beast::unit_test::suite
|
||||
testTypeChecking()
|
||||
{
|
||||
testcase("Type checking methods");
|
||||
STJson objJson;
|
||||
STJson const objJson;
|
||||
BEAST_EXPECT(objJson.isObject());
|
||||
BEAST_EXPECT(!objJson.isArray());
|
||||
BEAST_EXPECT(objJson.getType() == STJson::JsonType::Object);
|
||||
|
||||
STJson arrJson(STJson::Array{});
|
||||
STJson const arrJson(STJson::Array{});
|
||||
BEAST_EXPECT(arrJson.isArray());
|
||||
BEAST_EXPECT(!arrJson.isObject());
|
||||
BEAST_EXPECT(arrJson.getType() == STJson::JsonType::Array);
|
||||
@@ -469,11 +470,13 @@ struct STJson_test : public beast::unit_test::suite
|
||||
STJson json;
|
||||
json.setObjectField("foo", std::make_shared<STUInt16>(sfTransactionType, 65535));
|
||||
json.setObjectField("bar", nullptr); // test null value
|
||||
json.setNestedObjectField("meta", "version", std::make_shared<STUInt32>(sfNetworkID, 2));
|
||||
|
||||
Json::Value jv = json.getJson(JsonOptions::none);
|
||||
BEAST_EXPECT(jv.isObject());
|
||||
BEAST_EXPECT(jv["foo"].asUInt() == 65535);
|
||||
BEAST_EXPECT(jv["bar"].isNull());
|
||||
BEAST_EXPECT(jv[strHex(std::string{"foo"})].asUInt() == 65535);
|
||||
BEAST_EXPECT(jv[strHex(std::string{"bar"})].isNull());
|
||||
BEAST_EXPECT(jv[strHex(std::string{"meta"})][strHex(std::string{"version"})].asUInt() == 2);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -631,7 +634,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
{
|
||||
STJson json;
|
||||
// XRP amount
|
||||
STAmount xrp(sfAmount, static_cast<std::int64_t>(123456789u));
|
||||
STAmount const xrp(sfAmount, static_cast<std::int64_t>(123456789u));
|
||||
json.setObjectField("amount", std::make_shared<STAmount>(xrp));
|
||||
Serializer s;
|
||||
json.add(s);
|
||||
@@ -661,7 +664,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
{
|
||||
STJson json;
|
||||
// Use a known AccountID (20 bytes)
|
||||
AccountID acct = AccountID{};
|
||||
AccountID const acct = AccountID{};
|
||||
json.setObjectField("acct", std::make_shared<STAccount>(sfAccount, acct));
|
||||
Serializer s;
|
||||
json.add(s);
|
||||
@@ -690,7 +693,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
{
|
||||
STJson innerJson;
|
||||
// XRP amount
|
||||
STAmount xrp(sfAmount, static_cast<std::int64_t>(123456789u));
|
||||
STAmount const xrp(sfAmount, static_cast<std::int64_t>(123456789u));
|
||||
innerJson.setObjectField("amount", std::make_shared<STAmount>(xrp));
|
||||
|
||||
STJson json;
|
||||
@@ -713,7 +716,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
|
||||
// Empty object
|
||||
{
|
||||
STJson json;
|
||||
STJson const json;
|
||||
Serializer s;
|
||||
json.add(s);
|
||||
auto parsed = STJson::fromBlob(s.peekData().data(), s.peekData().size());
|
||||
@@ -723,7 +726,7 @@ struct STJson_test : public beast::unit_test::suite
|
||||
|
||||
// Empty array
|
||||
{
|
||||
STJson json(STJson::Array{});
|
||||
STJson const json(STJson::Array{});
|
||||
Serializer s;
|
||||
json.add(s);
|
||||
auto parsed = STJson::fromBlob(s.peekData().data(), s.peekData().size());
|
||||
@@ -749,14 +752,13 @@ struct STJson_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(*elem1 != nullptr);
|
||||
}
|
||||
|
||||
// Object with null value
|
||||
// Object with null value - getObjectField treats null as absent
|
||||
{
|
||||
STJson json;
|
||||
json.setObjectField("null_field", nullptr);
|
||||
|
||||
auto val = json.getObjectField("null_field");
|
||||
BEAST_EXPECT(val.has_value());
|
||||
BEAST_EXPECT(*val == nullptr);
|
||||
BEAST_EXPECT(!val.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -484,6 +484,9 @@ public:
|
||||
|
||||
if (jv.isMember(jss::extension_size) != isFlagLedger)
|
||||
return false;
|
||||
|
||||
if (jv.isMember(jss::gas_price) != isFlagLedger)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -492,6 +495,9 @@ public:
|
||||
|
||||
if (jv.isMember(jss::extension_size))
|
||||
return false;
|
||||
|
||||
if (jv.isMember(jss::gas_price))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -2278,7 +2278,7 @@ NetworkOPsImp::pubConsensus(ConsensusPhase phase)
|
||||
void
|
||||
NetworkOPsImp::pubContractEvent(std::string const& name, STJson const& event)
|
||||
{
|
||||
std::lock_guard sl(mSubLock);
|
||||
std::lock_guard const sl(mSubLock);
|
||||
|
||||
auto& streamMap = mStreamMaps[sContractEvents];
|
||||
if (!streamMap.empty())
|
||||
@@ -4269,7 +4269,7 @@ NetworkOPsImp::unsubConsensus(std::uint64_t uSeq)
|
||||
bool
|
||||
NetworkOPsImp::subContractEvent(InfoSub::ref isrListener)
|
||||
{
|
||||
std::lock_guard sl(mSubLock);
|
||||
std::lock_guard const sl(mSubLock);
|
||||
return mStreamMaps[sContractEvents].emplace(isrListener->getSeq(), isrListener).second;
|
||||
}
|
||||
|
||||
@@ -4277,7 +4277,7 @@ NetworkOPsImp::subContractEvent(InfoSub::ref isrListener)
|
||||
bool
|
||||
NetworkOPsImp::unsubContractEvent(std::uint64_t uSeq)
|
||||
{
|
||||
std::lock_guard sl(mSubLock);
|
||||
std::lock_guard const sl(mSubLock);
|
||||
return mStreamMaps[sContractEvents].erase(uSeq);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_UINT8: {
|
||||
if (funcParam.getInnerSType() != STI_UINT8)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
uint8_t data = funcParam.getFieldU8();
|
||||
uint8_t const data = funcParam.getFieldU8();
|
||||
return Bytes{data};
|
||||
}
|
||||
case STI_UINT16: {
|
||||
if (funcParam.getInnerSType() != STI_UINT16)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
uint16_t data = funcParam.getFieldU16();
|
||||
uint16_t const data = funcParam.getFieldU16();
|
||||
return Bytes{
|
||||
static_cast<unsigned char>(data & 0xFF),
|
||||
static_cast<unsigned char>((data >> 8) & 0xFF)};
|
||||
@@ -33,7 +33,7 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_UINT32: {
|
||||
if (funcParam.getInnerSType() != STI_UINT32)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
uint32_t data = funcParam.getFieldU32();
|
||||
uint32_t const data = funcParam.getFieldU32();
|
||||
return Bytes{
|
||||
static_cast<unsigned char>(data & 0xFF),
|
||||
static_cast<unsigned char>((data >> 8) & 0xFF),
|
||||
@@ -43,7 +43,7 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_UINT64: {
|
||||
if (funcParam.getInnerSType() != STI_UINT64)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
uint64_t data = funcParam.getFieldU64();
|
||||
uint64_t const data = funcParam.getFieldU64();
|
||||
return Bytes{
|
||||
static_cast<unsigned char>(data & 0xFF),
|
||||
static_cast<unsigned char>((data >> 8) & 0xFF),
|
||||
@@ -95,7 +95,7 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_AMOUNT: {
|
||||
if (funcParam.getInnerSType() != STI_AMOUNT)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
STAmount data = funcParam.getFieldAmount();
|
||||
STAmount const data = funcParam.getFieldAmount();
|
||||
Serializer s;
|
||||
data.add(s);
|
||||
auto const& serialized = s.getData();
|
||||
@@ -104,7 +104,7 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_NUMBER: {
|
||||
if (funcParam.getInnerSType() != STI_NUMBER)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
STNumber data = funcParam.getFieldNumber();
|
||||
STNumber const data = funcParam.getFieldNumber();
|
||||
Serializer s;
|
||||
data.add(s);
|
||||
auto const& serialized = s.getData();
|
||||
@@ -113,7 +113,7 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_ISSUE: {
|
||||
if (funcParam.getInnerSType() != STI_ISSUE)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
STIssue data = funcParam.getFieldIssue();
|
||||
STIssue const data = funcParam.getFieldIssue();
|
||||
Serializer s;
|
||||
data.add(s);
|
||||
auto const& serialized = s.getData();
|
||||
@@ -122,7 +122,7 @@ getFieldBytesFromSTData(xrpl::STData const& funcParam, std::uint32_t stTypeId)
|
||||
case STI_CURRENCY: {
|
||||
if (funcParam.getInnerSType() != STI_CURRENCY)
|
||||
return Unexpected(HostFunctionError::INVALID_PARAMS);
|
||||
STCurrency data = funcParam.getFieldCurrency();
|
||||
STCurrency const data = funcParam.getFieldCurrency();
|
||||
Serializer s;
|
||||
data.add(s);
|
||||
auto const& serialized = s.getData();
|
||||
@@ -198,12 +198,12 @@ getDataOrCache(ContractContext& contractCtx, AccountID const& account)
|
||||
if (dataSle)
|
||||
{
|
||||
// Return the STJson from the SLE
|
||||
STJson data = dataSle->getFieldJson(sfContractJson);
|
||||
STJson const data = dataSle->getFieldJson(sfContractJson);
|
||||
return {data.isObject(), data};
|
||||
}
|
||||
|
||||
// Return New STJson if not found
|
||||
STJson data;
|
||||
STJson const data;
|
||||
return {true, data};
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ setDataCache(
|
||||
return HostFunctionError::INVALID_ACCOUNT;
|
||||
}
|
||||
|
||||
uint32_t maxDataModifications = 1000u;
|
||||
uint32_t const maxDataModifications = 1000u;
|
||||
|
||||
if (modified && dataMap.modifiedCount >= maxDataModifications)
|
||||
{
|
||||
@@ -243,7 +243,7 @@ setDataCache(
|
||||
if (dataMap.find(account) == dataMap.end())
|
||||
{
|
||||
auto const& fees = contractCtx.applyCtx.view().fees();
|
||||
STAmount bal = sleAccount->getFieldAmount(sfBalance);
|
||||
STAmount const bal = sleAccount->getFieldAmount(sfBalance);
|
||||
|
||||
int64_t availableForReserves =
|
||||
bal.xrp().drops() - fees.accountReserve(sleAccount->getFieldU32(sfOwnerCount)).drops();
|
||||
@@ -465,7 +465,7 @@ ContractHostFunctionsImpl::setDataObjectField(
|
||||
}
|
||||
|
||||
data.setObjectField(std::string(key), value);
|
||||
if (HostFunctionError ret = setDataCache(contractCtx, account, data, j, true);
|
||||
if (HostFunctionError const ret = setDataCache(contractCtx, account, data, j, true);
|
||||
ret != HostFunctionError::SUCCESS)
|
||||
{
|
||||
JLOG(j.trace()) << "WasmTrace[" << contractId << "]: "
|
||||
@@ -502,7 +502,7 @@ ContractHostFunctionsImpl::setDataNestedObjectField(
|
||||
}
|
||||
|
||||
data.setNestedObjectField(std::string(key), std::string(nestedKey), value);
|
||||
if (HostFunctionError ret = setDataCache(contractCtx, account, data, j, true);
|
||||
if (HostFunctionError const ret = setDataCache(contractCtx, account, data, j, true);
|
||||
ret != HostFunctionError::SUCCESS)
|
||||
{
|
||||
JLOG(j.trace()) << "WasmTrace[" << contractId << "]: "
|
||||
@@ -761,7 +761,7 @@ ContractHostFunctionsImpl::setDataArrayElementField(
|
||||
}
|
||||
|
||||
data.setArrayElementField(index, std::string(key), value);
|
||||
if (HostFunctionError ret = setDataCache(contractCtx, account, data, j, true);
|
||||
if (HostFunctionError const ret = setDataCache(contractCtx, account, data, j, true);
|
||||
ret != HostFunctionError::SUCCESS)
|
||||
{
|
||||
JLOG(j.trace()) << "WasmTrace[" << contractId << "]: "
|
||||
@@ -801,7 +801,7 @@ ContractHostFunctionsImpl::setDataNestedArrayElementField(
|
||||
}
|
||||
|
||||
data.setNestedArrayElementField(std::string(key), index, std::string(nestedKey), value);
|
||||
if (HostFunctionError ret = setDataCache(contractCtx, account, data, j, true);
|
||||
if (HostFunctionError const ret = setDataCache(contractCtx, account, data, j, true);
|
||||
ret != HostFunctionError::SUCCESS)
|
||||
{
|
||||
JLOG(j.trace()) << "WasmTrace[" << contractId << "]: "
|
||||
@@ -956,22 +956,28 @@ ContractHostFunctionsImpl::emitBuiltTxn(std::uint32_t const& index)
|
||||
return Unexpected(HostFunctionError::SUBMIT_TXN_FAILURE);
|
||||
}
|
||||
|
||||
OpenView wholeBatchView(batch_view, contractCtx.applyCtx.openView());
|
||||
auto applyOneTransaction =
|
||||
[&app, &j, &parentBatchId, &wholeBatchView](std::shared_ptr<STTx const> const& tx) {
|
||||
auto const pfResult =
|
||||
preflight(app, wholeBatchView.rules(), parentBatchId, *tx, tapBATCH, j);
|
||||
auto const ret = preclaim(pfResult, app, wholeBatchView);
|
||||
JLOG(j.trace()) << "WasmTrace[" << parentBatchId << "]: " << tx->getTransactionID()
|
||||
<< " " << transToken(ret.ter);
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Use a persistent emit view that is seeded with the
|
||||
// transactor's pending state changes (balances, consumed
|
||||
// sequence, etc.) so that each emitted transaction validates
|
||||
// against the full current state. A full apply() is used
|
||||
// (matching the Batch inner-transaction pattern) so that
|
||||
// sequence numbers, balances, owner counts, and all other
|
||||
// ledger state are properly updated between successive emits.
|
||||
auto& emitView = contractCtx.getEmitView();
|
||||
auto const stx = tpTrans->getSTransaction();
|
||||
auto const result = applyOneTransaction(stx);
|
||||
if (isTesSuccess(result.ter))
|
||||
|
||||
OpenView perTxView(batch_view, emitView);
|
||||
auto const ret = apply(app, perTxView, parentBatchId, *stx, tapBATCH, j);
|
||||
|
||||
JLOG(j.trace()) << "WasmTrace[" << parentBatchId << "]: " << stx->getTransactionID() << " "
|
||||
<< transToken(ret.ter);
|
||||
|
||||
if (ret.applied && (isTesSuccess(ret.ter) || isTecClaim(ret.ter)))
|
||||
{
|
||||
perTxView.apply(emitView);
|
||||
contractCtx.result.emittedTxns.push(stx);
|
||||
return TERtoInt(result.ter);
|
||||
}
|
||||
return TERtoInt(ret.ter);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
@@ -1005,23 +1011,25 @@ ContractHostFunctionsImpl::emitTxn(std::shared_ptr<STTx const> const& stxPtr)
|
||||
if (tpTrans->getStatus() != NEW)
|
||||
return Unexpected(HostFunctionError::SUBMIT_TXN_FAILURE);
|
||||
|
||||
OpenView wholeBatchView(batch_view, contractCtx.applyCtx.openView());
|
||||
// Use a persistent emit view seeded with the transactor's
|
||||
// pending state, and do a full apply() for each emission
|
||||
// (see emitBuiltTxn for detailed rationale).
|
||||
auto& emitView = contractCtx.getEmitView();
|
||||
auto const parentBatchId = parentTx.getTransactionID();
|
||||
auto applyOneTransaction =
|
||||
[&app, &j, &parentBatchId, &wholeBatchView](std::shared_ptr<STTx const> const& tx) {
|
||||
auto const pfResult =
|
||||
preflight(app, wholeBatchView.rules(), parentBatchId, *tx, tapBATCH, j);
|
||||
auto const ret = preclaim(pfResult, app, wholeBatchView);
|
||||
JLOG(j.trace()) << "WasmTrace[" << parentBatchId << "]: " << tx->getTransactionID()
|
||||
<< " " << transToken(ret.ter);
|
||||
return ret;
|
||||
};
|
||||
|
||||
auto const stx = tpTrans->getSTransaction();
|
||||
auto const result = applyOneTransaction(stx);
|
||||
if (isTesSuccess(result.ter))
|
||||
|
||||
OpenView perTxView(batch_view, emitView);
|
||||
auto const ret = apply(app, perTxView, parentBatchId, *stx, tapBATCH, j);
|
||||
|
||||
JLOG(j.trace()) << "WasmTrace[" << parentBatchId << "]: " << stx->getTransactionID() << " "
|
||||
<< transToken(ret.ter);
|
||||
|
||||
if (ret.applied && (isTesSuccess(ret.ter) || isTecClaim(ret.ter)))
|
||||
{
|
||||
perTxView.apply(emitView);
|
||||
contractCtx.result.emittedTxns.push(stx);
|
||||
return TERtoInt(result.ter);
|
||||
}
|
||||
return TERtoInt(ret.ter);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
|
||||
@@ -68,7 +68,11 @@ struct FeeSetup
|
||||
/* (Remember to update the example cfg files when changing any of these
|
||||
* values.) */
|
||||
|
||||
/** Convert to a Fees object for use with Ledger construction. */
|
||||
/** Convert to a Fees object for use with Ledger construction.
|
||||
Extension fees (extensionComputeLimit, extensionSizeLimit, gasPrice)
|
||||
are intentionally NOT set here. They start at 0 and are activated
|
||||
through fee voting on the first flag ledger, or via the genesis
|
||||
ledger SLE when featureSmartEscrow is in the initial amendments. */
|
||||
Fees
|
||||
toFees() const
|
||||
{
|
||||
@@ -76,9 +80,9 @@ struct FeeSetup
|
||||
f.base = reference_fee;
|
||||
f.reserve = account_reserve;
|
||||
f.increment = owner_reserve;
|
||||
f.extensionComputeLimit = extension_compute_limit;
|
||||
f.extensionSizeLimit = extension_size_limit;
|
||||
f.gasPrice = gas_price;
|
||||
f.extensionComputeLimit = 0;
|
||||
f.extensionSizeLimit = 0;
|
||||
f.gasPrice = 0;
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -66,7 +66,7 @@ doContractInfo(RPC::JsonContext& context)
|
||||
RPC::inject_error(rpcACT_MALFORMED, result);
|
||||
return result;
|
||||
}
|
||||
auto const caID{std::move(caid.value())};
|
||||
auto const caID{caid.value()};
|
||||
auto const caSle = ledger->read(keylet::account(caID));
|
||||
if (!caSle)
|
||||
{
|
||||
|
||||
@@ -883,7 +883,7 @@ struct LedgerEntry
|
||||
Json::Value
|
||||
doLedgerEntry(RPC::JsonContext& context)
|
||||
{
|
||||
static LedgerEntry ledgerEntryParsers[] = {
|
||||
static LedgerEntry const ledgerEntryParsers[] = {
|
||||
#pragma push_macro("LEDGER_ENTRY")
|
||||
#undef LEDGER_ENTRY
|
||||
|
||||
|
||||
Reference in New Issue
Block a user