diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index 38e77dedf8..2d0cbbf244 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -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 diff --git a/include/xrpl/ledger/helpers/ContractUtils.h b/include/xrpl/ledger/helpers/ContractUtils.h index 3e478ad43d..831276b623 100644 --- a/include/xrpl/ledger/helpers/ContractUtils.h +++ b/include/xrpl/ledger/helpers/ContractUtils.h @@ -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); diff --git a/include/xrpl/protocol/STData.h b/include/xrpl/protocol/STData.h index 78e3a6657f..d347ac86da 100644 --- a/include/xrpl/protocol/STData.h +++ b/include/xrpl/protocol/STData.h @@ -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("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 diff --git a/include/xrpl/tx/paths/detail/StrandFlow.h b/include/xrpl/tx/paths/detail/StrandFlow.h index fba631c695..8db46cb165 100644 --- a/include/xrpl/tx/paths/detail/StrandFlow.h +++ b/include/xrpl/tx/paths/detail/StrandFlow.h @@ -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) { diff --git a/include/xrpl/tx/wasm/ContractContext.h b/include/xrpl/tx/wasm/ContractContext.h index 8c21405784..94845c646f 100644 --- a/include/xrpl/tx/wasm/ContractContext.h +++ b/include/xrpl/tx/wasm/ContractContext.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -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 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(&applyCtx.view())); + return *emitView; + } }; } // namespace xrpl diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index 77fecd16d5..da3173e704 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -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; diff --git a/src/libxrpl/ledger/helpers/ContractUtils.cpp b/src/libxrpl/ledger/helpers/ContractUtils.cpp index 6a0b23a434..db2fa8607d 100644 --- a/src/libxrpl/ledger/helpers/ContractUtils.cpp +++ b/src/libxrpl/ledger/helpers/ContractUtils.cpp @@ -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 #include #include @@ -46,7 +27,7 @@ contractCreateFee(uint64_t byteCount) constexpr uint64_t mul = static_cast(createByteMultiplier); if (byteCount > std::numeric_limits::max() / mul) return feeCalculationFailed; // overflow - uint64_t uf = byteCount * mul; + uint64_t const uf = byteCount * mul; if (uf > static_cast(std::numeric_limits::max())) return feeCalculationFailed; return static_cast(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) { diff --git a/src/libxrpl/ledger/helpers/NFTokenUtils.cpp b/src/libxrpl/ledger/helpers/NFTokenUtils.cpp index 874c483c3d..d0e4bab601 100644 --- a/src/libxrpl/ledger/helpers/NFTokenUtils.cpp +++ b/src/libxrpl/ledger/helpers/NFTokenUtils.cpp @@ -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; diff --git a/src/libxrpl/protocol/Emitable.cpp b/src/libxrpl/protocol/Emitable.cpp index 96f00cd47b..06bf6feb7f 100644 --- a/src/libxrpl/protocol/Emitable.cpp +++ b/src/libxrpl/protocol/Emitable.cpp @@ -75,7 +75,7 @@ Emitable::getEmitableName(std::uint32_t const value) const { auto const emitableValue = static_cast(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); diff --git a/src/libxrpl/protocol/STData.cpp b/src/libxrpl/protocol/STData.cpp index 24e165e3ca..e091626ac4 100644 --- a/src/libxrpl/protocol/STData.cpp +++ b/src/libxrpl/protocol/STData.cpp @@ -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(stype); + SerializedTypeID const s = static_cast(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(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("STData: expected string for NUMBER"); } - STNumber number = numberFromJson(field, value); + STNumber const number = numberFromJson(field, value); STData data(field, number); return data; } diff --git a/src/libxrpl/protocol/STDataType.cpp b/src/libxrpl/protocol/STDataType.cpp index 19f0afb91e..9da51aa99a 100644 --- a/src/libxrpl/protocol/STDataType.cpp +++ b/src/libxrpl/protocol/STDataType.cpp @@ -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()) { diff --git a/src/libxrpl/protocol/STJson.cpp b/src/libxrpl/protocol/STJson.cpp index 37f214ea96..0069892aa3 100644 --- a/src/libxrpl/protocol/STJson.cpp +++ b/src/libxrpl/protocol/STJson.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -46,10 +47,10 @@ STJson::STJson(SerialIter& sit, SField const& name) : STBase{name} // Read type byte auto typeByte = sit.get8(); - JsonType type = static_cast(typeByte); + JsonType const type = static_cast(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("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("STJson nesting depth exceeds maximum of 1"); + + // Arrays cannot contain arrays + if (isArray() && nested->isArray()) + Throw("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(typeByte); + JsonType const type = static_cast(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("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("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(typeCode); + SerializedTypeID const stype = static_cast(typeCode); // Dispatch to correct SType switch (stype) @@ -699,10 +705,11 @@ STJson::getJson(JsonOptions options) const auto const& map = std::get(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; } diff --git a/src/libxrpl/protocol/STObject.cpp b/src/libxrpl/protocol/STObject.cpp index 239d8e7080..87c4732853 100644 --- a/src/libxrpl/protocol/STObject.cpp +++ b/src/libxrpl/protocol/STObject.cpp @@ -775,6 +775,9 @@ STObject::addFieldFromSlice(SField const& sfield, Slice const& data) case STI_UINT160: element = std::make_unique(sit, sfield); break; + case STI_UINT192: + element = std::make_unique(sit, sfield); + break; case STI_UINT256: element = std::make_unique(sit, sfield); break; diff --git a/src/libxrpl/tx/transactors/contract/ContractCall.cpp b/src/libxrpl/tx/transactors/contract/ContractCall.cpp index fd1e415d14..110d4b8dd8 100644 --- a/src/libxrpl/tx/transactors/contract/ContractCall.cpp +++ b/src/libxrpl/tx/transactors/contract/ContractCall.cpp @@ -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 wasm(wasmStr.begin(), wasmStr.end()); + std::vector 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; diff --git a/src/libxrpl/tx/transactors/contract/ContractDelete.cpp b/src/libxrpl/tx/transactors/contract/ContractDelete.cpp index 6b91cd7ca5..781b558dc1 100644 --- a/src/libxrpl/tx/transactors/contract/ContractDelete.cpp +++ b/src/libxrpl/tx/transactors/contract/ContractDelete.cpp @@ -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) diff --git a/src/libxrpl/tx/transactors/contract/ContractModify.cpp b/src/libxrpl/tx/transactors/contract/ContractModify.cpp index e84e121cb4..24069e9ffc 100644 --- a/src/libxrpl/tx/transactors/contract/ContractModify.cpp +++ b/src/libxrpl/tx/transactors/contract/ContractModify.cpp @@ -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) diff --git a/src/libxrpl/tx/wasm/HostFuncWrapper.cpp b/src/libxrpl/tx/wasm/HostFuncWrapper.cpp index 95ebe23f39..e342d1a62a 100644 --- a/src/libxrpl/tx/wasm/HostFuncWrapper.cpp +++ b/src/libxrpl/tx/wasm/HostFuncWrapper.cpp @@ -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(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(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) diff --git a/src/test/app/ContractHostFuncImpl_test.cpp b/src/test/app/ContractHostFuncImpl_test.cpp index 928070a34f..0c5975fd75 100644 --- a/src/test/app/ContractHostFuncImpl_test.cpp +++ b/src/test/app/ContractHostFuncImpl_test.cpp @@ -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 instanceParameters; - std::vector functionParameters; + xrpl::ContractDataMap const dataMap; + xrpl::ContractEventMap const eventMap; + std::vector const instanceParameters; + std::vector 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 // { diff --git a/src/test/app/Contract_test.cpp b/src/test/app/Contract_test.cpp index ca3cb59974..589e72d1f1 100644 --- a/src/test/app/Contract_test.cpp +++ b/src/test/app/Contract_test.cpp @@ -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(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 buffer( + std::vector const buffer( (std::istreambuf_iterator(file)), std::istreambuf_iterator()); // 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, diff --git a/src/test/app/Delegate_test.cpp b/src/test/app/Delegate_test.cpp index 6c5698a227..2afc0c6d57 100644 --- a/src/test/app/Delegate_test.cpp +++ b/src/test/app/Delegate_test.cpp @@ -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 @@ -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, diff --git a/src/test/protocol/STDataType_test.cpp b/src/test/protocol/STDataType_test.cpp index f5828a4c82..a74e8c53b4 100644 --- a/src/test/protocol/STDataType_test.cpp +++ b/src/test/protocol/STDataType_test.cpp @@ -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(999)); + STDataType const dt(sf, static_cast(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(999)); + STDataType const dt(sf, static_cast(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 typeStrings = { + std::vector 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); } } diff --git a/src/test/protocol/STData_test.cpp b/src/test/protocol/STData_test.cpp index afc929983d..c1451fa6f1 100644 --- a/src/test/protocol/STData_test.cpp +++ b/src/test/protocol/STData_test.cpp @@ -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(8)); + STData const data_u8(sf, static_cast(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(16)); + STData const data_u16(sf, static_cast(16)); BEAST_EXPECT(data_u16.getFieldU16() == 16); BEAST_EXPECT(data_u16.getInnerTypeString() == "UINT16"); // UINT32 - STData data_u32(sf, static_cast(32)); + STData const data_u32(sf, static_cast(32)); BEAST_EXPECT(data_u32.getFieldU32() == 32); BEAST_EXPECT(data_u32.getInnerTypeString() == "UINT32"); // UINT64 - STData data_u64(sf, static_cast(64)); + STData const data_u64(sf, static_cast(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("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(8)); + STData const data_u8(sf, static_cast(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(16)); + STData const data_u16(sf, static_cast(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(32)); + STData const data_u32(sf, static_cast(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(64)); + STData const data_u64(sf, static_cast(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("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"); } diff --git a/src/test/protocol/STJson_test.cpp b/src/test/protocol/STJson_test.cpp index 8fd19feb8b..f90c5b4e81 100644 --- a/src/test/protocol/STJson_test.cpp +++ b/src/test/protocol/STJson_test.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -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(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(json.getMap().at("bar"))->value() == 42); @@ -76,7 +77,7 @@ struct STJson_test : public beast::unit_test::suite arr.push_back(std::make_shared(sfNetworkID, 100)); arr.push_back(std::make_shared(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(sfTransactionType, 65535)); json.setObjectField("bar", nullptr); // test null value + json.setNestedObjectField("meta", "version", std::make_shared(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(123456789u)); + STAmount const xrp(sfAmount, static_cast(123456789u)); json.setObjectField("amount", std::make_shared(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(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(123456789u)); + STAmount const xrp(sfAmount, static_cast(123456789u)); innerJson.setObjectField("amount", std::make_shared(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()); } } diff --git a/src/test/rpc/Subscribe_test.cpp b/src/test/rpc/Subscribe_test.cpp index 33876b9dbb..be412b36cd 100644 --- a/src/test/rpc/Subscribe_test.cpp +++ b/src/test/rpc/Subscribe_test.cpp @@ -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; }; diff --git a/src/xrpld/app/misc/NetworkOPs.cpp b/src/xrpld/app/misc/NetworkOPs.cpp index a2c13bcd7b..4006901c5c 100644 --- a/src/xrpld/app/misc/NetworkOPs.cpp +++ b/src/xrpld/app/misc/NetworkOPs.cpp @@ -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); } diff --git a/src/xrpld/app/wasm/detail/ContractHostFuncImpl.cpp b/src/xrpld/app/wasm/detail/ContractHostFuncImpl.cpp index 2c7c43dbe8..cdca7cc5ea 100644 --- a/src/xrpld/app/wasm/detail/ContractHostFuncImpl.cpp +++ b/src/xrpld/app/wasm/detail/ContractHostFuncImpl.cpp @@ -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(data & 0xFF), static_cast((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(data & 0xFF), static_cast((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(data & 0xFF), static_cast((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 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 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 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) { diff --git a/src/xrpld/core/Config.h b/src/xrpld/core/Config.h index 1b3a5fff03..ba5357693e 100644 --- a/src/xrpld/core/Config.h +++ b/src/xrpld/core/Config.h @@ -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; } }; diff --git a/src/xrpld/rpc/handlers/ContractInfo.cpp b/src/xrpld/rpc/handlers/ContractInfo.cpp index b07fa60d99..9cb3f4efb0 100644 --- a/src/xrpld/rpc/handlers/ContractInfo.cpp +++ b/src/xrpld/rpc/handlers/ContractInfo.cpp @@ -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) { diff --git a/src/xrpld/rpc/handlers/ledger/LedgerEntry.cpp b/src/xrpld/rpc/handlers/ledger/LedgerEntry.cpp index e9b77c0c31..85b0fb2710 100644 --- a/src/xrpld/rpc/handlers/ledger/LedgerEntry.cpp +++ b/src/xrpld/rpc/handlers/ledger/LedgerEntry.cpp @@ -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