Merge branch 'ripple/smart-escrow' into smart-escrow/versioning

This commit is contained in:
Timothy Banks
2026-07-23 10:12:13 -04:00
committed by GitHub
27 changed files with 316 additions and 322 deletions

View File

@@ -61,9 +61,9 @@ public:
}
void
setWasmReturnCode(std::int32_t const wasmReturnCode)
setVMReturnCode(std::int32_t const vmReturnCode)
{
wasmReturnCode_ = wasmReturnCode;
vmReturnCode_ = vmReturnCode;
}
/** Get the number of modified entries
@@ -85,7 +85,7 @@ public:
private:
std::optional<STAmount> deliver_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> wasmReturnCode_;
std::optional<std::int32_t> vmReturnCode_;
};
} // namespace xrpl

View File

@@ -52,7 +52,7 @@ public:
std::optional<STAmount> const& deliver,
std::optional<uint256 const> const& parentBatchId,
std::optional<std::uint32_t> const& gasUsed,
std::optional<std::int32_t> const& wasmReturnCode,
std::optional<std::int32_t> const& vmReturnCode,
bool isDryRun,
beast::Journal j);

View File

@@ -129,7 +129,7 @@ enum TEMcodes : TERUnderlyingType {
temINVALID_INNER_BATCH,
temBAD_MPT,
temBAD_WASM,
temINVALID_BYTECODE,
temTEMP_DISABLED,
};
@@ -177,8 +177,8 @@ enum TEFcodes : TERUnderlyingType {
tefNO_TICKET,
tefNFTOKEN_IS_NOT_TRANSFERABLE,
tefINVALID_LEDGER_FIX_TYPE,
tefNO_WASM,
tefWASM_FIELD_NOT_INCLUDED,
tefNO_BYTECODE,
tefBYTECODE_NOT_INCLUDED,
};
//------------------------------------------------------------------------------
@@ -363,7 +363,7 @@ enum TECcodes : TERUnderlyingType {
tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196,
tecPRECISION_LOSS = 197,
tecWASM_REJECTED = 198,
tecBYTECODE_REJECTED = 198,
};
//------------------------------------------------------------------------------

View File

@@ -88,8 +88,8 @@ public:
if (obj.isFieldPresent(sfGasUsed))
gasUsed_ = obj.getFieldU32(sfGasUsed);
if (obj.isFieldPresent(sfWasmReturnCode))
wasmReturnCode_ = obj.getFieldI32(sfWasmReturnCode);
if (obj.isFieldPresent(sfVMReturnCode))
vmReturnCode_ = obj.getFieldI32(sfVMReturnCode);
}
[[nodiscard]] std::optional<STAmount> const&
@@ -123,15 +123,15 @@ public:
}
void
setWasmReturnCode(std::optional<std::int32_t> const wasmReturnCode)
setVMReturnCode(std::optional<std::int32_t> const vmReturnCode)
{
wasmReturnCode_ = wasmReturnCode;
vmReturnCode_ = vmReturnCode;
}
[[nodiscard]] std::optional<std::int32_t> const&
getWasmReturnCode() const
getVMReturnCode() const
{
return wasmReturnCode_;
return vmReturnCode_;
}
private:
@@ -143,7 +143,7 @@ private:
std::optional<STAmount> deliveredAmount_;
std::optional<uint256> parentBatchID_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> wasmReturnCode_;
std::optional<std::int32_t> vmReturnCode_;
STArray nodes_;
};

View File

@@ -339,7 +339,7 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, escrow, ({
{sfCondition, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfFinishAfter, SoeOptional},
{sfFinishFunction, SoeOptional},
{sfBytecode, SoeOptional},
{sfData, SoeOptional},
{sfSourceTag, SoeOptional},
{sfDestinationTag, SoeOptional},

View File

@@ -116,7 +116,7 @@ TYPED_SFIELD(sfOverpaymentInterestRate, UINT32, 68) // 1/10 basis points (bi
TYPED_SFIELD(sfExtensionComputeLimit, UINT32, 69)
TYPED_SFIELD(sfExtensionSizeLimit, UINT32, 70)
TYPED_SFIELD(sfGasPrice, UINT32, 71)
TYPED_SFIELD(sfComputationAllowance, UINT32, 72)
TYPED_SFIELD(sfGas, UINT32, 72)
TYPED_SFIELD(sfGasUsed, UINT32, 73)
// 64-bit integers (common)
@@ -232,7 +232,7 @@ TYPED_SFIELD(sfManagementFeeOutstanding, NUMBER, 17, SField::kSmdNeedsAsset
// 32-bit signed (common)
TYPED_SFIELD(sfLoanScale, INT32, 1)
TYPED_SFIELD(sfWasmReturnCode, INT32, 2)
TYPED_SFIELD(sfVMReturnCode, INT32, 2)
// currency amount (common)
TYPED_SFIELD(sfAmount, AMOUNT, 1)
@@ -304,7 +304,7 @@ TYPED_SFIELD(sfAssetClass, VL, 28)
TYPED_SFIELD(sfProvider, VL, 29)
TYPED_SFIELD(sfMPTokenMetadata, VL, 30)
TYPED_SFIELD(sfCredentialType, VL, 31)
TYPED_SFIELD(sfFinishFunction, VL, 32)
TYPED_SFIELD(sfBytecode, VL, 32)
// account (common)
TYPED_SFIELD(sfAccount, ACCOUNT, 1)

View File

@@ -55,7 +55,7 @@ TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate,
{sfCondition, SoeOptional},
{sfCancelAfter, SoeOptional},
{sfFinishAfter, SoeOptional},
{sfFinishFunction, SoeOptional},
{sfBytecode, SoeOptional},
{sfData, SoeOptional},
}))
@@ -73,7 +73,7 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish,
{sfFulfillment, SoeOptional},
{sfCondition, SoeOptional},
{sfCredentialIDs, SoeOptional},
{sfComputationAllowance, SoeOptional},
{sfGas, SoeOptional},
}))

View File

@@ -175,27 +175,27 @@ public:
}
/**
* @brief Get sfFinishFunction (SoeOptional)
* @brief Get sfBytecode (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getFinishFunction() const
getBytecode() const
{
if (hasFinishFunction())
return this->sle_->at(sfFinishFunction);
if (hasBytecode())
return this->sle_->at(sfBytecode);
return std::nullopt;
}
/**
* @brief Check if sfFinishFunction is present.
* @brief Check if sfBytecode is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasFinishFunction() const
hasBytecode() const
{
return this->sle_->isFieldPresent(sfFinishFunction);
return this->sle_->isFieldPresent(sfBytecode);
}
/**
@@ -500,13 +500,13 @@ public:
}
/**
* @brief Set sfFinishFunction (SoeOptional)
* @brief Set sfBytecode (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowBuilder&
setFinishFunction(std::decay_t<typename SF_VL::type::value_type> const& value)
setBytecode(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfFinishFunction] = value;
object_[sfBytecode] = value;
return *this;
}

View File

@@ -175,29 +175,29 @@ public:
}
/**
* @brief Get sfFinishFunction (SoeOptional)
* @brief Get sfBytecode (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getFinishFunction() const
getBytecode() const
{
if (hasFinishFunction())
if (hasBytecode())
{
return this->tx_->at(sfFinishFunction);
return this->tx_->at(sfBytecode);
}
return std::nullopt;
}
/**
* @brief Check if sfFinishFunction is present.
* @brief Check if sfBytecode is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasFinishFunction() const
hasBytecode() const
{
return this->tx_->isFieldPresent(sfFinishFunction);
return this->tx_->isFieldPresent(sfBytecode);
}
/**
@@ -339,13 +339,13 @@ public:
}
/**
* @brief Set sfFinishFunction (SoeOptional)
* @brief Set sfBytecode (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowCreateBuilder&
setFinishFunction(std::decay_t<typename SF_VL::type::value_type> const& value)
setBytecode(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfFinishFunction] = value;
object_[sfBytecode] = value;
return *this;
}

View File

@@ -148,29 +148,29 @@ public:
}
/**
* @brief Get sfComputationAllowance (SoeOptional)
* @brief Get sfGas (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_UINT32::type::value_type>
getComputationAllowance() const
getGas() const
{
if (hasComputationAllowance())
if (hasGas())
{
return this->tx_->at(sfComputationAllowance);
return this->tx_->at(sfGas);
}
return std::nullopt;
}
/**
* @brief Check if sfComputationAllowance is present.
* @brief Check if sfGas is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasComputationAllowance() const
hasGas() const
{
return this->tx_->isFieldPresent(sfComputationAllowance);
return this->tx_->isFieldPresent(sfGas);
}
};
@@ -274,13 +274,13 @@ public:
}
/**
* @brief Set sfComputationAllowance (SoeOptional)
* @brief Set sfGas (SoeOptional)
* @return Reference to this builder for method chaining.
*/
EscrowFinishBuilder&
setComputationAllowance(std::decay_t<typename SF_UINT32::type::value_type> const& value)
setGas(std::decay_t<typename SF_UINT32::type::value_type> const& value)
{
object_[sfComputationAllowance] = value;
object_[sfGas] = value;
return *this;
}

View File

@@ -85,9 +85,9 @@ public:
/** Sets the gas used in the metadata */
void
setWasmReturnCode(std::int32_t const wasmReturnCode)
setVMReturnCode(std::int32_t const vmReturnCode)
{
wasmReturnCode_ = wasmReturnCode;
vmReturnCode_ = vmReturnCode;
}
/** Discard changes and start fresh. */
@@ -141,7 +141,7 @@ private:
// The ID of the batch transaction we are executing under, if seated.
std::optional<uint256 const> parentBatchId_;
std::optional<std::uint32_t> gasUsed_;
std::optional<std::int32_t> wasmReturnCode_;
std::optional<std::int32_t> vmReturnCode_;
};
} // namespace xrpl

View File

@@ -116,7 +116,7 @@ ApplyStateTable::apply(
std::optional<STAmount> const& deliver,
std::optional<uint256 const> const& parentBatchId,
std::optional<std::uint32_t> const& gasUsed,
std::optional<std::int32_t> const& wasmReturnCode,
std::optional<std::int32_t> const& vmReturnCode,
bool isDryRun,
beast::Journal j)
{
@@ -132,7 +132,7 @@ ApplyStateTable::apply(
meta.setDeliveredAmount(deliver);
meta.setParentBatchID(parentBatchId);
meta.setGasUsed(gasUsed);
meta.setWasmReturnCode(wasmReturnCode);
meta.setVMReturnCode(vmReturnCode);
Mods newMod;
for (auto& item : items_)

View File

@@ -31,8 +31,7 @@ ApplyViewImpl::apply(
bool isDryRun,
beast::Journal j)
{
return items_.apply(
to, tx, ter, deliver_, parentBatchId, gasUsed_, wasmReturnCode_, isDryRun, j);
return items_.apply(to, tx, ter, deliver_, parentBatchId, gasUsed_, vmReturnCode_, isDryRun, j);
}
std::size_t

View File

@@ -106,7 +106,7 @@ transResults()
MAKE_ERROR(tecLIMIT_EXCEEDED, "Limit exceeded."),
MAKE_ERROR(tecPSEUDO_ACCOUNT, "This operation is not allowed against a pseudo-account."),
MAKE_ERROR(tecPRECISION_LOSS, "The amounts used by the transaction cannot interact."),
MAKE_ERROR(tecWASM_REJECTED, "The custom WASM code that was run rejected your transaction."),
MAKE_ERROR(tecBYTECODE_REJECTED, "The custom WASM code that was run rejected your transaction."),
MAKE_ERROR(tefALREADY, "The exact transaction was already in this ledger."),
MAKE_ERROR(tefBAD_ADD_AUTH, "Not authorized to add account."),
@@ -130,8 +130,8 @@ transResults()
MAKE_ERROR(tefNO_TICKET, "Ticket is not in ledger."),
MAKE_ERROR(tefNFTOKEN_IS_NOT_TRANSFERABLE, "The specified NFToken is not transferable."),
MAKE_ERROR(tefINVALID_LEDGER_FIX_TYPE, "The LedgerFixType field has an invalid value."),
MAKE_ERROR(tefNO_WASM, "There is no WASM code to run, but a WASM-specific field was included."),
MAKE_ERROR(tefWASM_FIELD_NOT_INCLUDED, "WASM code requires a field to be included that was not included."),
MAKE_ERROR(tefNO_BYTECODE, "There is no WASM code to run, but a WASM-specific field was included."),
MAKE_ERROR(tefBYTECODE_NOT_INCLUDED, "WASM code requires a field to be included that was not included."),
MAKE_ERROR(telLOCAL_ERROR, "Local failure."),
MAKE_ERROR(telBAD_DOMAIN, "Domain too long."),
@@ -202,7 +202,7 @@ transResults()
MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."),
MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."),
MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."),
MAKE_ERROR(temBAD_WASM, "Malformed: Provided WASM code is invalid."),
MAKE_ERROR(temINVALID_BYTECODE, "Malformed: Provided WASM code is invalid."),
MAKE_ERROR(temTEMP_DISABLED, "The transaction requires logic that is currently temporarily disabled."),
MAKE_ERROR(terRETRY, "Retry transaction."),

View File

@@ -197,8 +197,8 @@ TxMeta::getAsObject() const
if (gasUsed_.has_value())
metaData.setFieldU32(sfGasUsed, *gasUsed_);
if (wasmReturnCode_.has_value())
metaData.setFieldI32(sfWasmReturnCode, *wasmReturnCode_);
if (vmReturnCode_.has_value())
metaData.setFieldI32(sfVMReturnCode, *vmReturnCode_);
return metaData;
}

View File

@@ -58,10 +58,10 @@ ApplyContext::discard()
std::optional<TxMeta>
ApplyContext::apply(TER ter)
{
if (wasmReturnCode_.has_value())
if (vmReturnCode_.has_value())
{
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) view_ emplaced in constructor
view_->setWasmReturnCode(*wasmReturnCode_);
view_->setVMReturnCode(*vmReturnCode_);
}
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) view_ emplaced in constructor
view_->setGasUsed(gasUsed_);

View File

@@ -1261,7 +1261,7 @@ Transactor::operator()()
}
else if (
(result == tecOVERSIZE) || (result == tecKILLED) || (result == tecINCOMPLETE) ||
(result == tecEXPIRED) || (result == tecWASM_REJECTED) ||
(result == tecEXPIRED) || (result == tecBYTECODE_REJECTED) ||
(isTecClaimHardFail(result, view().flags())))
{
JLOG(j_.trace()) << "reapplying because of " << transToken(result);
@@ -1281,7 +1281,7 @@ Transactor::operator()()
bool const doLinesOrMPTs = (result == tecINCOMPLETE);
bool const doNFTokenOffers = (result == tecEXPIRED);
bool const doCredentials = (result == tecEXPIRED);
bool const doWasmData = (result == tecWASM_REJECTED);
bool const doWasmData = (result == tecBYTECODE_REJECTED);
if (doOffers || doLinesOrMPTs || doNFTokenOffers || doCredentials || doWasmData)
{
ctx_.visit([doOffers,
@@ -1374,7 +1374,7 @@ Transactor::operator()()
view(), expiredCredentials, ctx_.registry.get().getJournal("View"));
}
if (result == tecWASM_REJECTED)
if (result == tecBYTECODE_REJECTED)
{
modifyWasmDataFields(
view(), modifiedWasmObjects, ctx_.registry.get().getJournal("View"));

View File

@@ -210,7 +210,7 @@ EscrowCancel::doApply()
}
}
auto const reserveToSubtract = calculateAdditionalReserve((*slep)[~sfFinishFunction]);
auto const reserveToSubtract = calculateAdditionalReserve((*slep)[~sfBytecode]);
adjustOwnerCount(ctx_.view(), sle, -1 * reserveToSubtract, ctx_.journal);
ctx_.view().update(sle);

View File

@@ -121,11 +121,11 @@ XRPAmount
EscrowCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
{
XRPAmount txnFees{Transactor::calculateBaseFee(view, tx)};
if (tx.isFieldPresent(sfFinishFunction))
if (tx.isFieldPresent(sfBytecode))
{
// 10 base fees for the transaction (1 is in
// `Transactor::calculateBaseFee`), plus 5 drops per byte
txnFees += 9 * view.fees().base + 5 * tx[sfFinishFunction].size();
txnFees += 9 * view.fees().base + 5 * tx[sfBytecode].size();
}
return txnFees;
}
@@ -133,7 +133,7 @@ EscrowCreate::calculateBaseFee(ReadView const& view, STTx const& tx)
bool
EscrowCreate::checkExtraFeatures(PreflightContext const& ctx)
{
return (!ctx.tx.isFieldPresent(sfFinishFunction) && !ctx.tx.isFieldPresent(sfData)) ||
return (!ctx.tx.isFieldPresent(sfBytecode) && !ctx.tx.isFieldPresent(sfData)) ||
ctx.rules.enabled(featureSmartEscrow);
}
@@ -168,17 +168,17 @@ EscrowCreate::preflight(PreflightContext const& ctx)
ctx.tx[sfCancelAfter] <= ctx.tx[sfFinishAfter])
return temBAD_EXPIRATION;
if (ctx.tx.isFieldPresent(sfFinishFunction) && !ctx.tx.isFieldPresent(sfCancelAfter))
if (ctx.tx.isFieldPresent(sfBytecode) && !ctx.tx.isFieldPresent(sfCancelAfter))
return temBAD_EXPIRATION;
// In the absence of a FinishAfter, the escrow can be finished
// immediately, which can be confusing. When creating an escrow,
// we want to ensure that either a FinishAfter time is explicitly
// specified or a completion condition is attached.
if (!ctx.tx[~sfFinishAfter] && !ctx.tx[~sfCondition] && !ctx.tx[~sfFinishFunction])
if (!ctx.tx[~sfFinishAfter] && !ctx.tx[~sfCondition] && !ctx.tx[~sfBytecode])
{
JLOG(ctx.j.debug()) << "Must have at least one of FinishAfter, "
"Condition, or FinishFunction.";
"Condition, or Bytecode.";
return temMALFORMED;
}
@@ -198,9 +198,9 @@ EscrowCreate::preflight(PreflightContext const& ctx)
if (ctx.tx.isFieldPresent(sfData))
{
if (!ctx.tx.isFieldPresent(sfFinishFunction))
if (!ctx.tx.isFieldPresent(sfBytecode))
{
JLOG(ctx.j.debug()) << "EscrowCreate with Data requires FinishFunction";
JLOG(ctx.j.debug()) << "EscrowCreate with Data requires Bytecode";
return temMALFORMED;
}
auto const data = ctx.tx.getFieldVL(sfData);
@@ -211,7 +211,7 @@ EscrowCreate::preflight(PreflightContext const& ctx)
}
}
if (ctx.tx.isFieldPresent(sfFinishFunction))
if (ctx.tx.isFieldPresent(sfBytecode))
{
auto const fees(ctx.registry.get().getFees());
if (fees.extensionSizeLimit == 0 || fees.extensionComputeLimit == 0)
@@ -220,10 +220,10 @@ EscrowCreate::preflight(PreflightContext const& ctx)
return temTEMP_DISABLED;
}
auto const code = ctx.tx.getFieldVL(sfFinishFunction);
auto const code = ctx.tx.getFieldVL(sfBytecode);
if (code.empty() || code.size() > fees.extensionSizeLimit)
{
JLOG(ctx.j.debug()) << "EscrowCreate.FinishFunction bad size " << code.size();
JLOG(ctx.j.debug()) << "EscrowCreate.Bytecode bad size " << code.size();
return temMALFORMED;
}
// actual validity of WASM code happens in `preflightSigValidated`
@@ -236,16 +236,16 @@ EscrowCreate::preflight(PreflightContext const& ctx)
NotTEC
EscrowCreate::preflightSigValidated(PreflightContext const& ctx)
{
if (ctx.tx.isFieldPresent(sfFinishFunction))
if (ctx.tx.isFieldPresent(sfBytecode))
{
auto const code = ctx.tx.getFieldVL(sfFinishFunction);
auto const code = ctx.tx.getFieldVL(sfBytecode);
// basic checks happen in `preflight`
HostFunctions mock(ctx.j);
auto const re = preflightEscrowWasm(code, mock, escrowFunctionName);
if (!isTesSuccess(re))
{
JLOG(ctx.j.debug()) << "EscrowCreate.FinishFunction bad WASM";
JLOG(ctx.j.debug()) << "EscrowCreate.Bytecode bad WASM";
return re;
}
}
@@ -508,7 +508,7 @@ EscrowCreate::doApply()
// Check reserve and funds availability
STAmount const amount{ctx_.tx[sfAmount]};
auto const reserveToAdd = calculateAdditionalReserve(ctx_.tx[~sfFinishFunction]);
auto const reserveToAdd = calculateAdditionalReserve(ctx_.tx[~sfBytecode]);
auto const reserve = ctx_.view().fees().accountReserve((*sle)[sfOwnerCount] + reserveToAdd);
@@ -544,7 +544,7 @@ EscrowCreate::doApply()
(*slep)[~sfCancelAfter] = ctx_.tx[~sfCancelAfter];
(*slep)[~sfFinishAfter] = ctx_.tx[~sfFinishAfter];
(*slep)[~sfDestinationTag] = ctx_.tx[~sfDestinationTag];
(*slep)[~sfFinishFunction] = ctx_.tx[~sfFinishFunction];
(*slep)[~sfBytecode] = ctx_.tx[~sfBytecode];
(*slep)[~sfData] = ctx_.tx[~sfData];
if (ctx_.view().rules().enabled(fixIncludeKeyletFields))

View File

@@ -77,7 +77,7 @@ EscrowFinish::checkExtraFeatures(PreflightContext const& ctx)
if (ctx.tx.isFieldPresent(sfCredentialIDs) && !ctx.rules.enabled(featureCredentials))
return false;
if (ctx.tx.isFieldPresent(sfComputationAllowance) && !ctx.rules.enabled(featureSmartEscrow))
if (ctx.tx.isFieldPresent(sfGas) && !ctx.rules.enabled(featureSmartEscrow))
{
return false;
}
@@ -98,7 +98,7 @@ EscrowFinish::preflight(PreflightContext const& ctx)
return temMALFORMED;
}
if (auto const allowance = ctx.tx[~sfComputationAllowance]; allowance)
if (auto const allowance = ctx.tx[~sfGas]; allowance)
{
auto const fees(ctx.registry.get().getFees());
if (fees.extensionComputeLimit == 0)
@@ -112,7 +112,7 @@ EscrowFinish::preflight(PreflightContext const& ctx)
}
if (*allowance > fees.extensionComputeLimit)
{
JLOG(ctx.j.debug()) << "ComputationAllowance too large: " << *allowance;
JLOG(ctx.j.debug()) << "Gas too large: " << *allowance;
return temBAD_LIMIT;
}
}
@@ -164,7 +164,7 @@ EscrowFinish::calculateBaseFee(ReadView const& view, STTx const& tx)
{
extraFee += view.fees().base * (32 + (fb->size() / 16));
}
if (std::optional<uint64_t> const allowance = tx[~sfComputationAllowance]; allowance)
if (std::optional<uint64_t> const allowance = tx[~sfGas]; allowance)
{
// The extra fee is the allowance in drops, rounded up to the nearest
// whole drop.
@@ -259,21 +259,21 @@ EscrowFinish::preclaim(PreclaimContext const& ctx)
if (ctx.view.rules().enabled(featureSmartEscrow))
{
if (slep->isFieldPresent(sfFinishFunction))
if (slep->isFieldPresent(sfBytecode))
{
if (!ctx.tx.isFieldPresent(sfComputationAllowance))
if (!ctx.tx.isFieldPresent(sfGas))
{
JLOG(ctx.j.debug()) << "FinishFunction requires ComputationAllowance";
return tefWASM_FIELD_NOT_INCLUDED;
JLOG(ctx.j.debug()) << "Bytecode requires Gas";
return tefBYTECODE_NOT_INCLUDED;
}
}
else
{
if (ctx.tx.isFieldPresent(sfComputationAllowance))
if (ctx.tx.isFieldPresent(sfGas))
{
JLOG(ctx.j.debug()) << "FinishFunction not present, "
"ComputationAllowance present";
return tefNO_WASM;
JLOG(ctx.j.debug()) << "Bytecode not present, "
"Gas present";
return tefNO_BYTECODE;
}
}
}
@@ -403,21 +403,21 @@ EscrowFinish::doApply()
}
// Execute custom release function
if ((*slep)[~sfFinishFunction])
if ((*slep)[~sfBytecode])
{
JLOG(j_.trace()) << "The escrow has a finish function, running WASM code...";
// WASM execution
auto const wasmStr = slep->getFieldVL(sfFinishFunction);
auto const wasmStr = slep->getFieldVL(sfBytecode);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
WasmHostFunctionsImpl ledgerDataProvider(ctx_, k);
if (!ctx_.tx.isFieldPresent(sfComputationAllowance))
if (!ctx_.tx.isFieldPresent(sfGas))
{
// already checked above, this check is just in case
return tecINTERNAL;
}
std::uint32_t const allowance = ctx_.tx[sfComputationAllowance];
std::uint32_t const allowance = ctx_.tx[sfGas];
auto re = runEscrowWasm(wasm, ledgerDataProvider, allowance, escrowFunctionName);
JLOG(j_.trace()) << "Escrow WASM ran";
@@ -438,7 +438,7 @@ EscrowFinish::doApply()
auto const reCost = re.value().cost;
JLOG(j_.debug()) << "WASM Success: " + std::to_string(reValue) << ", cost: " << reCost;
ctx_.setWasmReturnCode(reValue);
ctx_.setVMReturnCode(reValue);
if (reCost < 0 || reCost > std::numeric_limits<uint32_t>::max())
return tecINTERNAL; // LCOV_EXCL_LINE
@@ -446,7 +446,7 @@ EscrowFinish::doApply()
if (reValue <= 0)
{
return tecWASM_REJECTED;
return tecBYTECODE_REJECTED;
}
}
else
@@ -531,7 +531,7 @@ EscrowFinish::doApply()
ctx_.view().update(sled);
auto const reserveToSubtract = calculateAdditionalReserve((*slep)[~sfFinishFunction]);
auto const reserveToSubtract = calculateAdditionalReserve((*slep)[~sfBytecode]);
// Adjust source owner count
auto const sle = ctx_.view().peek(keylet::account(account));

View File

@@ -1033,7 +1033,7 @@ WasmiEngine::check(
}
// LCOV_EXCL_STOP
return temBAD_WASM;
return temINVALID_BYTECODE;
}
NotTEC

View File

@@ -59,9 +59,9 @@ namespace xrpl::test {
struct EscrowSmart_test : public beast::unit_test::Suite
{
void
testCreateFinishFunctionPreflight(FeatureBitset features)
testCreateBytecodePreflight(FeatureBitset features)
{
testcase("Test preflight checks involving FinishFunction");
testcase("Test preflight checks involving Bytecode");
using namespace jtx;
using namespace std::chrono;
@@ -79,14 +79,14 @@ struct EscrowSmart_test : public beast::unit_test::Suite
XRPAmount const txnFees = env.current()->fees().base + 1000;
auto const escrowCreate = escrow::create(alice, carol, XRP(1000));
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees),
Ter(temDISABLED));
env.close();
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
escrow::Data("00112233"),
Fee(txnFees),
@@ -95,7 +95,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}
{
// FinishFunction > max length
// Bytecode > max length
Env env(
*this,
envconfig([](std::unique_ptr<Config> cfg) {
@@ -112,7 +112,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// 11-byte string
std::string const longWasmHex = "00112233445566778899AA";
env(escrowCreate,
escrow::FinishFunction(longWasmHex),
escrow::Bytecode(longWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees),
Ter(temMALFORMED));
@@ -136,9 +136,9 @@ struct EscrowSmart_test : public beast::unit_test::Suite
auto const escrowCreate = escrow::create(alice, carol, XRP(500));
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
escrow::CompAllowance(100),
escrow::Gas(100),
Fee(txnFees),
Ter(temMALFORMED));
env.close();
@@ -161,14 +161,14 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// 2-byte string
env(escrowCreate,
escrow::FinishFunction("AA"),
escrow::Bytecode("AA"),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees),
Ter(temTEMP_DISABLED));
env.close();
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees),
Ter(temTEMP_DISABLED));
@@ -176,7 +176,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}
{
// Data without FinishFunction
// Data without Bytecode
Env env(*this, features);
XRPAmount const txnFees = env.current()->fees().base + 100000;
// create escrow
@@ -206,7 +206,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
std::string const longData((maxWasmDataLength + 1) * 2, 'B');
env(escrowCreate,
escrow::Data(longData),
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees),
Ter(temMALFORMED));
@@ -229,35 +229,35 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// Success situations
{
// FinishFunction + CancelAfter
// Bytecode + CancelAfter
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 20s),
Fee(txnFees));
env.close();
}
{
// FinishFunction + Condition + CancelAfter
// Bytecode + Condition + CancelAfter
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 30s),
escrow::kCondition(escrow::kCb1),
Fee(txnFees));
env.close();
}
{
// FinishFunction + FinishAfter + CancelAfter
// Bytecode + FinishAfter + CancelAfter
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 40s),
escrow::kFinishTime(env.now() + 2s),
Fee(txnFees));
env.close();
}
{
// FinishFunction + FinishAfter + Condition + CancelAfter
// Bytecode + FinishAfter + Condition + CancelAfter
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 50s),
escrow::kCondition(escrow::kCb1),
escrow::kFinishTime(env.now() + 2s),
@@ -267,35 +267,35 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// Failure situations (i.e. all other combinations)
{
// only FinishFunction
// only Bytecode
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
Fee(txnFees),
Ter(temBAD_EXPIRATION));
env.close();
}
{
// FinishFunction + FinishAfter
// Bytecode + FinishAfter
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kFinishTime(env.now() + 2s),
Fee(txnFees),
Ter(temBAD_EXPIRATION));
env.close();
}
{
// FinishFunction + Condition
// Bytecode + Condition
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCondition(escrow::kCb1),
Fee(txnFees),
Ter(temBAD_EXPIRATION));
env.close();
}
{
// FinishFunction + FinishAfter + Condition
// Bytecode + FinishAfter + Condition
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCondition(escrow::kCb1),
escrow::kFinishTime(env.now() + 2s),
Fee(txnFees),
@@ -303,9 +303,9 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env.close();
}
{
// FinishFunction 0 length
// Bytecode 0 length
env(escrowCreate,
escrow::FinishFunction(""),
escrow::Bytecode(""),
escrow::kCancelTime(env.now() + 60s),
Fee(txnFees),
Ter(temMALFORMED));
@@ -314,7 +314,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
{
// Not enough fees
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 70s),
Fee(txnFees - 1),
Ter(telINSUF_FEE_P));
@@ -322,7 +322,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}
{
// FinishFunction nonexistent host function
// Bytecode nonexistent host function
// pub fn finish() -> bool {
// unsafe { host_lib::bad() >= 5 }
// }
@@ -337,10 +337,10 @@ struct EscrowSmart_test : public beast::unit_test::Suite
"042b0f6d757461626c652d676c6f62616c732b087369676e2d6578742b0f72"
"65666572656e63652d74797065732b0a6d756c746976616c7565";
env(escrowCreate,
escrow::FinishFunction(badWasmHex),
escrow::Bytecode(badWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees),
Ter(temBAD_WASM));
Ter(temINVALID_BYTECODE));
env.close();
}
}
@@ -365,15 +365,12 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env.fund(XRP(5000), alice, carol);
XRPAmount const txnFees =
env.current()->fees().base * 10 + kLedgerSqnWasmHex.size() / 2 * 5;
env(escrow::finish(carol, alice, 1),
Fee(txnFees),
escrow::CompAllowance(4),
Ter(temDISABLED));
env(escrow::finish(carol, alice, 1), Fee(txnFees), escrow::Gas(4), Ter(temDISABLED));
env.close();
}
{
// ComputationAllowance > max compute limit
// Gas > max compute limit
Env env(
*this,
envconfig([](std::unique_ptr<Config> cfg) {
@@ -391,7 +388,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
auto const allowance = 1'001;
env(escrow::finish(carol, alice, 1),
Fee(env.current()->fees().base + allowance),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Ter(temBAD_LIMIT));
}
@@ -423,7 +420,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
sle->setFieldAmount(sfAmount, XRP(100));
sle->setFieldU32(sfCancelAfter, 110);
sle->setAccountID(sfDestination, alice.id());
sle->setFieldVL(sfFinishFunction, strUnHex(kLedgerSqnWasmHex).value());
sle->setFieldVL(sfBytecode, strUnHex(kLedgerSqnWasmHex).value());
sle->setFieldU32(sfFlags, 0);
sle->setFieldU64(sfOwnerNode, 0);
uint256 tmp;
@@ -440,7 +437,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
BEAST_EXPECT(env.le(keylet));
env(escrow::finish(alice, alice, seq),
escrow::CompAllowance(1000),
escrow::Gas(1000),
Fee(env.current()->fees().base + 1000),
Ter(temTEMP_DISABLED));
}
@@ -460,19 +457,19 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// create escrow
auto const seq = env.seq(alice);
env(escrow::create(alice, carol, XRP(500)),
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees));
env.close();
{
// no ComputationAllowance field
env(escrow::finish(carol, alice, seq), Ter(tefWASM_FIELD_NOT_INCLUDED));
// no Gas field
env(escrow::finish(carol, alice, seq), Ter(tefBYTECODE_NOT_INCLUDED));
}
{
// ComputationAllowance value of 0
env(escrow::finish(carol, alice, seq), escrow::CompAllowance(0), Ter(temBAD_LIMIT));
// Gas value of 0
env(escrow::finish(carol, alice, seq), escrow::Gas(0), Ter(temBAD_LIMIT));
}
{
@@ -482,7 +479,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
auto const finishFee = env.current()->fees().base + 3;
env(escrow::finish(carol, alice, seq),
Fee(finishFee),
escrow::CompAllowance(4),
escrow::Gas(4),
Ter(telINSUF_FEE_P));
}
@@ -493,12 +490,12 @@ struct EscrowSmart_test : public beast::unit_test::Suite
auto const finishFee = env.current()->fees().base + 4;
env(escrow::finish(carol, alice, seq),
Fee(finishFee),
escrow::CompAllowance(2),
escrow::Gas(2),
Ter(tecFAILED_PROCESSING));
}
{
// ComputationAllowance field included w/no FinishFunction on
// Gas field included w/no Bytecode on
// escrow
auto const seq2 = env.seq(alice);
env(escrow::create(alice, carol, XRP(500)),
@@ -510,13 +507,13 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env(escrow::finish(carol, alice, seq2),
Fee(env.current()->fees().base +
(allowance * env.current()->fees().gasPrice) / microDropsPerDrop + 1),
escrow::CompAllowance(allowance),
Ter(tefNO_WASM));
escrow::Gas(allowance),
Ter(tefNO_BYTECODE));
}
}
void
testFinishFunction(FeatureBitset features)
testBytecode(FeatureBitset features)
{
testcase("Example escrow function");
@@ -539,14 +536,14 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}();
{
// basic FinishFunction situation
// basic Bytecode situation
Env env(*this, features);
// create escrow
env.fund(XRP(5000), alice, carol);
auto const seq = env.seq(alice);
BEAST_EXPECT(env.ownerCount(alice) == 0);
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(createFee));
env.close();
@@ -557,25 +554,25 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env.require(Balance(carol, XRP(5000)));
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
env(escrow::finish(alice, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
env(escrow::finish(alice, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
env.close();
{
@@ -590,7 +587,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env(escrow::finish(alice, alice, seq),
Fee(finishFee),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Ter(tesSUCCESS));
auto const txMeta = env.meta();
@@ -600,11 +597,11 @@ struct EscrowSmart_test : public beast::unit_test::Suite
txMeta->getFieldU32(sfGasUsed) == allowance,
std::to_string(txMeta->getFieldU32(sfGasUsed)));
}
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
{
BEAST_EXPECTS(
txMeta->getFieldI32(sfWasmReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfWasmReturnCode)));
txMeta->getFieldI32(sfVMReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfVMReturnCode)));
}
BEAST_EXPECT(env.ownerCount(alice) == 0);
@@ -612,14 +609,14 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}
{
// FinishFunction + Condition
// Bytecode + Condition
Env env(*this, features);
env.fund(XRP(5000), alice, carol);
BEAST_EXPECT(env.ownerCount(alice) == 0);
auto const seq = env.seq(alice);
// create escrow
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCondition(escrow::kCb1),
escrow::kCancelTime(env.now() + 100s),
Fee(createFee));
@@ -634,16 +631,16 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// no fulfillment provided, function fails
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecCRYPTOCONDITION_ERROR));
// fulfillment provided, function fails
env(escrow::finish(carol, alice, seq),
escrow::kCondition(escrow::kCb1),
escrow::kFulfillment(escrow::kFb1),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(conditionFinishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
if (BEAST_EXPECT(env.meta()->isFieldPresent(sfGasUsed)))
{
BEAST_EXPECTS(
@@ -653,21 +650,21 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env.close();
// no fulfillment provided, function succeeds
env(escrow::finish(alice, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(conditionFinishFee),
Ter(tecCRYPTOCONDITION_ERROR));
// wrong fulfillment provided, function succeeds
env(escrow::finish(alice, alice, seq),
escrow::kCondition(escrow::kCb1),
escrow::kFulfillment(escrow::kFb2),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(conditionFinishFee),
Ter(tecCRYPTOCONDITION_ERROR));
// fulfillment provided, function succeeds, tx succeeds
env(escrow::finish(alice, alice, seq),
escrow::kCondition(escrow::kCb1),
escrow::kFulfillment(escrow::kFb1),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(conditionFinishFee),
Ter(tesSUCCESS));
@@ -678,11 +675,11 @@ struct EscrowSmart_test : public beast::unit_test::Suite
txMeta->getFieldU32(sfGasUsed) == allowance,
std::to_string(txMeta->getFieldU32(sfGasUsed)));
}
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
{
BEAST_EXPECTS(
txMeta->getFieldI32(sfWasmReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfWasmReturnCode)));
txMeta->getFieldI32(sfVMReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfVMReturnCode)));
}
env.close();
@@ -691,7 +688,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}
{
// FinishFunction + FinishAfter
// Bytecode + FinishAfter
Env env(*this, features);
// create escrow
env.fund(XRP(5000), alice, carol);
@@ -699,7 +696,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
BEAST_EXPECT(env.ownerCount(alice) == 0);
auto const ts = env.now() + 97s;
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kFinishTime(ts),
escrow::kCancelTime(env.now() + 1000s),
Fee(createFee));
@@ -712,7 +709,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// finish time hasn't passed, function fails
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee + 1),
Ter(tecNO_PERMISSION));
env.close();
@@ -720,24 +717,24 @@ struct EscrowSmart_test : public beast::unit_test::Suite
for (; env.now() < ts; env.close())
{
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee + 2),
Ter(tecNO_PERMISSION));
}
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee + 1),
Ter(tesSUCCESS));
auto const txMeta = env.meta();
if (BEAST_EXPECT(txMeta->isFieldPresent(sfGasUsed)))
BEAST_EXPECT(txMeta->getFieldU32(sfGasUsed) == allowance);
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
{
BEAST_EXPECTS(
txMeta->getFieldI32(sfWasmReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfWasmReturnCode)));
txMeta->getFieldI32(sfVMReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfVMReturnCode)));
}
BEAST_EXPECT(env.ownerCount(alice) == 0);
@@ -745,14 +742,14 @@ struct EscrowSmart_test : public beast::unit_test::Suite
}
{
// FinishFunction + FinishAfter #2
// Bytecode + FinishAfter #2
Env env(*this, features);
// create escrow
env.fund(XRP(5000), alice, carol);
auto const seq = env.seq(alice);
BEAST_EXPECT(env.ownerCount(alice) == 0);
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kFinishTime(env.now() + 2s),
escrow::kCancelTime(env.now() + 100s),
Fee(createFee));
@@ -765,16 +762,16 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// finish time hasn't passed, function fails
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecNO_PERMISSION));
env.close();
// finish time has passed, function fails
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
if (BEAST_EXPECT(env.meta()->isFieldPresent(sfGasUsed)))
{
BEAST_EXPECTS(
@@ -784,18 +781,18 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env.close();
// finish time has passed, function succeeds, tx succeeds
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tesSUCCESS));
auto const txMeta = env.meta();
if (BEAST_EXPECT(txMeta->isFieldPresent(sfGasUsed)))
BEAST_EXPECT(txMeta->getFieldU32(sfGasUsed) == allowance);
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
{
BEAST_EXPECTS(
txMeta->getFieldI32(sfWasmReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfWasmReturnCode)));
txMeta->getFieldI32(sfVMReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfVMReturnCode)));
}
env.close();
@@ -825,7 +822,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
XRPAmount const txnFees =
env.current()->fees().base * 10 + kUpdateDataWasmHex.size() / 2 * 5;
env(escrowCreate,
escrow::FinishFunction(kUpdateDataWasmHex),
escrow::Bytecode(kUpdateDataWasmHex),
escrow::kFinishTime(env.now() + 2s),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees));
@@ -843,9 +840,9 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// FinishAfter time hasn't passed
env(escrow::finish(alice, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecWASM_REJECTED));
Ter(tecBYTECODE_REJECTED));
auto const txMeta = env.meta();
if (BEAST_EXPECT(txMeta && txMeta->isFieldPresent(sfGasUsed)))
@@ -854,11 +851,11 @@ struct EscrowSmart_test : public beast::unit_test::Suite
txMeta->getFieldU32(sfGasUsed) == allowance,
std::to_string(txMeta->getFieldU32(sfGasUsed)));
}
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
{
BEAST_EXPECTS(
txMeta->getFieldI32(sfWasmReturnCode) == -256,
std::to_string(txMeta->getFieldI32(sfWasmReturnCode)));
txMeta->getFieldI32(sfVMReturnCode) == -256,
std::to_string(txMeta->getFieldI32(sfVMReturnCode)));
}
auto const sle = env.le(keylet::escrow(alice, seq));
@@ -908,7 +905,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
auto const seq = env.seq(alice);
BEAST_EXPECT(env.ownerCount(alice) == 0);
env(escrowCreate,
escrow::FinishFunction(kLedgerSqnWasmHex),
escrow::Bytecode(kLedgerSqnWasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(createFee));
env.close();
@@ -930,17 +927,17 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env(escrow::finish(alice, alice, seq),
Fee(finishFeeOverflow), // enough if there's an overflow
escrow::CompAllowance(bigAllowance),
escrow::Gas(bigAllowance),
Ter(telINSUF_FEE_P));
env(escrow::finish(alice, alice, seq),
Fee(finishFee - 1),
escrow::CompAllowance(bigAllowance),
escrow::Gas(bigAllowance),
Ter(telINSUF_FEE_P));
env(escrow::finish(alice, alice, seq),
Fee(finishFee),
escrow::CompAllowance(bigAllowance),
escrow::Gas(bigAllowance),
Ter(tesSUCCESS));
auto const txMeta = env.meta();
@@ -950,11 +947,11 @@ struct EscrowSmart_test : public beast::unit_test::Suite
txMeta->getFieldU32(sfGasUsed) == allowance,
std::to_string(txMeta->getFieldU32(sfGasUsed)));
}
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
{
BEAST_EXPECTS(
txMeta->getFieldI32(sfWasmReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfWasmReturnCode)));
txMeta->getFieldI32(sfVMReturnCode) == 5,
std::to_string(txMeta->getFieldI32(sfVMReturnCode)));
}
BEAST_EXPECT(env.ownerCount(alice) == 0);
@@ -983,7 +980,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
XRPAmount const txnFees =
env.current()->fees().base * 10 + kAllHostFunctionsWasmHex.size() / 2 * 5;
env(escrowCreate,
escrow::FinishFunction(kAllHostFunctionsWasmHex),
escrow::Bytecode(kAllHostFunctionsWasmHex),
escrow::kFinishTime(env.now() + 11s),
escrow::kCancelTime(env.now() + 100s),
escrow::Data("1000000000"), // 1000 XRP in drops
@@ -1002,7 +999,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
// FinishAfter time hasn't passed
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tecNO_PERMISSION));
env.close();
@@ -1015,7 +1012,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
env.close();
env(escrow::finish(alice, alice, seq),
escrow::CompAllowance(allowance),
escrow::Gas(allowance),
Fee(finishFee),
Ter(tesSUCCESS));
@@ -1026,8 +1023,8 @@ struct EscrowSmart_test : public beast::unit_test::Suite
txMeta->getFieldU32(sfGasUsed) == 68'292,
std::to_string(txMeta->getFieldU32(sfGasUsed)));
}
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
BEAST_EXPECT(txMeta->getFieldI32(sfWasmReturnCode) == 1);
if (BEAST_EXPECT(txMeta->isFieldPresent(sfVMReturnCode)))
BEAST_EXPECT(txMeta->getFieldI32(sfVMReturnCode) == 1);
env.close();
BEAST_EXPECT(env.ownerCount(alice) == 0);
@@ -1092,7 +1089,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
XRPAmount const txnFees =
env.current()->fees().base * 10 + kAllKeyletsWasmHex.size() / 2 * 5;
env(escrow::create(alice, carol, XRP(1000)),
escrow::FinishFunction(kAllKeyletsWasmHex),
escrow::Bytecode(kAllKeyletsWasmHex),
escrow::kFinishTime(env.now() + 2s),
escrow::kCancelTime(env.now() + 100s),
Fee(txnFees));
@@ -1103,9 +1100,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
auto const allowance = 184'444;
auto const finishFee = env.current()->fees().base +
(allowance * env.current()->fees().gasPrice) / microDropsPerDrop + 1;
env(escrow::finish(carol, alice, seq),
escrow::CompAllowance(allowance),
Fee(finishFee));
env(escrow::finish(carol, alice, seq), escrow::Gas(allowance), Fee(finishFee));
env.close();
auto const txMeta = env.meta();
@@ -1157,7 +1152,7 @@ struct EscrowSmart_test : public beast::unit_test::Suite
try
{
env(escrow::create(alice, alice, XRP(1000)),
escrow::FinishFunction(wasmHex),
escrow::Bytecode(wasmHex),
escrow::kCancelTime(env.now() + 100s),
Fee(env.current()->fees().base * 10 + wasmHex.size() / 2 * 5),
Ter(expectedStatus == ExpectedStatus::Success ? TER{tesSUCCESS}
@@ -1244,9 +1239,9 @@ struct EscrowSmart_test : public beast::unit_test::Suite
void
testWithFeats(FeatureBitset features)
{
testCreateFinishFunctionPreflight(features);
testCreateBytecodePreflight(features);
testFinishWasmFailures(features);
testFinishFunction(features);
testBytecode(features);
testUpdateDataOnFailure(features);
testFees(features);

View File

@@ -138,7 +138,7 @@ getSection(Bytes const& module, std::uint8_t n)
}
static std::optional<int32_t>
runFinishFunction(std::string const& code)
runFinish(std::string const& code)
{
auto& engine = WasmEngine::instance();
auto const wasm = hexToBytes(code);
@@ -155,7 +155,7 @@ runFinishFunction(std::string const& code)
static bool
finishFunctionReturns(std::string const& code, int32_t expected)
{
auto const result = runFinishFunction(code);
auto const result = runFinish(code);
return result.has_value() && *result == expected;
}
@@ -286,7 +286,7 @@ struct Wasm_test : public beast::unit_test::Suite
}
{
// FinishFunction wrong function name
// Bytecode wrong function name
// pub fn bad() -> bool {
// unsafe { host_lib::getLedgerSqn() >= 5 }
// }
@@ -733,16 +733,16 @@ struct Wasm_test : public beast::unit_test::Suite
{
testcase("Wasm additional memory limit tests");
BEAST_EXPECT(finishFunctionReturns(kMemoryPointerAtLimitHex, 1));
BEAST_EXPECT(!runFinishFunction(kMemoryPointerOverLimitHex).has_value());
BEAST_EXPECT(!runFinishFunction(kMemoryOffsetOverLimitHex).has_value());
BEAST_EXPECT(!runFinishFunction(kMemoryEndOfWordOverLimitHex).has_value());
BEAST_EXPECT(!runFinish(kMemoryPointerOverLimitHex).has_value());
BEAST_EXPECT(!runFinish(kMemoryOffsetOverLimitHex).has_value());
BEAST_EXPECT(!runFinish(kMemoryEndOfWordOverLimitHex).has_value());
BEAST_EXPECT(finishFunctionReturns(kMemoryGrow0To1PageHex, 1));
BEAST_EXPECT(finishFunctionReturns(kMemoryGrow1To0PageHex, -1));
BEAST_EXPECT(finishFunctionReturns(kMemoryLastByteOf8MbHex, 1));
BEAST_EXPECT(finishFunctionReturns(kMemoryGrow1MoreThan8MbHex, -1));
BEAST_EXPECT(finishFunctionReturns(kMemoryGrow0MoreThan8MbHex, 1));
BEAST_EXPECT(!runFinishFunction(kMemoryInit1MoreThan8MbHex).has_value());
BEAST_EXPECT(!runFinishFunction(kMemoryNegativeAddressHex).has_value());
BEAST_EXPECT(!runFinish(kMemoryInit1MoreThan8MbHex).has_value());
BEAST_EXPECT(!runFinish(kMemoryNegativeAddressHex).has_value());
}
void
@@ -750,64 +750,64 @@ struct Wasm_test : public beast::unit_test::Suite
{
testcase("Wasm table limit tests");
BEAST_EXPECT(finishFunctionReturns(kTable64ElementsHex, 1));
BEAST_EXPECT(!runFinishFunction(kTable65ElementsHex).has_value());
BEAST_EXPECT(!runFinishFunction(kTable2TablesHex).has_value());
BEAST_EXPECT(!runFinish(kTable65ElementsHex).has_value());
BEAST_EXPECT(!runFinish(kTable2TablesHex).has_value());
BEAST_EXPECT(finishFunctionReturns(kTable0ElementsHex, 1));
BEAST_EXPECT(!runFinishFunction(kTableUintMaxHex).has_value());
BEAST_EXPECT(!runFinish(kTableUintMaxHex).has_value());
}
void
testWasmProposal()
{
testcase("Wasm disabled proposal tests");
BEAST_EXPECT(!runFinishFunction(kProposalMutableGlobalHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalGcStructNewHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalMultiValueHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalSignExtHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalFloatToIntHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalBulkMemoryHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalRefTypesHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalTailCallHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalExtendedConstHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalMultiMemoryHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalCustomPageSizesHex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalMemory64Hex).has_value());
BEAST_EXPECT(!runFinishFunction(kProposalWideArithmeticHex).has_value());
BEAST_EXPECT(!runFinish(kProposalMutableGlobalHex).has_value());
BEAST_EXPECT(!runFinish(kProposalGcStructNewHex).has_value());
BEAST_EXPECT(!runFinish(kProposalMultiValueHex).has_value());
BEAST_EXPECT(!runFinish(kProposalSignExtHex).has_value());
BEAST_EXPECT(!runFinish(kProposalFloatToIntHex).has_value());
BEAST_EXPECT(!runFinish(kProposalBulkMemoryHex).has_value());
BEAST_EXPECT(!runFinish(kProposalRefTypesHex).has_value());
BEAST_EXPECT(!runFinish(kProposalTailCallHex).has_value());
BEAST_EXPECT(!runFinish(kProposalExtendedConstHex).has_value());
BEAST_EXPECT(!runFinish(kProposalMultiMemoryHex).has_value());
BEAST_EXPECT(!runFinish(kProposalCustomPageSizesHex).has_value());
BEAST_EXPECT(!runFinish(kProposalMemory64Hex).has_value());
BEAST_EXPECT(!runFinish(kProposalWideArithmeticHex).has_value());
}
void
testWasmTrap()
{
testcase("Wasm trap tests");
BEAST_EXPECT(!runFinishFunction(kTrapDivideBy0Hex).has_value());
BEAST_EXPECT(!runFinishFunction(kTrapIntOverflowHex).has_value());
BEAST_EXPECT(!runFinishFunction(kTrapUnreachableHex).has_value());
BEAST_EXPECT(!runFinishFunction(kTrapNullCallHex).has_value());
BEAST_EXPECT(!runFinishFunction(kTrapFuncSigMismatchHex).has_value());
BEAST_EXPECT(!runFinish(kTrapDivideBy0Hex).has_value());
BEAST_EXPECT(!runFinish(kTrapIntOverflowHex).has_value());
BEAST_EXPECT(!runFinish(kTrapUnreachableHex).has_value());
BEAST_EXPECT(!runFinish(kTrapNullCallHex).has_value());
BEAST_EXPECT(!runFinish(kTrapFuncSigMismatchHex).has_value());
}
void
testWasmWasi()
{
testcase("Wasm Wasi tests");
BEAST_EXPECT(!runFinishFunction(kWasiGetTimeHex).has_value());
BEAST_EXPECT(!runFinishFunction(kWasiPrintHex).has_value());
BEAST_EXPECT(!runFinish(kWasiGetTimeHex).has_value());
BEAST_EXPECT(!runFinish(kWasiPrintHex).has_value());
}
void
testWasmSectionCorruption()
{
testcase("Wasm Section Corruption tests");
BEAST_EXPECT(!runFinishFunction(kBadMagicNumberHex).has_value());
BEAST_EXPECT(!runFinishFunction(kBadVersionNumberHex).has_value());
BEAST_EXPECT(!runFinishFunction(kLyingHeaderHex).has_value());
BEAST_EXPECT(!runFinishFunction(kNeverEndingNumberHex).has_value());
BEAST_EXPECT(!runFinishFunction(kVectorLieHex).has_value());
BEAST_EXPECT(!runFinishFunction(kSectionOrderingHex).has_value());
BEAST_EXPECT(!runFinishFunction(kGhostPayloadHex).has_value());
BEAST_EXPECT(!runFinishFunction(kJunkAfterSectionHex).has_value());
BEAST_EXPECT(!runFinishFunction(kInvalidSectionIdHex).has_value());
BEAST_EXPECT(!runFinishFunction(kLocalVariableBombHex).has_value());
BEAST_EXPECT(!runFinish(kBadMagicNumberHex).has_value());
BEAST_EXPECT(!runFinish(kBadVersionNumberHex).has_value());
BEAST_EXPECT(!runFinish(kLyingHeaderHex).has_value());
BEAST_EXPECT(!runFinish(kNeverEndingNumberHex).has_value());
BEAST_EXPECT(!runFinish(kVectorLieHex).has_value());
BEAST_EXPECT(!runFinish(kSectionOrderingHex).has_value());
BEAST_EXPECT(!runFinish(kGhostPayloadHex).has_value());
BEAST_EXPECT(!runFinish(kJunkAfterSectionHex).has_value());
BEAST_EXPECT(!runFinish(kInvalidSectionIdHex).has_value());
BEAST_EXPECT(!runFinish(kLocalVariableBombHex).has_value());
}
void

View File

@@ -77,29 +77,29 @@ auto const kCondition = JTxFieldWrapper<BlobField>(sfCondition);
auto const kFulfillment = JTxFieldWrapper<BlobField>(sfFulfillment);
struct FinishFunction
struct Bytecode
{
private:
std::string value_;
public:
explicit FinishFunction(std::string func) : value_(std::move(func))
explicit Bytecode(std::string func) : value_(std::move(func))
{
}
explicit FinishFunction(Slice const& func) : value_(strHex(func))
explicit Bytecode(Slice const& func) : value_(strHex(func))
{
}
template <size_t N>
explicit FinishFunction(std::array<std::uint8_t, N> const& f) : FinishFunction(makeSlice(f))
explicit Bytecode(std::array<std::uint8_t, N> const& f) : Bytecode(makeSlice(f))
{
}
void
operator()(Env&, JTx& jt) const
{
jt.jv[sfFinishFunction.jsonName] = value_;
jt.jv[sfBytecode.jsonName] = value_;
}
};
@@ -129,20 +129,20 @@ public:
}
};
struct CompAllowance
struct Gas
{
private:
std::uint32_t value_;
public:
explicit CompAllowance(std::uint32_t const& value) : value_(value)
explicit Gas(std::uint32_t const& value) : value_(value)
{
}
void
operator()(Env&, JTx& jt) const
{
jt.jv[sfComputationAllowance.jsonName] = value_;
jt.jv[sfGas.jsonName] = value_;
}
};

View File

@@ -27,7 +27,7 @@ TEST(EscrowTests, BuilderSettersRoundTrip)
auto const conditionValue = canonical_VL();
auto const cancelAfterValue = canonical_UINT32();
auto const finishAfterValue = canonical_UINT32();
auto const finishFunctionValue = canonical_VL();
auto const bytecodeValue = canonical_VL();
auto const dataValue = canonical_VL();
auto const sourceTagValue = canonical_UINT32();
auto const destinationTagValue = canonical_UINT32();
@@ -51,7 +51,7 @@ TEST(EscrowTests, BuilderSettersRoundTrip)
builder.setCondition(conditionValue);
builder.setCancelAfter(cancelAfterValue);
builder.setFinishAfter(finishAfterValue);
builder.setFinishFunction(finishFunctionValue);
builder.setBytecode(bytecodeValue);
builder.setData(dataValue);
builder.setSourceTag(sourceTagValue);
builder.setDestinationTag(destinationTagValue);
@@ -137,11 +137,11 @@ TEST(EscrowTests, BuilderSettersRoundTrip)
}
{
auto const& expected = finishFunctionValue;
auto const actualOpt = entry.getFinishFunction();
auto const& expected = bytecodeValue;
auto const actualOpt = entry.getBytecode();
ASSERT_TRUE(actualOpt.has_value());
expectEqualField(expected, *actualOpt, "sfFinishFunction");
EXPECT_TRUE(entry.hasFinishFunction());
expectEqualField(expected, *actualOpt, "sfBytecode");
EXPECT_TRUE(entry.hasBytecode());
}
{
@@ -212,7 +212,7 @@ TEST(EscrowTests, BuilderFromSleRoundTrip)
auto const conditionValue = canonical_VL();
auto const cancelAfterValue = canonical_UINT32();
auto const finishAfterValue = canonical_UINT32();
auto const finishFunctionValue = canonical_VL();
auto const bytecodeValue = canonical_VL();
auto const dataValue = canonical_VL();
auto const sourceTagValue = canonical_UINT32();
auto const destinationTagValue = canonical_UINT32();
@@ -232,7 +232,7 @@ TEST(EscrowTests, BuilderFromSleRoundTrip)
sle->at(sfCondition) = conditionValue;
sle->at(sfCancelAfter) = cancelAfterValue;
sle->at(sfFinishAfter) = finishAfterValue;
sle->at(sfFinishFunction) = finishFunctionValue;
sle->at(sfBytecode) = bytecodeValue;
sle->at(sfData) = dataValue;
sle->at(sfSourceTag) = sourceTagValue;
sle->at(sfDestinationTag) = destinationTagValue;
@@ -365,16 +365,16 @@ TEST(EscrowTests, BuilderFromSleRoundTrip)
}
{
auto const& expected = finishFunctionValue;
auto const& expected = bytecodeValue;
auto const fromSleOpt = entryFromSle.getFinishFunction();
auto const fromBuilderOpt = entryFromBuilder.getFinishFunction();
auto const fromSleOpt = entryFromSle.getBytecode();
auto const fromBuilderOpt = entryFromBuilder.getBytecode();
ASSERT_TRUE(fromSleOpt.has_value());
ASSERT_TRUE(fromBuilderOpt.has_value());
expectEqualField(expected, *fromSleOpt, "sfFinishFunction");
expectEqualField(expected, *fromBuilderOpt, "sfFinishFunction");
expectEqualField(expected, *fromSleOpt, "sfBytecode");
expectEqualField(expected, *fromBuilderOpt, "sfBytecode");
}
{
@@ -527,8 +527,8 @@ TEST(EscrowTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(entry.getCancelAfter().has_value());
EXPECT_FALSE(entry.hasFinishAfter());
EXPECT_FALSE(entry.getFinishAfter().has_value());
EXPECT_FALSE(entry.hasFinishFunction());
EXPECT_FALSE(entry.getFinishFunction().has_value());
EXPECT_FALSE(entry.hasBytecode());
EXPECT_FALSE(entry.getBytecode().has_value());
EXPECT_FALSE(entry.hasData());
EXPECT_FALSE(entry.getData().has_value());
EXPECT_FALSE(entry.hasSourceTag());

View File

@@ -35,7 +35,7 @@ TEST(TransactionsEscrowCreateTests, BuilderSettersRoundTrip)
auto const conditionValue = canonical_VL();
auto const cancelAfterValue = canonical_UINT32();
auto const finishAfterValue = canonical_UINT32();
auto const finishFunctionValue = canonical_VL();
auto const bytecodeValue = canonical_VL();
auto const dataValue = canonical_VL();
EscrowCreateBuilder builder{
@@ -51,7 +51,7 @@ TEST(TransactionsEscrowCreateTests, BuilderSettersRoundTrip)
builder.setCondition(conditionValue);
builder.setCancelAfter(cancelAfterValue);
builder.setFinishAfter(finishAfterValue);
builder.setFinishFunction(finishFunctionValue);
builder.setBytecode(bytecodeValue);
builder.setData(dataValue);
auto tx = builder.build(publicKey, secretKey);
@@ -115,11 +115,11 @@ TEST(TransactionsEscrowCreateTests, BuilderSettersRoundTrip)
}
{
auto const& expected = finishFunctionValue;
auto const actualOpt = tx.getFinishFunction();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfFinishFunction should be present";
expectEqualField(expected, *actualOpt, "sfFinishFunction");
EXPECT_TRUE(tx.hasFinishFunction());
auto const& expected = bytecodeValue;
auto const actualOpt = tx.getBytecode();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBytecode should be present";
expectEqualField(expected, *actualOpt, "sfBytecode");
EXPECT_TRUE(tx.hasBytecode());
}
{
@@ -152,7 +152,7 @@ TEST(TransactionsEscrowCreateTests, BuilderFromStTxRoundTrip)
auto const conditionValue = canonical_VL();
auto const cancelAfterValue = canonical_UINT32();
auto const finishAfterValue = canonical_UINT32();
auto const finishFunctionValue = canonical_VL();
auto const bytecodeValue = canonical_VL();
auto const dataValue = canonical_VL();
// Build an initial transaction
@@ -168,7 +168,7 @@ TEST(TransactionsEscrowCreateTests, BuilderFromStTxRoundTrip)
initialBuilder.setCondition(conditionValue);
initialBuilder.setCancelAfter(cancelAfterValue);
initialBuilder.setFinishAfter(finishAfterValue);
initialBuilder.setFinishFunction(finishFunctionValue);
initialBuilder.setBytecode(bytecodeValue);
initialBuilder.setData(dataValue);
auto initialTx = initialBuilder.build(publicKey, secretKey);
@@ -229,10 +229,10 @@ TEST(TransactionsEscrowCreateTests, BuilderFromStTxRoundTrip)
}
{
auto const& expected = finishFunctionValue;
auto const actualOpt = rebuiltTx.getFinishFunction();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfFinishFunction should be present";
expectEqualField(expected, *actualOpt, "sfFinishFunction");
auto const& expected = bytecodeValue;
auto const actualOpt = rebuiltTx.getBytecode();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBytecode should be present";
expectEqualField(expected, *actualOpt, "sfBytecode");
}
{
@@ -309,8 +309,8 @@ TEST(TransactionsEscrowCreateTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(tx.getCancelAfter().has_value());
EXPECT_FALSE(tx.hasFinishAfter());
EXPECT_FALSE(tx.getFinishAfter().has_value());
EXPECT_FALSE(tx.hasFinishFunction());
EXPECT_FALSE(tx.getFinishFunction().has_value());
EXPECT_FALSE(tx.hasBytecode());
EXPECT_FALSE(tx.getBytecode().has_value());
EXPECT_FALSE(tx.hasData());
EXPECT_FALSE(tx.getData().has_value());
}

View File

@@ -34,7 +34,7 @@ TEST(TransactionsEscrowFinishTests, BuilderSettersRoundTrip)
auto const fulfillmentValue = canonical_VL();
auto const conditionValue = canonical_VL();
auto const credentialIDsValue = canonical_VECTOR256();
auto const computationAllowanceValue = canonical_UINT32();
auto const gasValue = canonical_UINT32();
EscrowFinishBuilder builder{
accountValue,
@@ -48,7 +48,7 @@ TEST(TransactionsEscrowFinishTests, BuilderSettersRoundTrip)
builder.setFulfillment(fulfillmentValue);
builder.setCondition(conditionValue);
builder.setCredentialIDs(credentialIDsValue);
builder.setComputationAllowance(computationAllowanceValue);
builder.setGas(gasValue);
auto tx = builder.build(publicKey, secretKey);
@@ -103,11 +103,11 @@ TEST(TransactionsEscrowFinishTests, BuilderSettersRoundTrip)
}
{
auto const& expected = computationAllowanceValue;
auto const actualOpt = tx.getComputationAllowance();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfComputationAllowance should be present";
expectEqualField(expected, *actualOpt, "sfComputationAllowance");
EXPECT_TRUE(tx.hasComputationAllowance());
auto const& expected = gasValue;
auto const actualOpt = tx.getGas();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGas should be present";
expectEqualField(expected, *actualOpt, "sfGas");
EXPECT_TRUE(tx.hasGas());
}
}
@@ -131,7 +131,7 @@ TEST(TransactionsEscrowFinishTests, BuilderFromStTxRoundTrip)
auto const fulfillmentValue = canonical_VL();
auto const conditionValue = canonical_VL();
auto const credentialIDsValue = canonical_VECTOR256();
auto const computationAllowanceValue = canonical_UINT32();
auto const gasValue = canonical_UINT32();
// Build an initial transaction
EscrowFinishBuilder initialBuilder{
@@ -145,7 +145,7 @@ TEST(TransactionsEscrowFinishTests, BuilderFromStTxRoundTrip)
initialBuilder.setFulfillment(fulfillmentValue);
initialBuilder.setCondition(conditionValue);
initialBuilder.setCredentialIDs(credentialIDsValue);
initialBuilder.setComputationAllowance(computationAllowanceValue);
initialBuilder.setGas(gasValue);
auto initialTx = initialBuilder.build(publicKey, secretKey);
@@ -198,10 +198,10 @@ TEST(TransactionsEscrowFinishTests, BuilderFromStTxRoundTrip)
}
{
auto const& expected = computationAllowanceValue;
auto const actualOpt = rebuiltTx.getComputationAllowance();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfComputationAllowance should be present";
expectEqualField(expected, *actualOpt, "sfComputationAllowance");
auto const& expected = gasValue;
auto const actualOpt = rebuiltTx.getGas();
ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGas should be present";
expectEqualField(expected, *actualOpt, "sfGas");
}
}
@@ -269,8 +269,8 @@ TEST(TransactionsEscrowFinishTests, OptionalFieldsReturnNullopt)
EXPECT_FALSE(tx.getCondition().has_value());
EXPECT_FALSE(tx.hasCredentialIDs());
EXPECT_FALSE(tx.getCredentialIDs().has_value());
EXPECT_FALSE(tx.hasComputationAllowance());
EXPECT_FALSE(tx.getComputationAllowance().has_value());
EXPECT_FALSE(tx.hasGas());
EXPECT_FALSE(tx.getGas().has_value());
}
}