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.
In this release, we are reintroducing fields that previously constituted breaking changes:
- Previously, in RC2,
getTransactions would encode createdAt as a string instead of number. This change has been reverted. The next release will continue to encode it as a number (specifically, a uint32).
- 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 replaced pagingToken with cursor within each event for pagination. This change is now additive, and the response schema will now include both fields. Please note that the id field will continue to match both the old pagingToken and the new cursor.
- Previously,
simulateTransaction removed the deprecated cost 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 to getLedgerEntries 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" ]
}
}
Similarly, we are reintroducing fields that previously constituted breaking changes:
- Previously, the
/transaction_async endpoint changed errorResultXdr ➡️ error_result_xdr. This change is now additive, and in the next release the response schema will have both fields.
- Previously, the
/asset endpoint dropped num_accounts and amount, and the /transactions/:id endpoint dropped valid_before and valid_after. These changes remain, because the values still exist in other locations. Namely, num_accounts and amount are inside of accounts, while valid_before and valid_after are equivalent to the values in the preconditions 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
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: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-rc3In this release, we are reintroducing fields that previously constituted breaking changes:
getTransactionswould encodecreatedAtas astringinstead ofnumber. This change has been reverted. The next release will continue to encode it as anumber(specifically, auint32).getVersionInfowould now use camelCasing over snake_case. This change is now additive. The response schema in the next release will contains both variants:getEventsreplacedpagingTokenwithcursorwithin each event for pagination. This change is now additive, and the response schema will now include both fields. Please note that theidfield will continue to match both the oldpagingTokenand the newcursor.simulateTransactionremoved the deprecatedcostfield. 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,getLedgerEntryendpoint had been removed entirely. This change remains, because clients can transition togetLedgerEntrieswithout waiting on a provider upgrade. For example,Horizon:
v22.0.0-rc2Similarly, we are reintroducing fields that previously constituted breaking changes:
/transaction_asyncendpoint changederrorResultXdr➡️error_result_xdr. This change is now additive, and in the next release the response schema will have both fields./assetendpoint droppednum_accountsandamount, and the/transactions/:idendpoint droppedvalid_beforeandvalid_after. These changes remain, because the values still exist in other locations. Namely,num_accountsandamountare inside ofaccounts, whilevalid_beforeandvalid_afterare equivalent to the values in thepreconditionsobject.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
createdAtfield returned byrpc.getTransaction. If they upgrade to the latest version, their code will break because the field is now strictly typed as astring. 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 likecostbeing removed, because they can write code that works on both v21 and v22 RPCs by using the existingtransactionDatafield to migrate.Reference Implementations
JavaScript: stellar/js-stellar-sdk#1084