Description
Protocol 22: Additional Changes
Interface Compatibility
In the previous announcement about the upcoming changes for Protocol 22, we made a significant oversight in compatibility. When a user upgrades to the latest version of your SDK, their code will now only be compatible with a v22.*
version of the backend services they're connected to. This means they can only upgrade exactly when their RPC/Horizon provider upgrades, which is a violation of the previous compatibility guarantees we provide the ecosystem. That guideline essentially boils down to:
You can safely upgrade your SDK prior to the next major version upgrade.
To maintain this principle, we are releasing new release candidates of Horizon and Stellar RPC to increase the backwards-compatibility of various interfaces and make it easier for people to have a smooth upgrade. We are also asking SDK maintainers to use these new, smoother interfaces to ensure that users can upgrade to the latest version of their SDKs without requiring their use exclusively with Protocol 22-compatible software. In other words, users should be able to upgrade today and not rely on v22 versions of Horizon or RPC deployed for their dependent network.
Stellar RPC: v22.0.0-rc3
In this release, we are reintroducing fields that previously constituted breaking changes:
- Previously, in RC2,
getTransactions
would encodecreatedAt
as astring
instead ofnumber
. This change has been reverted. The next release will continue to encode it as anumber
(specifically, auint32
). - Previously,
getVersionInfo
would now use camelCasing over snake_case. This change is now additive. The response schema in the next release will contains both variants:
interface GetVersionInfoResponse {
version: string;
commitHash: string;
buildTimestamp: string;
captiveCoreVersion: string;
protocolVersion: number; // uint32
/// Deprecated field names:
commit_hash: string;
build_timestamp: string;
captive_core_version: string;
protocol_version: number; // uint32
}
- Previously,
getEvents
replacedpagingToken
withcursor
within each event for pagination. This change is now additive, and the response schema will now include both fields. Please note that theid
field will continue to match both the oldpagingToken
and the newcursor
. - Previously,
simulateTransaction
removed the deprecatedcost
field. This change remains, because it does not require a "lockstep" upgrade with their provider: users can acquire the new costs by extracting them from the transaction resource data. For example,
// before:
let result = await server.simulateTranasction(tx);
// assume result.error === undefined
let cost: rpc.Api.Cost = result.cost;
// after:
let resources = result.transactionData.build().resources();
let cost: rpc.Api.Cost = {
cpuInsns: resources.instructions().toString(),
memBytes: (resources.readBytes() + resources.writeBytes()).toString(),
};
- Previously, the
getLedgerEntry
endpoint had been removed entirely. This change remains, because clients can transition togetLedgerEntries
without waiting on a provider upgrade. For example,
# before, the JSON-RPC request would have
{
# ...
"method": "getLedgerEntry",
"params": {
"key": "insert base64 xdr here"
}
}
# now it will have
{
# ...
"method": "getLedgerEntries",
"params": {
"keys": [ "insert base64 xdr here" ]
}
}
Horizon: v22.0.0-rc2
Similarly, we are reintroducing fields that previously constituted breaking changes:
- Previously, the
/transaction_async
endpoint changederrorResultXdr
➡️error_result_xdr
. This change is now additive, and in the next release the response schema will have both fields. - Previously, the
/asset
endpoint droppednum_accounts
andamount
, and the/transactions/:id
endpoint droppedvalid_before
andvalid_after
. These changes remain, because the values still exist in other locations. Namely,num_accounts
andamount
are inside ofaccounts
, whilevalid_before
andvalid_after
are equivalent to the values in thepreconditions
object.
Maintainer Actions
Please ensure that users can upgrade to your latest SDK version without depending exclusively on the breaking schemas in Horizon v22.0.0-rc1 and Stellar RPC v22.0.0-rc2. Users should be able to upgrade today and not rely on v22 versions of Horizon or RPC deployed for their dependent network.
Please release your Protocol-22 compatible software releases as release candidates, because things are still subject to change.
As outlined above, breaking changes are still acceptable if there is an alternative, client-side way of acquiring the same field but not if the field is only present in a v22 version of the backend service. These are part of the natural transition to a new version that clients should be prepared for.
A concrete example: someone with an existing codebase may have code written that uses the createdAt
field returned by rpc.getTransaction
. If they upgrade to the latest version, their code will break because the field is now strictly typed as a string
. And yet, if they were to update their code accordingly, their code would not function unless they pointed at a v22 RPC. This is the lockstep upgrade we are trying to avoid. This is in contrast to a change like cost
being removed, because they can write code that works on both v21 and v22 RPCs by using the existing transactionData
field to migrate.
Reference Implementations
JavaScript: stellar/js-stellar-sdk#1084
Activity