Skip to content

Latest commit

 

History

History
860 lines (803 loc) · 25.4 KB

cap-0046.md

File metadata and controls

860 lines (803 loc) · 25.4 KB

Preamble

CAP: 0046
Title: Soroban smart contract system overview
Working Group:
    Owner: Graydon Hoare <@graydon>
    Authors: Graydon Hoare <@graydon>, Siddharth Suresh <@sisuresh>, Dmytro Kozhevin <@dmkozh>, Jay Geng <@jayz22>, Garand Tyson <@SirTyson>
    Consulted: Leigh McCulloch <@leighmcculloch>, Tomer Weller <@tomerweller>, Jon Jove <@jonjove>, Nicolas Barry <@MonsieurNicolas>, Thibault de Lacheze-Murel <@C0x41lch0x41>
Status: Final
Created: 2022-10-27
Discussion: 
Protocol version: 20

Simple Summary

This CAP is an overview of changes to stellar-core and the Stellar Protocol needed to enable the Soroban smart contract system.

Various aspects of the system design are described in Soroban "sub-CAPs". This "overview CAP" exists to

  • Discuss motivation and design choices across the overall project, to avoid repeating it in each sub-CAP.
  • Give a cumulative XDR diff covering changes made in all related CAPs, to ease the burden of keeping the XDR diff current during development.
  • Link to and describe the relationships between sub-CAPs and the XDR changes.

Working Group

The authors of the linked sub-CAPs are members of SDF's core team. Each sub-CAP lists an owner.

Consultation on the Soroban project's core design necessarily encompasses a large proportion of the Stellar ecosystem. It has included and will continue to include members of the Horizon team, the Security team, the teams building the Soroban SDK, CLI and RPC server, Stellar and Soroban SDK developers, Soroban contract and application developers, and Stellar network validator operators.

Motivation

The Stellar Network currently supports a rich but fixed repertoire of transactions. Developers have indicated this repertoire is insufficiently flexible in adapting to new application needs, and wish to be able to submit custom turing-complete code to run in the transaction-execution phase of the network.

The Soroban project provides such an ability, through mechanisms specified in the various sub-CAPs linked from this CAP. Each sub-CAP specifies its relationship to the whole Soroban project and, where necessary, links to other sub-CAPs that it depends on or interacts with.

Goals Alignment

This CAP is aligned with the following Stellar Network Goals:

  • The Stellar Network should make it easy for developers of Stellar projects to create highly usable products

Abstract

Soroban adds a platform for executing smart contracts to the Stellar network.

It is small, simple, efficient, and based on standardized technology, leveraging standard tools and techniques whenever possible, and focusing on providing a high-quality and low-effort developer experience for writing smart contracts.

Specification

All specifications besides the cumulative XDR diffs below are provided in the following sub-CAPs:

XDR changes

There are four entirely new XDR files:

As well as updates to several of the other XDR files, which are maintained and modified on an ongoing basis during the development of Soroban in a separate, parallel src/protocol-next directory within the [stellar-core repository].

The diff showing the updates is therefore not generated by git diff, but by running the following command:

diff -ru --exclude='*.h' --exclude='.git*' --exclude='*.md' src/protocol-{curr,next}/xdr

That calculates the following difference between the src/protocol-curr and src/protocol-next directories:

diff -ru '--exclude=*.h' '--exclude=.git*' '--exclude=*.md' src/protocol-curr/xdr/Stellar-ledger-entries.x src/protocol-next/xdr/Stellar-ledger-entries.x
--- src/protocol-curr/xdr/Stellar-ledger-entries.x	2023-06-27 12:08:33.568636804 -0700
+++ src/protocol-next/xdr/Stellar-ledger-entries.x	2023-07-14 14:50:55.534242191 -0700
@@ -3,17 +3,16 @@
 // of this distribution or at http://www.apache.org/licenses/LICENSE-2.0
 
 %#include "xdr/Stellar-types.h"
+%#include "xdr/Stellar-contract.h"
+%#include "xdr/Stellar-contract-config-setting.h"
 
 namespace stellar
 {
 
-typedef PublicKey AccountID;
 typedef opaque Thresholds[4];
 typedef string string32<32>;
 typedef string string64<64>;
 typedef int64 SequenceNumber;
-typedef uint64 TimePoint;
-typedef uint64 Duration;
 typedef opaque DataValue<64>;
 typedef Hash PoolID; // SHA256(LiquidityPoolParameters)
 
@@ -98,7 +97,10 @@
     OFFER = 2,
     DATA = 3,
     CLAIMABLE_BALANCE = 4,
-    LIQUIDITY_POOL = 5
+    LIQUIDITY_POOL = 5,
+    CONTRACT_DATA = 6,
+    CONTRACT_CODE = 7,
+    CONFIG_SETTING = 8
 };
 
 struct Signer
@@ -491,6 +493,60 @@
     body;
 };
 
+enum ContractEntryBodyType {
+    DATA_ENTRY = 0,
+    EXPIRATION_EXTENSION = 1
+};
+
+const MASK_CONTRACT_DATA_FLAGS_V20 = 0x1;
+
+enum ContractDataFlags {
+    // When set, the given entry does not recieve automatic expiration bumps
+    // on access. Note that entries can still be bumped manually via the footprint.
+    NO_AUTOBUMP = 0x1
+};
+
+enum ContractDataDurability {
+    TEMPORARY = 0,
+    PERSISTENT = 1
+};
+
+struct ContractDataEntry {
+    SCAddress contract;
+    SCVal key;
+    ContractDataDurability durability;
+
+    union switch (ContractEntryBodyType bodyType)
+    {
+    case DATA_ENTRY:
+    struct
+    {
+        uint32 flags;
+        SCVal val;
+    } data;
+    case EXPIRATION_EXTENSION:
+        void;
+    } body;
+
+    uint32 expirationLedgerSeq;
+};
+
+struct ContractCodeEntry {
+    ExtensionPoint ext;
+
+    Hash hash;
+    union switch (ContractEntryBodyType bodyType)
+    {
+    case DATA_ENTRY:
+        opaque code<>;
+    case EXPIRATION_EXTENSION:
+        void;
+    } body;
+
+    uint32 expirationLedgerSeq;
+};
+
+
 struct LedgerEntryExtensionV1
 {
     SponsorshipDescriptor sponsoringID;
@@ -521,6 +577,12 @@
         ClaimableBalanceEntry claimableBalance;
     case LIQUIDITY_POOL:
         LiquidityPoolEntry liquidityPool;
+    case CONTRACT_DATA:
+        ContractDataEntry contractData;
+    case CONTRACT_CODE:
+        ContractCodeEntry contractCode;
+    case CONFIG_SETTING:
+        ConfigSettingEntry configSetting;
     }
     data;
 
@@ -575,6 +637,25 @@
     {
         PoolID liquidityPoolID;
     } liquidityPool;
+case CONTRACT_DATA:
+    struct
+    {
+        SCAddress contract;
+        SCVal key;
+        ContractDataDurability durability;
+        ContractEntryBodyType bodyType;
+    } contractData;
+case CONTRACT_CODE:
+    struct
+    {
+        Hash hash;
+        ContractEntryBodyType bodyType;
+    } contractCode;
+case CONFIG_SETTING:
+    struct
+    {
+        ConfigSettingID configSettingID;
+    } configSetting;
 };
 
 // list of all envelope types used in the application
@@ -589,6 +670,8 @@
     ENVELOPE_TYPE_SCPVALUE = 4,
     ENVELOPE_TYPE_TX_FEE_BUMP = 5,
     ENVELOPE_TYPE_OP_ID = 6,
-    ENVELOPE_TYPE_POOL_REVOKE_OP_ID = 7
+    ENVELOPE_TYPE_POOL_REVOKE_OP_ID = 7,
+    ENVELOPE_TYPE_CONTRACT_ID = 8,
+    ENVELOPE_TYPE_SOROBAN_AUTHORIZATION = 9
 };
 }
diff -ru '--exclude=*.h' '--exclude=.git*' '--exclude=*.md' src/protocol-curr/xdr/Stellar-ledger.x src/protocol-next/xdr/Stellar-ledger.x
--- src/protocol-curr/xdr/Stellar-ledger.x	2023-06-27 12:08:33.572636794 -0700
+++ src/protocol-next/xdr/Stellar-ledger.x	2023-08-03 13:12:14.983930940 -0700
@@ -47,13 +47,17 @@
     ext;
 };
 
-const MASK_LEDGER_HEADER_FLAGS = 0x7;
+const MASK_LEDGER_HEADER_FLAGS = 0x7F;
 
 enum LedgerHeaderFlags
 {
     DISABLE_LIQUIDITY_POOL_TRADING_FLAG = 0x1,
     DISABLE_LIQUIDITY_POOL_DEPOSIT_FLAG = 0x2,
-    DISABLE_LIQUIDITY_POOL_WITHDRAWAL_FLAG = 0x4
+    DISABLE_LIQUIDITY_POOL_WITHDRAWAL_FLAG = 0x4,
+    DISABLE_CONTRACT_CREATE = 0x8,
+    DISABLE_CONTRACT_UPDATE = 0x10,
+    DISABLE_CONTRACT_REMOVE = 0x20,
+    DISABLE_CONTRACT_INVOKE = 0x40
 };
 
 struct LedgerHeaderExtensionV1
@@ -122,7 +126,14 @@
     LEDGER_UPGRADE_BASE_FEE = 2,
     LEDGER_UPGRADE_MAX_TX_SET_SIZE = 3,
     LEDGER_UPGRADE_BASE_RESERVE = 4,
-    LEDGER_UPGRADE_FLAGS = 5
+    LEDGER_UPGRADE_FLAGS = 5,
+    LEDGER_UPGRADE_CONFIG = 6,
+    LEDGER_UPGRADE_MAX_SOROBAN_TX_SET_SIZE = 7
+};
+
+struct ConfigUpgradeSetKey {
+    Hash contractID;
+    Hash contentHash;
 };
 
 union LedgerUpgrade switch (LedgerUpgradeType type)
@@ -137,6 +148,17 @@
     uint32 newBaseReserve; // update baseReserve
 case LEDGER_UPGRADE_FLAGS:
     uint32 newFlags; // update flags
+case LEDGER_UPGRADE_CONFIG:
+    // Update arbitray `ConfigSetting` entries identified by the key.
+    ConfigUpgradeSetKey newConfig;
+case LEDGER_UPGRADE_MAX_SOROBAN_TX_SET_SIZE:
+    // Update ConfigSettingContractExecutionLanesV0.ledgerMaxTxCount without
+    // using `LEDGER_UPGRADE_CONFIG`.
+    uint32 newMaxSorobanTxSetSize;
+};
+
+struct ConfigUpgradeSet {
+    ConfigSettingEntry updatedEntry<>;
 };
 
 /* Entries used to define the bucket list */
@@ -348,6 +370,74 @@
                                         // applied if any
 };
 
+enum ContractEventType
+{
+    SYSTEM = 0,
+    CONTRACT = 1,
+    DIAGNOSTIC = 2
+};
+
+struct ContractEvent
+{
+    // We can use this to add more fields, or because it
+    // is first, to change ContractEvent into a union.
+    ExtensionPoint ext;
+
+    Hash* contractID;
+    ContractEventType type;
+
+    union switch (int v)
+    {
+    case 0:
+        struct
+        {
+            SCVal topics<>;
+            SCVal data;
+        } v0;
+    }
+    body;
+};
+
+struct DiagnosticEvent
+{
+    bool inSuccessfulContractCall;
+    ContractEvent event;
+};
+
+struct SorobanTransactionMeta 
+{
+    ExtensionPoint ext;
+
+    ContractEvent events<>;             // custom events populated by the
+                                        // contracts themselves.
+    SCVal returnValue;                  // return value of the host fn invocation
+
+    // Diagnostics events that are not hashed.
+    // This will contain all contract and diagnostic events. Even ones
+    // that were emitted in a failed contract call.
+    DiagnosticEvent diagnosticEvents<>;
+};
+
+struct TransactionMetaV3
+{
+    ExtensionPoint ext;
+
+    LedgerEntryChanges txChangesBefore;  // tx level changes before operations
+                                         // are applied if any
+    OperationMeta operations<>;          // meta for each operation
+    LedgerEntryChanges txChangesAfter;   // tx level changes after operations are
+                                         // applied if any
+    SorobanTransactionMeta* sorobanMeta; // Soroban-specific meta (only for 
+                                         // Soroban transactions).
+};
+
+// This is in Stellar-ledger.x to due to a circular dependency 
+struct InvokeHostFunctionSuccessPreImage
+{
+    SCVal returnValue;
+    ContractEvent events<>;
+};
+
 // this is the meta produced when applying transactions
 // it does not include pre-apply updates such as fees
 union TransactionMeta switch (int v)
@@ -358,6 +448,8 @@
     TransactionMetaV1 v1;
 case 2:
     TransactionMetaV2 v2;
+case 3:
+    TransactionMetaV3 v3;
 };
 
 // This struct groups together changes on a per transaction basis
@@ -414,11 +506,46 @@
     SCPHistoryEntry scpInfo<>;
 };
 
+struct LedgerCloseMetaV2
+{
+    // We forgot to add an ExtensionPoint in v1 but at least
+    // we can add one now in v2.
+    ExtensionPoint ext;
+
+    LedgerHeaderHistoryEntry ledgerHeader;
+
+    GeneralizedTransactionSet txSet;
+
+    // NB: transactions are sorted in apply order here
+    // fees for all transactions are processed first
+    // followed by applying transactions
+    TransactionResultMeta txProcessing<>;
+
+    // upgrades are applied last
+    UpgradeEntryMeta upgradesProcessing<>;
+
+    // other misc information attached to the ledger close
+    SCPHistoryEntry scpInfo<>;
+
+    // Size in bytes of BucketList, to support downstream
+    // systems calculating storage fees correctly.
+    uint64 totalByteSizeOfBucketList;
+
+    // Expired temp keys that are being evicted at this ledger.
+    LedgerKey evictedTemporaryLedgerKeys<>;
+
+    // Expired restorable ledger entries that are being
+    // evicted at this ledger.
+    LedgerEntry evictedPersistentLedgerEntries<>;
+};
+
 union LedgerCloseMeta switch (int v)
 {
 case 0:
     LedgerCloseMetaV0 v0;
 case 1:
     LedgerCloseMetaV1 v1;
+case 2:
+    LedgerCloseMetaV2 v2;
 };
 }
diff -ru '--exclude=*.h' '--exclude=.git*' '--exclude=*.md' src/protocol-curr/xdr/Stellar-transaction.x src/protocol-next/xdr/Stellar-transaction.x
--- src/protocol-curr/xdr/Stellar-transaction.x	2023-06-27 12:08:33.572636794 -0700
+++ src/protocol-next/xdr/Stellar-transaction.x	2023-08-03 13:12:14.983930940 -0700
@@ -2,11 +2,15 @@
 // under the Apache License, Version 2.0. See the COPYING file at the root
 // of this distribution or at http://www.apache.org/licenses/LICENSE-2.0
 
+%#include "xdr/Stellar-contract.h"
 %#include "xdr/Stellar-ledger-entries.h"
 
 namespace stellar
 {
 
+// maximum number of operations per transaction
+const MAX_OPS_PER_TX = 100;
+
 union LiquidityPoolParameters switch (LiquidityPoolType type)
 {
 case LIQUIDITY_POOL_CONSTANT_PRODUCT:
@@ -57,7 +61,10 @@
     CLAWBACK_CLAIMABLE_BALANCE = 20,
     SET_TRUST_LINE_FLAGS = 21,
     LIQUIDITY_POOL_DEPOSIT = 22,
-    LIQUIDITY_POOL_WITHDRAW = 23
+    LIQUIDITY_POOL_WITHDRAW = 23,
+    INVOKE_HOST_FUNCTION = 24,
+    BUMP_FOOTPRINT_EXPIRATION = 25,
+    RESTORE_FOOTPRINT = 26
 };
 
 /* CreateAccount
@@ -465,6 +472,141 @@
     int64 minAmountB; // minimum amount of second asset to withdraw
 };
 
+enum HostFunctionType
+{
+    HOST_FUNCTION_TYPE_INVOKE_CONTRACT = 0,
+    HOST_FUNCTION_TYPE_CREATE_CONTRACT = 1,
+    HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM = 2
+};
+
+enum ContractIDPreimageType
+{
+    CONTRACT_ID_PREIMAGE_FROM_ADDRESS = 0,
+    CONTRACT_ID_PREIMAGE_FROM_ASSET = 1
+};
+ 
+union ContractIDPreimage switch (ContractIDPreimageType type)
+{
+case CONTRACT_ID_PREIMAGE_FROM_ADDRESS:
+    struct
+    {
+        SCAddress address;
+        uint256 salt;
+    } fromAddress;
+case CONTRACT_ID_PREIMAGE_FROM_ASSET:
+    Asset fromAsset;
+};
+
+struct CreateContractArgs
+{
+    ContractIDPreimage contractIDPreimage;
+    ContractExecutable executable;
+};
+
+struct InvokeContractArgs {
+    SCAddress contractAddress;
+    SCSymbol functionName;
+    SCVal args<>;
+};
+
+union HostFunction switch (HostFunctionType type)
+{
+case HOST_FUNCTION_TYPE_INVOKE_CONTRACT:
+    InvokeContractArgs invokeContract;
+case HOST_FUNCTION_TYPE_CREATE_CONTRACT:
+    CreateContractArgs createContract;
+case HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM:
+    opaque wasm<>;
+};
+
+enum SorobanAuthorizedFunctionType
+{
+    SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN = 0,
+    SOROBAN_AUTHORIZED_FUNCTION_TYPE_CREATE_CONTRACT_HOST_FN = 1
+};
+
+union SorobanAuthorizedFunction switch (SorobanAuthorizedFunctionType type)
+{
+case SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN:
+    InvokeContractArgs contractFn;
+case SOROBAN_AUTHORIZED_FUNCTION_TYPE_CREATE_CONTRACT_HOST_FN:
+    CreateContractArgs createContractHostFn;
+};
+
+struct SorobanAuthorizedInvocation
+{
+    SorobanAuthorizedFunction function;
+    SorobanAuthorizedInvocation subInvocations<>;
+};
+
+struct SorobanAddressCredentials
+{
+    SCAddress address;
+    int64 nonce;
+    uint32 signatureExpirationLedger;    
+    SCVal signature;
+};
+
+enum SorobanCredentialsType
+{
+    SOROBAN_CREDENTIALS_SOURCE_ACCOUNT = 0,
+    SOROBAN_CREDENTIALS_ADDRESS = 1
+};
+
+union SorobanCredentials switch (SorobanCredentialsType type)
+{
+case SOROBAN_CREDENTIALS_SOURCE_ACCOUNT:
+    void;
+case SOROBAN_CREDENTIALS_ADDRESS:
+    SorobanAddressCredentials address;
+};
+
+/* Unit of authorization data for Soroban.
+
+   Represents an authorization for executing the tree of authorized contract 
+   and/or host function calls by the user defined by `credentials`.
+*/
+struct SorobanAuthorizationEntry
+{
+    SorobanCredentials credentials;
+    SorobanAuthorizedInvocation rootInvocation;
+};
+
+/* Upload Wasm, create, and invoke contracts in Soroban.
+
+    Threshold: med
+    Result: InvokeHostFunctionResult
+*/
+struct InvokeHostFunctionOp
+{
+    // Host function to invoke.
+    HostFunction hostFunction;
+    // Per-address authorizations for this host function.
+    SorobanAuthorizationEntry auth<>;
+};
+
+/* Bump the expiration ledger of the entries specified in the readOnly footprint
+   so they'll expire at least ledgersToExpire ledgers from lcl.
+
+    Threshold: med
+    Result: BumpFootprintExpirationResult
+*/
+struct BumpFootprintExpirationOp
+{
+    ExtensionPoint ext;
+    uint32 ledgersToExpire;
+};
+
+/* Restore the expired or evicted entries specified in the readWrite footprint.
+
+    Threshold: med
+    Result: RestoreFootprintOp
+*/
+struct RestoreFootprintOp
+{
+    ExtensionPoint ext;
+};
+
 /* An operation is the lowest unit of work that a transaction does */
 struct Operation
 {
@@ -523,6 +665,12 @@
         LiquidityPoolDepositOp liquidityPoolDepositOp;
     case LIQUIDITY_POOL_WITHDRAW:
         LiquidityPoolWithdrawOp liquidityPoolWithdrawOp;
+    case INVOKE_HOST_FUNCTION:
+        InvokeHostFunctionOp invokeHostFunctionOp;
+    case BUMP_FOOTPRINT_EXPIRATION:
+        BumpFootprintExpirationOp bumpFootprintExpirationOp;
+    case RESTORE_FOOTPRINT:
+        RestoreFootprintOp restoreFootprintOp;
     }
     body;
 };
@@ -540,11 +688,25 @@
     struct
     {
         AccountID sourceAccount;
-        SequenceNumber seqNum;
+        SequenceNumber seqNum; 
         uint32 opNum;
         PoolID liquidityPoolID;
         Asset asset;
     } revokeID;
+case ENVELOPE_TYPE_CONTRACT_ID:
+    struct
+    {
+        Hash networkID;
+        ContractIDPreimage contractIDPreimage;
+    } contractID;
+case ENVELOPE_TYPE_SOROBAN_AUTHORIZATION:
+    struct
+    {
+        Hash networkID;
+        int64 nonce;
+        uint32 signatureExpirationLedger;
+        SorobanAuthorizedInvocation invocation;
+    } sorobanAuthorization;
 };
 
 enum MemoType
@@ -632,8 +794,40 @@
     PreconditionsV2 v2;
 };
 
-// maximum number of operations per transaction
-const MAX_OPS_PER_TX = 100;
+// Ledger key sets touched by a smart contract transaction.
+struct LedgerFootprint
+{
+    LedgerKey readOnly<>;
+    LedgerKey readWrite<>;
+};
+
+// Resource limits for a Soroban transaction.
+// The transaction will fail if it exceeds any of these limits.
+struct SorobanResources
+{   
+    // The ledger footprint of the transaction.
+    LedgerFootprint footprint;
+    // The maximum number of instructions this transaction can use
+    uint32 instructions; 
+
+    // The maximum number of bytes this transaction can read from ledger
+    uint32 readBytes;
+    // The maximum number of bytes this transaction can write to ledger
+    uint32 writeBytes;
+
+    // Maximum size of the contract events (serialized to XDR) this transaction
+    // can emit.
+    uint32 contractEventsSizeBytes;
+};
+
+// The transaction extension for Soroban.
+struct SorobanTransactionData
+{
+    ExtensionPoint ext;
+    SorobanResources resources;
+    // Portion of transaction `fee` allocated to refundable fees.
+    int64 refundableFee;
+};
 
 // TransactionV0 is a transaction with the AccountID discriminant stripped off,
 // leaving a raw ed25519 public key to identify the source account. This is used
@@ -695,6 +889,8 @@
     {
     case 0:
         void;
+    case 1:
+        SorobanTransactionData sorobanData;
     }
     ext;
 };
@@ -1588,6 +1784,67 @@
     void;
 };
 
+enum InvokeHostFunctionResultCode
+{
+    // codes considered as "success" for the operation
+    INVOKE_HOST_FUNCTION_SUCCESS = 0,
+
+    // codes considered as "failure" for the operation
+    INVOKE_HOST_FUNCTION_MALFORMED = -1,
+    INVOKE_HOST_FUNCTION_TRAPPED = -2,
+    INVOKE_HOST_FUNCTION_RESOURCE_LIMIT_EXCEEDED = -3,
+    INVOKE_HOST_FUNCTION_ENTRY_EXPIRED = -4
+};
+
+union InvokeHostFunctionResult switch (InvokeHostFunctionResultCode code)
+{
+case INVOKE_HOST_FUNCTION_SUCCESS:
+    Hash success; // sha256(InvokeHostFunctionSuccessPreImage)
+case INVOKE_HOST_FUNCTION_MALFORMED:
+case INVOKE_HOST_FUNCTION_TRAPPED:
+case INVOKE_HOST_FUNCTION_RESOURCE_LIMIT_EXCEEDED:
+case INVOKE_HOST_FUNCTION_ENTRY_EXPIRED:
+    void;
+};
+
+enum BumpFootprintExpirationResultCode
+{
+    // codes considered as "success" for the operation
+    BUMP_FOOTPRINT_EXPIRATION_SUCCESS = 0,
+
+    // codes considered as "failure" for the operation
+    BUMP_FOOTPRINT_EXPIRATION_MALFORMED = -1,
+    BUMP_FOOTPRINT_EXPIRATION_RESOURCE_LIMIT_EXCEEDED = -2
+};
+
+union BumpFootprintExpirationResult switch (BumpFootprintExpirationResultCode code)
+{
+case BUMP_FOOTPRINT_EXPIRATION_SUCCESS:
+    void;
+case BUMP_FOOTPRINT_EXPIRATION_MALFORMED:
+case BUMP_FOOTPRINT_EXPIRATION_RESOURCE_LIMIT_EXCEEDED:
+    void;
+};
+
+enum RestoreFootprintResultCode
+{
+    // codes considered as "success" for the operation
+    RESTORE_FOOTPRINT_SUCCESS = 0,
+
+    // codes considered as "failure" for the operation
+    RESTORE_FOOTPRINT_MALFORMED = -1,
+    RESTORE_FOOTPRINT_RESOURCE_LIMIT_EXCEEDED = -2
+};
+
+union RestoreFootprintResult switch (RestoreFootprintResultCode code)
+{
+case RESTORE_FOOTPRINT_SUCCESS:
+    void;
+case RESTORE_FOOTPRINT_MALFORMED:
+case RESTORE_FOOTPRINT_RESOURCE_LIMIT_EXCEEDED:
+    void;
+};
+
 /* High level Operation Result */
 enum OperationResultCode
 {
@@ -1654,6 +1911,12 @@
         LiquidityPoolDepositResult liquidityPoolDepositResult;
     case LIQUIDITY_POOL_WITHDRAW:
         LiquidityPoolWithdrawResult liquidityPoolWithdrawResult;
+    case INVOKE_HOST_FUNCTION:
+        InvokeHostFunctionResult invokeHostFunctionResult;
+    case BUMP_FOOTPRINT_EXPIRATION:
+        BumpFootprintExpirationResult bumpFootprintExpirationResult;
+    case RESTORE_FOOTPRINT:
+        RestoreFootprintResult restoreFootprintResult;
     }
     tr;
 case opBAD_AUTH:
@@ -1689,7 +1952,9 @@
     txBAD_SPONSORSHIP = -14,       // sponsorship not confirmed
     txBAD_MIN_SEQ_AGE_OR_GAP =
         -15, // minSeqAge or minSeqLedgerGap conditions not met
-    txMALFORMED = -16 // precondition is invalid
+    txMALFORMED = -16, // precondition is invalid
+    // declared Soroban resource usage exceeds the network limit
+    txSOROBAN_RESOURCE_LIMIT_EXCEEDED = -17
 };
 
 // InnerTransactionResult must be binary compatible with TransactionResult
@@ -1720,6 +1985,7 @@
     case txBAD_SPONSORSHIP:
     case txBAD_MIN_SEQ_AGE_OR_GAP:
     case txMALFORMED:
+    case txSOROBAN_RESOURCE_LIMIT_EXCEEDED:
         void;
     }
     result;
@@ -1766,6 +2032,7 @@
     case txBAD_SPONSORSHIP:
     case txBAD_MIN_SEQ_AGE_OR_GAP:
     case txMALFORMED:
+    case txSOROBAN_RESOURCE_LIMIT_EXCEEDED:
         void;
     }
     result;
diff -ru '--exclude=*.h' '--exclude=.git*' '--exclude=*.md' src/protocol-curr/xdr/Stellar-types.x src/protocol-next/xdr/Stellar-types.x
--- src/protocol-curr/xdr/Stellar-types.x	2023-06-27 12:08:33.572636794 -0700
+++ src/protocol-next/xdr/Stellar-types.x	2023-07-14 14:50:55.538242159 -0700
@@ -14,6 +14,9 @@
 typedef unsigned hyper uint64;
 typedef hyper int64;
 
+typedef uint64 TimePoint;
+typedef uint64 Duration;
+
 // An ExtensionPoint is always marshaled as a 32-bit 0 value.  At a
 // later point, it can be replaced by a different union so as to
 // extend a structure.
@@ -79,6 +82,7 @@
 typedef opaque SignatureHint[4];
 
 typedef PublicKey NodeID;
+typedef PublicKey AccountID;
 
 struct Curve25519Secret
 {