Skip to content

v11.14.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 00:10
33e6ad1
  • Breaking: BaseAsset and QuoteAsset of PriceData (Xrpl.BinaryCodec 11.14.0.0) encode a three-character code at bytes 12-14, as rippled and xrpl.js encode every Currency field. The codec wrote it at bytes 0-2, which the ledger holds as a different, nonstandard currency: an oracle published by the SDK with USD was shown by the node as 5553440000000000000000000000000000000000, was not found by get_aggregate_price for USD, and did not aggregate with oracles published by other SDKs. Currency.FromOracleJson, Currency.FromOracleString and Currency.EncodeOracleCurrency are removed; Currency.GetCurrencyCodeFromTlcBytes no longer reads text at bytes 0-2 as a standard code, and OracleCurrencyConverter reads such a value as hex instead of as the three characters. Migration: an oracle the SDK published with a three-character code holds the nonstandard code; send OracleSet again with the same codes to store the standard ones, and delete the old pairs if they are no longer wanted

  • IXrplClient.GetAggregatePrice with GetAggregatePriceRequest, OracleIdentifier, GetAggregatePriceResponse and AggregatePriceSet (get_aggregate_price). AggregatePriceAssetConverter writes base_asset / quote_asset in the form rippled displays the stored currency in, which is what the node compares them with. The time filter is sent as time_threshold, the name rippled reads; the xrpl.org reference and xrpl.js name it trim_threshold

  • IXrplClient.BookChanges with BookChangesRequest and BookChangesResponse (book_changes). Without a ledger, rippled answers for the open ledger, not a validated one

  • IXrplClient.Manifest with ManifestRequest, ManifestResponse and ManifestDetails (manifest). For a key with no manifest, rippled answers with details naming the key as both master and ephemeral key, without manifest or seq; the xrpl.js model expects details to be absent instead

  • IXrplClient.Version with VersionResponse and ApiVersionRange (version). first, good and last are read as strings: rippled sends the strings 1.0.0 to API version 1 requests and the numbers of the supported range to later ones

  • IXrplClient.GetAggregatePrice, BookChanges, Manifest and Version have default implementations that call GRequest, so an existing IXrplClient implementation compiles without them

  • PathFindCreateRequest.Domain (domain): the streaming path_find create searches a permissioned domain's books, as RipplePathFindRequest.Domain does for ripple_path_find. Without it, a search for a Payment with DomainID quoted the open books. PathFindCreateRequest.SendMax documents that rippled accepts it only with a DestinationAmount of -1

  • BookChange (the book_changes stream and method) gains MptIssuanceIdA, MptIssuanceIdB and Domain, which rippled sends for an MPT side and for a permissioned-domain book; AssetA / AssetB carry the MPT issuance ID for an MPT side

  • TakerAmount (book_offers) gains MptIssuanceId (mpt_issuance_id), the MPT side of an order book under MPTokensV2 (XLS-82), and TakerAmount.FromAsset(IssuedCurrency), which builds the side of XRP, an issued currency or an MPT. DexSnapshotLoader and BookIndex build their book_offers sides with it, so an MPT side is asked for by its issuance ID rather than with neither currency nor issuer

  • BookOffersRequest.Validate() checks a request as rippled develop's book_offers handler does, in its order: mpt_issuance_id excludes currency and issuer and is 48 hex digits; currency and issuer are parsed as toCurrency and toIssuer parse them, with XRP taking no issuer and an issued currency requiring one other than account one; taker is an address, domain 64 hex digits; and two sides naming one asset are badMarket. Messages name the field and the rippled error code

  • Behaviour change: IXrplClient.BookOffers calls Validate() and raises ValidationException before sending a request the node would refuse; such a request used to reach the node and fail with RippledException

  • OfferCreateCrossing, PaymentFlow and PathFinding cross, pay and find paths through MPT order books (MPTokensV2, XLS-82), ported from rippled 3.4.0; the NotSupportedException they threw for an MPT side, payment or path step is gone. Ported: MPTEndpointStep (MptEndpointStep), toStrand's MPT path elements and no-rippling rules, BookStep's MPT transfer rate, WeakAuth and checkMPTDEX checks, issuer input cap, overflow removal, checkCreateMPT and issuerSelfDebitHookMPT, OfferStream's issuerFundsToSelfIssue, directSendNoFeeMPT with PaymentSandbox's creditMPT, balanceHookMPT and balanceHookSelfIssueMPT, accountHolds / accountFunds / requireAuth / canTrade / canTransfer for MPT, OfferCreate's MPT preflight and preclaim (temDISABLED, tecLOCKED, an unfunded MPT issuer, checkAcceptAsset, canTrade), the tick size leaving an MPT side exact and an unrepresentable quality not placed, Payment's pre-MPTokensV2 direct MPT payment with its transfer fee, getBookBase's tagged MPT book keys, and the path finder's getMPTs, PathFindMPT::canSend, MPT account links, books and path counts

  • DexSnapshot.MptIssuances (DexMptIssuance) and DexSnapshot.MptHoldings (DexMptHolding); DexSnapshot.FromNodeAsync reads the issuances and MPTokens of the strands, offers and pools it covers, and UnlimitedTaker holds plenty of an MPT it pays

  • OfferCrossingResult.MpTokens and PaymentFlowResult.MpTokens (MpTokenChange): the MPTokens a transaction creates. BalanceChanges report MPT holdings, and an issuer's change as the negated change of OutstandingAmount, as BalanceChanges.GetBalanceChanges reads the metadata

  • OfferRemovalReason.Overflow

  • OfferCreateCrossing.RoundToTickSize leaves an MPT side as given

  • BookIndex reads MPT book directories (TakerPaysMPT, TakerGetsMPT), and BookIndex.FromAccountsAsync adds the MPTs the accounts issue or hold. PathFindRequest.SourceCurrencies names an MPT by MptIssuanceId; PathFindResult.DestinationCurrencies lists the destination's MPT issuance IDs

  • SourceCurrency.MptIssuanceId (mpt_issuance_id) for ripple_path_find

  • Docs: "MPTs on the DEX" in the Amounts guide (DocFx/Amounts-Guide.md, Amounts-Guide.ru.md)

  • CI: MPTEndpointStep.cpp, TokenHelpers.h, MPTokenHelpers.h / .cpp, MPTAmount.h / .cpp, PathAsset.h, Indexes.cpp and rpc/detail/MPT.h are on the engine-watch list of protocol-watch.yml

  • CI: .ci-config/check-rpc-methods.sh with .ci-config/rpc-methods-ignore.txt, run by the rpc-methods job of protocol-watch.yml, compares rippled develop's RPC method names with the SDK's request models, with no method left as a gap; MethodNames.h and handlers/Handlers.h are on the protocol-watch list. submit_multisigned is listed as covered: a multi-signed blob goes through submit (Signer.Multisign, SubmitMulti)

  • Tests: TestUGetAggregatePrice; TestIOracle aggregates prices with trim, with a nonstandard code and with time_threshold, and asks for an unpriced pair; TestUOracleSet compares the OracleSet encoding byte for byte with xrpl.js and replaces TestVerify_CurrencyOracleEncoding with TestVerify_CurrencyEncoding_StandardCodeAtIsoPosition; TestUOracleCurrencyConverter.Read_HexCode40Chars_ThreeCharsAtByteZero_StaysHex; TestUBookChangesManifestVersion; TestURequestSerialization covers domain in path_find create; TestIPathFinding.PathFindCreateThroughADomainBook checks that path_find quotes the domain's book as ripple_path_find does; TestIBookChangesManifestVersion reads the trade of an offer crossing back through book_changes, the manifest of a key without one, and the API version range; TestISubmitMultisigned, an empty stub that tested nothing, is removed (multi-signed submission is covered by TestIMultisign); TestUBookOffersMpt; TestUMptDex builds strands as rippled's PayStrandMPT_test pins them and crosses and pays MPTs worked out by hand; TestUOfferCreateCrossing.MptSidesAreNotSupported is removed; TestIMptDex predicts each crossing and payment with OfferCreateCrossing and PaymentFlow and compares it with the node through BookCrossingHarness - offers pairing an MPT with XRP and with an issued currency, the taker's MPToken created, a transfer fee rounded up, a walked MPT book, an issuer's own offer at its maximum, an MPT/XRP pool crossed with the book, a locked issuance, payments from XRP and from an issued currency, with a fee and between holders, a locked sender - reads MPT books through book_offers, and sends the requests Validate() refuses to the node and gets the same errors back; TestIPathFinding compares MPT searches with ripple_path_find (XRP to an MPT, an MPT as the source currency, XRP to an issued currency bridged through an MPT book, the holder's MPT among every source asset) and searches at the stand's [path_search] of 7, which ripple_path_find uses, instead of 2; BookCrossingHarness.AdjustRules turns MPTokensV2 on for a standalone stand, where it is a [features] preset, and AssertMpTokens compares the MPTokens created

  • Breaking (source, named arguments only): LoanSigningHelper names its LoanSet parties by role, submitter (Account) and counterparty, instead of broker and borrower (#276). rippled takes the counterparty as Counterparty, or the LoanBroker's owner when the field is omitted, and needs one of Account and the counterparty to be the owner, so the borrower may submit and the broker owner co-sign. Renamed parameters: PrepareForSigning(…, submitterWallet), SignLoanSet(…, submitterWallet, counterpartyWallet), CombineLoanSignatures(submitterSignedBlob, counterpartySignedBlob). Migration: a call passing these by name uses the new names; positional calls are unchanged

  • LoanSigningHelper.SignLoanSet takes the two wallets in either order and gives the TxnSignature to the one whose address is Account; it refused a borrower-submitted LoanSet whose Counterparty is the broker owner. It throws when neither wallet is Account, or when the other wallet is not Counterparty. The new overload SignLoanSet(preparedTx, submitterWallet, counterpartyWallet, brokerOwner) also checks the counterparty when Counterparty is omitted and that one of the two parties is the broker owner

  • LoanSigningHelper.SubmitterSign replaces BrokerSign, which is [Obsolete] and forwards to it

  • Docs: ILoanSet.Counterparty, LoanSet, LoanSigningHelper, XrplWallet.SignAsLoanCounterparty and LendingProtocol-Guide (both languages) describe the two roles

  • Tests: TestULoanSigningRoles; TestILoanBorrowerSubmits submits a LoanSet from the borrower with Counterparty set to the broker owner, with it omitted, and with the broker owner signing first, gated on AmendmentGuard.LendingProtocol

  • Validation.ValidateLoanManage accepts a LoanManage with no action flag, as rippled's LoanManage::preflight does: it rejects only more than one of tfLoanDefault, tfLoanImpair and tfLoanUnimpair (temINVALID_FLAG), and doApply treats none as a no-op (#277). It refused a transaction with Flags absent, zero, or carrying only tfInnerBatchTxn. LoanManage, LoanManageFlags and LendingProtocol-Guide document the no-op

  • Tests: TestULoanManage

  • Breaking: ITransactionCommon gains SponsorSignature and ILoanSet gains CounterpartySignature, both SignatureObject (#278). TransactionRequest and TransactionResponse implement the first, LoanSet and LoanSetResponse the second. A request model dropped either co-signature when deserialized and written back with ToJson; a response kept it only as raw JSON in UnknownFields, where it no longer appears. Migration: a class implementing ITransactionCommon or ILoanSet directly adds the property; code reading either field from UnknownFields reads the typed property

  • SignatureObjectConverter writes a SignatureObject in its wire shape (SigningPubKey and TxnSignature, or Signers with each entry wrapped in Signer) and reads one without enforcing a form, so a Batch inner marker - an empty object, or an empty SigningPubKey - writes back as it came. SignatureObject.ValidateShape also refuses a Signer entry that nests Signers, which FromJsonObject refused before through its recursive parse. Both fields are not signing fields in the codec, so they change no signing preimage

  • SignatureResult.GetTx keeps both co-signatures instead of refusing a blob that carries them, so a partially signed LoanSet decodes and its submitter's Sign of the typed transaction gives the blob LoanSigningHelper.SubmitterSign gives

  • Tests: TestUCoSignatureFields round-trips both fields in single and multisig form through the request and response models, checks that the signing preimage under the transaction, counterparty and sponsor prefixes is unchanged by them, signs a decoded partially signed LoanSet, and round-trips the Batch inner markers; TestUSignatureResultRoundTrip refuses an unmodelled field (Destination on a LoanSet) and keeps CounterpartySignature

  • Validation.ValidateBatch (and BatchUtils.Build, which calls it) no longer rejects Vault, LoanBroker and Loan inner transactions. rippled develop refuses them (kDisabledTxTypes → temINVALID_INNER_BATCH) only while LendingProtocolV1_2 is not enabled (rippled #8244); the offline check has no ledger rules, so the node decides. DisabledInnerTxTypes is removed

  • Tests: TestUBatchCoSigning.TestUValidateBatch_LendingInner_LeftToTheNode (all fifteen types) and TestUBuildBatch_TypedLoanSetAndVaultDeposit_Builds replace TestUValidateBatch_LoanOrVaultInner_Throws; TestIBatchInnerTypes.Batch_Inner_VaultCreate_RejectedByNodeBeforeLendingProtocolV12 and Batch_Inner_VaultCreate_WithLendingProtocolV12, gated on AmendmentGuard.LendingProtocolV12; the Sponsorship guide describes the amendment gate

  • Xrpl.Amounts ports the integer-arithmetic hardening of rippled 3.4.1 in the payment engine: StrandFlow.Run returns tecPATH_DRY when an XRP or MPT sum of the strands' ins or outs leaves int64 (checkedStepAddOpt), and BookCrossingStep fails the strand with tecPATH_DRY when its sum does (checkedStepAdd). New: StepMath.CheckedAdd and StepMath.TrySum

  • CI: engine-watch's baseline_ref in protocol-watch.yml is 3.4.1

  • Docs: the Amounts guide (DocFx/Amounts-Guide.md, Amounts-Guide.ru.md) and the summaries of OfferCreateCrossing, PaymentFlow, Pathfinder and PathFinding name rippled 3.4.1 as the release the engine follows

  • Tests: TestUCheckedStepAdd replays the checkedAdd assertions of MathUtilities.h on MPT and XRP amounts and checks the step and flow sums