<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.39 (Ruby 3.4.9) -->
<?rfc rfcedstyle="yes"?>
<?rfc tocindent="yes"?>
<?rfc strict="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc text-list-symbols="o-*+"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-belchior-satp-gateway-recovery-05" category="info" consensus="true" submissionType="IETF" tocDepth="4" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.0 -->
  <front>
    <title abbrev="SATP Gateway Crash Recovery">Secure Asset Transfer Protocol (SATP) Gateway Crash Recovery Mechanism</title>
    <seriesInfo name="Internet-Draft" value="draft-belchior-satp-gateway-recovery-05"/>
    <author initials="R." surname="Belchior" fullname="Rafael Belchior">
      <organization>INESC-ID, Técnico Lisboa, Blockdaemon</organization>
      <address>
        <email>rafael.belchior@tecnico.ulisboa.pt</email>
      </address>
    </author>
    <author initials="M." surname="Correia" fullname="Miguel Correia">
      <organization>INESC-ID, Técnico Lisboa</organization>
      <address>
        <email>miguel.p.correia@tecnico.ulisboa.pt</email>
      </address>
    </author>
    <author initials="A." surname="Augusto" fullname="André Augusto">
      <organization>INESC-ID, Técnico Lisboa</organization>
      <address>
        <email>andre.augusto@tecnico.ulisboa.pt</email>
      </address>
    </author>
    <author initials="T." surname="Hardjono" fullname="Thomas Hardjono">
      <organization>MIT</organization>
      <address>
        <email>hardjono@mit.edu</email>
      </address>
    </author>
    <date year="2026" month="July" day="28"/>
    <area>Applications and Real-Time</area>
    <workgroup>Secure Asset Transfer Protocol</workgroup>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 90?>

<t>This memo describes the crash recovery mechanism for the Secure Asset Transfer Protocol (SATP). The goal of this draft is to specify the message flow that implements a crash recovery mechanism, composed of self-healing and rollback sub-protocols. The mechanism assures that gateways running SATP are able to recover faults, enforcing ACID properties for asset transfers across ledgers (i.e., double spend does not occur).</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://ietf-satp.github.io/draft-belchior-satp-gateway-recovery/draft-belchior-satp-gateway-recovery.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-belchior-satp-gateway-recovery/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Secure Asset Transfer Protocol Working Group mailing list (<eref target="mailto:sat@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/sat/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/sat/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/ietf-satp/draft-belchior-satp-gateway-recovery"/>.</t>
    </note>
  </front>
  <middle>
    <?line 95?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Gateway systems that perform digital asset transfers among networks must possess a degree of resiliency and fault tolerance in the face of possible crashes. Accounting for the possibility of crashes is
particularly important to guarantee asset consistency across networks.</t>
      <t>The crash recovering mechanism is applied to a version of SATP <xref target="I-D.draft-ietf-satp-core"/> using either 2PC or 3PC, which are atomic commitment protocol (ACP).
2PC and 3PC considers two roles: a coordinator who manages the protocol's execution and participants who manage the resources that must be kept consistent. The origin gateway plays the ACP role of Coordinator, and the destination Gateway plays the Participant role in relay mode. Gateways exchange messages corresponding to the protocol execution, generating log entries for each one.
The crash recovery draft does not depend on the specific SATP messages, but defines procedures to recover from crashes and for rollbacks, independently of the specific protocol phase being executed.</t>
      <t>Log entries are organized into logs. Logs enable either the same or other backup gateways to resume any phase of SATP. This log can also serve as an accountability tool in case of disputes. Log entries are then the basis satisfying one of the key deployment requirements of gateways for asset transfers: a high degree of availability. In this document, we consider two common strategies to increase availability: (1) to support the recovery of the gateways (self-healing model) and (2) to employ backup gateways with the ability to resume a stalled transfer (primary-backup model).</t>
      <t>This memo proposes:</t>
      <t>(i) the logging model of the crash recovery mechanism; (ii) the log storage types; (iii) the log storage API; (iv)  the log entry format; (v) the recovery and rollback procedures.</t>
    </section>
    <section anchor="terminology">
      <name>Terminology</name>
      <t>There following are some terminology used in the current document:</t>
      <ul spacing="normal">
        <li>
          <t>Gateway: The collection of services which connects to a minimum of one network or system, and which implements the secure asset transfer protocol.</t>
        </li>
        <li>
          <t>Primary Gateway: The node of a network that has been selected or elected to act as a gateway in an asset transfer.</t>
        </li>
        <li>
          <t>Backup Gateway: The node of a network that has been selected or elected to act as a backup gateway to a primary gateway.</t>
        </li>
        <li>
          <t>Message Flow Parameters: The parameters and payload employed in a message flow between a sending gateway and receiving gateway.</t>
        </li>
        <li>
          <t>Origin Gateway: The gateway that initiates the transfer protocol. Acts as a coordinator of the ACP and mediates the message flow.</t>
        </li>
        <li>
          <t>Destination Gateway: The gateway that is the target of an asset transfer. It follows instructions from the origin Gateway.</t>
        </li>
        <li>
          <t>Log: Set of log entries such that those are ordered by the time of its creation.</t>
        </li>
        <li>
          <t>Public (or Shared) Log: log where several gateways can read and write from it.</t>
        </li>
        <li>
          <t>Private Log: log where only one gateway can read and write from it.</t>
        </li>
        <li>
          <t>Log data: The log information is retained by a gateway connected to an exchanged message within an asset transfer protocol.</t>
        </li>
        <li>
          <t>Log entry: The log information generated and persisted by a gateway regarding one specific message flow step.</t>
        </li>
        <li>
          <t>Log format: The format of log data generated by a gateway.</t>
        </li>
        <li>
          <t>Atomic commit protocol (ACP): A protocol that guarantees that assets taken from a network are persisted into the other network. Examples are two and three-phase commit protocols (2PC, 3PC, respectively) and non-blocking atomic commit protocols.</t>
        </li>
        <li>
          <t>Fault: A fault is an event that alters the expected behavior of a system.</t>
        </li>
        <li>
          <t>Crash-fault tolerant models: the models allowing a system to keep operating correctly despite having a set of faulty components.</t>
        </li>
      </ul>
    </section>
    <section anchor="log-model">
      <name>Logging Model</name>
      <t>We consider the log file to be a stack of log entries. Each time a log entry is added, it goes to the top of the stack (the highest index).
For each protocol step a gateway performs, a log entry is created immediately before executing and immediately after executing a given operation.</t>
      <t>To manipulate the log, we define a set of log primitives that translate log entry requests from a process into log entries, realized by the log storage API (for the context of SATP, Section 3.5):</t>
      <ul spacing="normal">
        <li>
          <t>writeLogEntry(e,L) (WRITE) - appends a log entry e in the log L (held by the corresponding Log Storage Support).</t>
        </li>
        <li>
          <t>getLogEntry(i,L) (READ) - retrieves a log entry with index i from log L.</t>
        </li>
      </ul>
      <t>From these primitives, other functions can be built:</t>
      <ul spacing="normal">
        <li>
          <t>getLogLength (L) (READ) - obtains the number of log entries from log L.</t>
        </li>
        <li>
          <t>getLogDiff(l1,l2) (READ) - obtains the difference between two logs.</t>
        </li>
        <li>
          <t>getLastEntry(L): obtains the last log entry from log L.</t>
        </li>
        <li>
          <t>getLog(L): retrieves the whole log L.</t>
        </li>
        <li>
          <t>updateLog(l1,l2): updates l1 based on l2 (uses getLogDiff and writeLogEntry).</t>
        </li>
      </ul>
      <t>The following example shows a simplified version log referring to the transfer initiation flow SATP phase. Each log entry (simplified, see the definition in Section 3) is composed of metadata (phase, sequence number) and one attribute from the payload (operation). Operations map behavior to state (see Section 4).</t>
      <section anchor="example">
        <name>Example</name>
        <figure anchor="example-log-model">
          <artwork><![CDATA[
     ,--.                     ,--.                                 ,-------.
     |G1|                     |G2|                                 |Log API|
     `--'                     `--'                                 `-------'
      |             [1]: writeLogEntry <1,1,init-validate>             |
      | --------------------------------------------------------------->
      |                        |                                       |
      | initiate SATP's phase 1|                                       |
      | ----------------------->                                       |
      |                        |                                       |
      |                        | [2]: writeLogEntry <1,2,exec-validate>|
      |                        | -------------------------------------->
      |                        |                                       |
      |                        |----.                                  |
      |                        |    | execute validate from p1         |
      |                        |<---'                                  |
      |                        |                                       |
      |                        | [3]: writeLogEntry <1,3,done-validate>|
      |                        | -------------------------------------->
      |                        |                                       |
      |                        | [4]: writeLogEntry <1,4,ack-validate> |
      |                        | -------------------------------------->
      |                        |                                       |
      |   validation complete  |                                       |
      | <-----------------------                                       |
     ,--.                     ,--.                                 ,-------.
     |G1|                     |G2|                                 |Log API|
     `--'                     `--'                                 `-------'

]]></artwork>
        </figure>
        <t>This example shows the sequence of logging operations over part of the first phase of SATP (simplified):</t>
        <ol spacing="normal" type="1"><li>
            <t>At step 1, G1 writes an init-validate operation, meaning it will require G2 to initiate the validate function:
This step generates a log entry (p1, 1, init-validate).</t>
          </li>
          <li>
            <t>At step 2, G2 writes an exec-validate operation, meaning it will try to execute the validate function:
This step generates a log entry (p1, 2, exec-validate).</t>
          </li>
          <li>
            <t>At step 3, G2 writes a done-validate operation, meaning it successfully executed the validate function:
This step generates a log entry (p1, 3, done-validate).</t>
          </li>
          <li>
            <t>At step 4, G2 writes an ack-validate operation, meaning it will send an acknowledgment to G1 regarding the done-validate:
This step generates a log entry (p1, 4, ack-validate).</t>
          </li>
        </ol>
        <t>Without loss of generality, the above logging model applies to all phases of SATP.</t>
      </section>
      <section anchor="satp-example">
        <name>SATP Example</name>
        <t>This example showcases the logging procedure step 2.4 of SATP (lock-assertion) by both gateways.</t>
        <figure anchor="satp-example-lock-assertion">
          <artwork><![CDATA[
    ,----------.               ,----------.                                   ,-------.
     |Gateway G1|               |Gateway G2|                                   |Log API|
     `----------'               `----------'                                   `-------'
          |----.                     |                                             |
          |    | 1 using log api     |                                             |
          |<---'                     |                                             |
          |                          |                                             |
          |              2 writeLogEntry(2,2.2-1,init-lock-assertion)              |
          | ----------------------------------------------------------------------->
          |                          |                                             |
          |  3 Lock-Assertion (2.2)  |                                             |
          | ------------------------->                                             |
          |                          |                                             |
          |                          | 4 writeLogEntry(2,2.2-2,exec-lock-assertion)|
          |                          | -------------------------------------------->
          |                          |                                             |
          |                          |----.                                        |
          |                          |    | 5 execute lock assertion phase         |
          |                          |<---'                                        |
          |                          |                                             |
          |                          | 6 writeLogEntry(2,2.2-3,done-lock-assertion)|
          |                          | -------------------------------------------->
          |                          |                                             |
          |                          |----.                                        |
          |                          |    | 7 generate lock assertion receipt      |
          |                          |<---'                                        |
          |                          |                                             |
          |                          |  8 (optional) write lock assertion receipt  |
          |                          | -------------------------------------------->
          |                          |                                             |
          |                          | 9 writeLogEntry(2,2.2-4,ack-lock-assertion) |
          |                          | -------------------------------------------->
          |                          |                                             |
          | 10 lock assertion receipt|                                             |
          | <-------------------------                                             |
     ,----------.               ,----------.                                   ,-------.
     |Gateway G1|               |Gateway G2|                                   |Log API|
     `----------'               `----------'                                   `-------'

]]></artwork>
        </figure>
      </section>
      <section anchor="log-storage-modes">
        <name>Log Storage Modes</name>
        <t>Gateways store state that is captured by logs. Gateways have private logs recording enterprise-sensitive data that can be used, for instance, for analytics. Entries can include end-to-end cross-jurisdiction transaction latency and throughput.</t>
        <t>Apart from the enterprise log, a state log can be public or private, centralized or decentralized. This log is meant to be shared with everyone with an internet connection (public) or only within the gateway consortium (private). Logs can be stored locally or in a cloud service, per gateway (centralized), or in a decentralized infrastructure (i.e., decentralized ledger, decentralized database). We call the latter option decentralized log storage. The type of the state log depends on the trust assumptions among gateways and the log access mode.</t>
        <t>In greater detail:</t>
        <ol spacing="normal" type="1"><li>
            <t>Public decentralized log: log entries are stored on a decentralized public log (e.g., Ethereum blockchain, IPFS). Each gateway writes non-encrypted log entries to a decentralized log storage.
Although this is the best option for providing accountability of gateways, availability, and integrity of the logs, leading to shorter dispute resolution, this can lead to leak of information which can lead to privacy issues.
The integrity of the log can be asserted by hashing the entries and comparing it to each stored hash on the decentralized log storage.
A solution to the privacy problems could be given by gateways publishing a hash of the log entry plus metadata to the decentralized log storage instead of the log entries. Although this is a first step towards resolving privacy issues, a tradeoff with data availability exists.
In particular, this choice leads to lower availability guarantees since a gateway needs to wait for the counterparty gateway to deliver the logs in case logs need to be shared. In this case, the decentralized log storage acts as a notarizing service.
This mode is recommended when gateways operate in the  Relay Mode: Client-initiated Gateway to Gateway. This mode can also be used by the Direct Mode: Client to Multiple Gateway access mode because gateways may need to share state between themselves.
Note: the difference between the mentioned modes is that in Direct Mode: Client to Multiple Gateway, a single client/organization controls all the gateways, whereas, in the Relay Mode, gateways are controlled by different organizations.</t>
          </li>
          <li>
            <t>Public centralized log: log entries are published in a bulletin that more organizations control. That bulletin can be updated or removed at any time. Accountability is only guaranteed provided that there are multiple copies of such bulletin by conflicting parties.
Availability and integrity can be obtained via redundancy.</t>
          </li>
          <li>
            <t>Private centralized log. Each gateway stores logs locally or in a cloud in the private log storage mode but does not share them by default with other gateways. If needed, logs are requested from the counterparty gateway.
Saving logs locally is faster than saving them on the respective ledger since issuing a transaction is several orders of magnitude slower than writing on a disk or accessing a cloud service.
Nonetheless, this model delivers weaker integrity and availability guarantees.</t>
          </li>
          <li>
            <t>Private decentralized log. Each gateway stores logs in a private blockchain, and are shared with other gateways by default.</t>
          </li>
        </ol>
        <t>Each log storage mode provides a different process to recover the state from crashes. In the private log, a gateway requires the most recent log from the counterparty gateway. This mode is the one where the most trust is needed.
The gateway publishes hashes of log entries and metadata on a decentralized log storage in the centralized public log. Gateways who need the logs request them from other gateways and perform integrity checks of the received logs.
In the public decentralized mode, the gateways publish the plain log entries on decentralized log storage. This is the most trustless and decentralized mode of operation.</t>
        <t>By default, if there are gateways from different institutions involved in an asset transfer, the storage mode should be a decentralized log storage. The decentralized log storage can provide a common source of truth to solve disputes and maintain a shared state, alleviating trust assumptions between gateways.</t>
      </section>
      <section anchor="log-storage-api">
        <name>Log Storage API</name>
        <t>The log storage API allows developers to be abstracted from the log storage support, providing a standardized way
to interact with logs (e.g., relational vs. non-relational, local vs. on-chain). It also handles access control if needed.</t>
        <figure anchor="api-table">
          <artwork><![CDATA[
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Function                              | Parameters                       | Endpoint                                                               |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Append log entry                      | logId - log entry to be appended | POST / writeLogEntry/:logId Host: example.org Accept: application/json |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Obtains a log entry                   | id - log entry id                | GET getLogEntry/:id Host: example.org                                  |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Obtains the length of the log         | None                             | GET getLogLength Host: example.org                                     |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Obtains the difference                | log - log to be compared         |  POST /getLogDiff/:log Host: example.org                                     |
| between a given log and a current log |                                  |                                                                        |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Obtains the last log entry            | None                             | GET getLastEntry Host: example.org                                     |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+
| Obtains the whole log                 | None                             | GET getLog Host: example.org                                           |
+---------------------------------------+----------------------------------+------------------------------------------------------------------------+

]]></artwork>
        </figure>
        <t>The following table maps the respective return values and response examples:</t>
        <figure anchor="return-values-api-table">
          <artwork><![CDATA[
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| Returns                         | Response Example                                                                                                                                      |
+=================================+=======================================================================================================================================================+
| The entry index of the last log | HTTP/1.1 200 OK Cache-Control: private Date: Mon, 02 Mar 2020 05:07:35 GMT Content-Type: application/json { "success": true, "response_data":"2" }    |
| (string)                        |                                                                                                                                                       |
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| A log entry                     | HTTP/1.1 200 OK Cache-Control: private Date: Mon, 02 Mar 2020 05:07:35 GMT Content-Type: application/json { "success": true, "response_data": {...} } |
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| The length of the log           | HTTP/1.1 200 OK Cache-Control: private Date: Mon, 02 Mar 2020 05:07:35 GMT Content-Type: application/json { "success": true, "response_data":"2" }    |
| (string)                        |                                                                                                                                                       |
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| The difference between two logs | HTTP/1.1 200 OK Cache-Control: private Date: Mon, 02 Mar 2020 05:07:35 GMT Content-Type: application/json { "success": true, "response_data": {...} } |
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| A log entry                     | HTTP/1.1 200 OK Cache-Control: private Date: Mon, 02 Mar 2020 05:07:35 GMT Content-Type: application/json { "success": true, "response_data": {...} } |
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| The log                         | HTTP/1.1 200 OK Cache-Control: private Date: Mon, 02 Mar 2020 05:07:35 GMT Content-Type: application/json { "success": true, "response_data": {...} } |
+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------+

]]></artwork>
        </figure>
        <section anchor="response-codes">
          <name>Response Codes</name>
          <t>The log storage API  MUST respond with return codes indicating the failure (error 5XX) or success of the operation (200). The application may carry out a further operation in the future to determine the ultimate status of the operation.</t>
          <t>The log storage API response is in JSON format and contains two fields: 1) success: true if the operation was successful, and 2) response_data: contains the payload of the response generated by the log storage API.</t>
        </section>
      </section>
    </section>
    <section anchor="format">
      <name>Format of Log Entries</name>
      <t>A gateway stores the log entries in its log, and they capture gateways operations. Entries account for the current status of one of the three SATP flows: Transfer Initiation flow, Lock-Evidence flow, and Commitment Establishment flow.</t>
      <t>The recommended format for log entries is JSON, with protocol-specific mandatory fields supporting a free format field for plaintext or encrypted payloads directed at the SATP gateway or an underlying network. Although the recommended format is JSON, other formats can be used (e.g., XML).</t>
      <t>The mandatory fields of a log entry, that SATP generates, are:</t>
      <ul spacing="normal">
        <li>
          <t>Version: SATP protocol Version (major, minor).</t>
        </li>
        <li>
          <t>Session ID: a unique identifier (UUIDv2) representing a session.</t>
        </li>
        <li>
          <t>Context ID: a unique identifier (UUIDv2) representing a session context <xref target="I-D.draft-avrilionis-satp-setup-stage-01"/>.</t>
        </li>
        <li>
          <t>Sequence Number: monotonically increasing counter that uniquely represents a message from a session.</t>
        </li>
        <li>
          <t>SATP Phase: current SATP phase.</t>
        </li>
        <li>
          <t>Resource URL: Location of Resource to be accessed.</t>
        </li>
        <li>
          <t>Developer URN: Assertion of developer/application identity.</t>
        </li>
        <li>
          <t>Action/Response: GET/POST and arguments (or Response Code).</t>
        </li>
        <li>
          <t>Credential Profile: Specify the type of auth (e.g., SAML, OAuth, X.509)</t>
        </li>
        <li>
          <t>Credential Block: Credential token, certificate, string.</t>
        </li>
        <li>
          <t>Payload Profile: Asset Profile provenance and capabilities.</t>
        </li>
        <li>
          <t>Application Profile: Vendor or Application-specific profile.</t>
        </li>
        <li>
          <t>Payload: Payload for POST, responses, and native network transactions. The payload is specific to the current SATP phase.</t>
        </li>
        <li>
          <t>Payload Hash: hash of the current message payload.</t>
        </li>
      </ul>
      <t>In addition to the attributes that belong to SATP s schema, each log entry REQUIRES the following attributes:</t>
      <ul spacing="normal">
        <li>
          <t>timestamp REQUIRED: timestamp referring to when the log entry was generated (UNIX format).</t>
        </li>
        <li>
          <t>origin_gateway_pubkey REQUIRED: the public key of the gateway initiating a transfer.</t>
        </li>
        <li>
          <t>origin_gateway_system REQUIRED: the ID  of the source network.</t>
        </li>
        <li>
          <t>destination_gateway_pubkey REQUIRED: the public key of the gateway involved in a transfer.</t>
        </li>
        <li>
          <t>destination_gateway_system REQUIRED: the ID of the destination Gateway involved in a transfer.</t>
        </li>
        <li>
          <t>logging_profile REQUIRED: contains the profile regarding the logging procedure. Default is a local store.</t>
        </li>
        <li>
          <t>Message_signature REQUIRED: Gateway ECDSA signature over the log entry.</t>
        </li>
        <li>
          <t>Last_entry_hash REQUIRED: Hash of previous log entry.</t>
        </li>
        <li>
          <t>Access_control_profile REQUIRED: the profile regarding the confidentiality of the log entries being stored. Default is only the gateway that created the logs that can access them.</t>
        </li>
        <li>
          <t>Operation: the high-level operation being executed by the gateway on that step.
There are five types of operations: Operation init- states the intention of a node to execute a particular operation; Operation exec- expresses that the node is executing the operation; Operation done- states when a node successfully executes a step of the protocol;
Operation ack- refers to when a node acknowledges a message received from another (e.g., the command executed); Operation fail- occurs when an agent fails to execute a specific step.</t>
        </li>
      </ul>
      <t>Optional field entries are:</t>
      <ul spacing="normal">
        <li>
          <t>recovery message: the type of recovery message, if the gateway is involved in a recovery procedure.</t>
        </li>
        <li>
          <t>recovery payload: the payload associated with the recovery message.</t>
        </li>
      </ul>
      <t>Example of a log entry created by G1, corresponding to locking an asset (phase 2.3 of the SATP protocol):</t>
      <figure anchor="example-log-entry">
        <artwork><![CDATA[
{
  "Version": "1.0",
  "Session ID": "123e4567-e89b-12d3-a456-426655440000",
  "Sequence Number": 1,
  "SATP Phase": "Initialization",
  "Resource URL": "http://myresource.com",
  "Developer URN": "urn:myapp:developerid",
  "Action/Response": "POST /myresource",
  "Credential Profile": "OAuth",
  "Credential Block": "ABC123TOKEN",
  "Payload Profile": "ProvenanceProfile1",
  "Application Profile": "AppProfile1",
  "Payload": "{ 'key1': 'value1', 'key2': 'value2' }",
  "Payload Hash": "abc123def456",
  "timestamp": 1646176142,
  "origin_gateway_pubkey": "abc123",
  "origin_gateway_system": "system1",
  "destination_gateway_pubkey": "def456",
  "destination_gateway_system": "system2",
  "logging_profile": "Local Store",
  "Message_signature": "ecdsa_signature_here",
  "Last_entry_hash": "hash_of_last_entry",
  "Access_control_profile": "GatewayOnly",
  "Operation": "init",
  "recovery message": "recovery_message_here",
  "recovery payload": "recovery_payload_here"
}
]]></artwork>
      </figure>
      <t>Example of a log entry created by G2, acknowledging G1 locking an asset (phase 2.4 of the SATP protocol) :</t>
      <figure anchor="example-log-entry-two">
        <artwork><![CDATA[
{
    "sessionId": "4eb424c8-aead-4e9e-a321-a160ac3909ac",
    "contextId": "5eb424c8-aead-4e9e-a321-a160ac3909ac",
    "seqNumber": 7,
    "phaseId": "lock",
    "originGatewayId": "5.47.165.186",
    "originNetworkId": "Hyperledger-Fabric-JusticeChain",
    "destinationGatewayId": "192.47.113.116",
    "destinationNetworkId": "Ethereum",
    "timestamp": "1606157333",
    "payload": {
    "messageType": "2pc-log",
    "message": "LOCK_ASSET_ACK",
    "votes": "none"
}
]]></artwork>
      </figure>
    </section>
    <section anchor="procedure">
      <name>Crash Recovery Procedure</name>
      <t>This section defines general considerations about crash recovery for the self-healing mode. Note that the procedure for the primary-backup mode is the same, but first has a session resumption process.</t>
      <section anchor="crm">
        <name>Crash Recovery Model</name>
        <t>Gateways can fail by crashing (i.e., becoming silent). In order to be able to recover from these crashes, gateways store log entries in a persistent data storage. Thus, gateways can recover by obtaining the latest successful operation and continuing from there. We consider two recovery models:</t>
        <ol spacing="normal" type="1"><li>
            <t>Self-healing mode: assumes that after a crash, a gateway eventually recovers. The gateway does not lose its long-term keys (public-private key pair) and can reestablish all TLS connections.</t>
          </li>
          <li>
            <t>Primary-backup mode assumes that a gateway may never recover after a crash but that this failure can be detected by timeout <xref target="AD76"/>. If the timeout is exceeded, a backup gateway detects that failure unequivocally and takes the role of the primary gateway. The failure is detected using heartbeat messages and a conservative period.</t>
          </li>
        </ol>
        <t>In both modes, after a gateway recovers, the gateways follow a general recovery procedure (in Section 6.2 explained in detail for each phase):</t>
        <ol spacing="normal" type="1"><li>
            <t>Crash communication: using the self-healing or primary-backup modes, a node recovers. After that, it sends a message RECOVER to the counterparty gateways.</t>
          </li>
          <li>
            <t>State update: The gateway syncs its state with the latest state, either by requesting it from the decentralized log storage or other gateways (depending on the log storage mode).
If a decentralized log storage is available, the crashed gateway attempts to update its local log, using getLogDiff from the shared log.
If there is no shared log, the crashed gateway needs to synchronize itself with the counterparty gateway by querying the counterparty gateway with a recovery message RECOVER containing the latest log before the crash.
The counterparty gateway sends back a RECOVER-UPDATE message with its log. The recovered gateway can now reconstruct the updated log via getLogDiff, and derive the current state of the asset transfer.
The gateways now share the same state and can proceed with its operation.</t>
          </li>
          <li>
            <t>Recovery communication: The gateway and informs other gateways of the recovery with a recovery confirmation message is sent (RECOVERY-UPDATE-ACK), and the respective acknowledgment is sent by the counterparty gateway (RECOVERY-SUCCESS).</t>
          </li>
        </ol>
        <t>Finally, the gateway resumes the normal execution of SATP (session resumption).</t>
      </section>
      <section anchor="rp">
        <name>Recovery Procedure</name>
        <t>The previous section explained the general procedure that gateways follow upon crashing. In more detail, for each SATP phase, we define the recovery procedure:</t>
        <section anchor="transfer-initiation-flow">
          <name>Transfer Initiation Flow</name>
          <t>This phase of SATP follows the Crash Recovery Model from Section 6.1.</t>
        </section>
        <section anchor="lock-evidence-flow">
          <name>Lock-Evidence Flow</name>
          <t>This phase of SATP follows the Crash Recovery Model from Section 6.1.
Note that, in this phase, distributed ledgers were changed by gateways. The crash gateways' recovery should take place in less than the timeout specified for the asset transfer. Otherwise, the rollback protocol present in the next section is applied.</t>
        </section>
        <section anchor="commitment-establishment-flow">
          <name>Commitment Establishment  Flow</name>
          <t>As transactions cannot be undone on blockchains, reverting a transaction includes issuing new transactions (with the contrary effect of the ones to be reverted). We use a rollback list to keep track of which transaction may be rolled back.
The crash recovery protocol for the Stage 2 (lock) and Stage 3 (mint) is as follows:</t>
          <ol spacing="normal" type="1"><li>
              <t>Rollback lists for all the gateways involved are initialized.</t>
            </li>
            <li>
              <t>On step 2.1A, add a pre-lock transaction to the origin gateway rollback list.</t>
            </li>
            <li>
              <t>On step 2.1B, if the request is denied, abort the transaction and apply rollbacks on the origin gateway.</t>
            </li>
            <li>
              <t>On step 3.4A, add a lock transaction to the origin gateway rollback list.</t>
            </li>
            <li>
              <t>On step 3.4B, if the commit fails, abort the transaction and apply rollbacks on the origin gateway.</t>
            </li>
            <li>
              <t>On step 3.6A,  add a create asset transaction to the rollback list of the destination gateway.</t>
            </li>
            <li>
              <t>On step 3.8, if the commit is successful (confirmed by the ack final receipt), SATP terminates (3.9).</t>
            </li>
          </ol>
          <t>8: Otherwise, if the last commit is unsuccessful, then abort the transaction and apply rollbacks to both gateways.</t>
        </section>
      </section>
      <section anchor="recovery-messages">
        <name>Recovery Messages</name>
        <t>SATP-2PC messages are used to recover from crashes at the several SATP phases.
These messages inform gateways of the current state of a recovery procedure.
SATP-2PC messages follow the log format from Section 4.</t>
        <section anchor="recover">
          <name>RECOVER</name>
          <t>A recover message is sent from the crashed gateway to the counterparty gateway, sending its most recent state.
This message type is encoded on the recovery message field of an SATP log.</t>
          <t>The parameters of the recovery message payload consist of the following:</t>
          <ul spacing="normal">
            <li>
              <t>Session ID: a unique identifier (UUIDv2) representing a session.</t>
            </li>
            <li>
              <t>Context ID: a unique identifier (UUIDv2) representing a session context <xref target="I-D.draft-avrilionis-satp-setup-stage-01"/>.</t>
            </li>
            <li>
              <t>Message Type REQUIRED: urn:ietf:SATP-2pc:msgtype:recover-msg.</t>
            </li>
            <li>
              <t>SATP phase: latest SATP phase registered.</t>
            </li>
            <li>
              <t>Sequence number: latest sequence number registered.</t>
            </li>
            <li>
              <t>Is_Backup REQUIRED: indicates whether the sender is a backup gateway or not.</t>
            </li>
            <li>
              <t>New Identity Public Key: The public key of the sender if it is a backup gateway.</t>
            </li>
            <li>
              <t>Last_entry_timestamp REQUIRED: Timestamp of last known log entry.</t>
            </li>
            <li>
              <t>Sender Signature REQUIRED. The digital signature of the sender.</t>
            </li>
          </ul>
        </section>
        <section anchor="recover-udpdate">
          <name>RECOVER-UDPDATE</name>
          <t>The counterparty gateway sends the recover update message after receiving a RECOVER message from a recovered gateway. The recovered gateway informs of its current state (via the current state of the log).
The counterparty gateway now calculates the difference between the log entry corresponding to the received sequence number from the recovered gateway and
the latest sequence number (corresponding to the latest log entry).
This state is sent to the recovered gateway.</t>
          <t>The parameters of the recover update payload consist of the following:</t>
          <ul spacing="normal">
            <li>
              <t>Session ID: a unique identifier (UUIDv2) representing a session.</t>
            </li>
            <li>
              <t>Context ID: a unique identifier (UUIDv2) representing a session context <xref target="I-D.draft-avrilionis-satp-setup-stage-01"/>.</t>
            </li>
            <li>
              <t>Message Type REQUIRED: urn:ietf:SATP-2pc:msgtype:recover-update-msg.</t>
            </li>
            <li>
              <t>Hash Recover Message REQUIRED. The hash of previous message.</t>
            </li>
            <li>
              <t>Recovered logs: the list of log messages that the recovered gateway needs to update.</t>
            </li>
            <li>
              <t>Sender Signature REQUIRED. The digital signature of the sender.</t>
            </li>
          </ul>
        </section>
        <section anchor="recover-success">
          <name>RECOVER-SUCCESS</name>
          <t>The recover-success message (response to RECOVER-UPDATE) states if the recovered gateway's logs have been successfully updated. If inconsistencies are detected, the recovered gateway answers with initiates a dispute (RECOVER-DISPUTE message).</t>
          <t>The counterparty gateway sends this message to sinalize the recovered gateway acknowledging that the state is synchronized.</t>
          <t>The parameters of this message consist of the following:</t>
          <ul spacing="normal">
            <li>
              <t>Session ID: a unique identifier (UUIDv2) representing a session.</t>
            </li>
            <li>
              <t>Context ID: a unique identifier (UUIDv2) representing a session context <xref target="I-D.draft-avrilionis-satp-setup-stage-01"/>.</t>
            </li>
            <li>
              <t>Message Type REQUIRED: urn:ietf:SATP-2pc:msgtype:recover-update-ack-msg.</t>
            </li>
            <li>
              <t>Hash Recover Update Message REQUIRED. The hash of previous message.</t>
            </li>
            <li>
              <t>success: true/false.</t>
            </li>
            <li>
              <t>entries changed: list of hashes of log entries that were appended to the recovered gateway log.</t>
            </li>
            <li>
              <t>Sender Signature REQUIRED. The digital signature of the sender.</t>
            </li>
          </ul>
        </section>
        <section anchor="rollback">
          <name>ROLLBACK</name>
          <t>A rollback message is sent by a gateway that initiates a rollback. The parameters of this message consist of the following:</t>
          <ul spacing="normal">
            <li>
              <t>Session ID: a unique identifier (UUIDv2) representing a session.</t>
            </li>
            <li>
              <t>Context ID: a unique identifier (UUIDv2) representing a session context <xref target="I-D.draft-avrilionis-satp-setup-stage-01"/>.</t>
            </li>
            <li>
              <t>Message Type REQUIRED: urn:ietf:SATP-2pc:msgtype:rollback-msg.</t>
            </li>
            <li>
              <t>success: true/false.</t>
            </li>
            <li>
              <t>actions performed: actions performed to rollback a state (e.g., UNLOCK; BURN).</t>
            </li>
            <li>
              <t>proofs: a list of proofs specific to the network</t>
            </li>
            <li>
              <t>Sender Signature REQUIRED. The digital signature of the sender.</t>
            </li>
          </ul>
        </section>
        <section anchor="rollback-ack">
          <name>ROLLBACK-ACK</name>
          <t>The counterparty gateway sends the rollback-ack message to the recovered gateway acknowledging that the rollback has been performed successfully.</t>
          <t>The parameters of this message consist of the following:</t>
          <ul spacing="normal">
            <li>
              <t>Session ID: a unique identifier (UUIDv2) representing a session.</t>
            </li>
            <li>
              <t>Context ID: a unique identifier (UUIDv2) representing a session context <xref target="I-D.draft-avrilionis-satp-setup-stage-01"/>.</t>
            </li>
            <li>
              <t>Message Type REQUIRED: urn:ietf:SATP-2pc:msgtype:rollback-ack-msg.</t>
            </li>
            <li>
              <t>success: true/false.</t>
            </li>
            <li>
              <t>actions performed: actions performed to rollback a state (e.g., UNLOCK; BURN).</t>
            </li>
            <li>
              <t>proofs: a list of proofs specific to the network</t>
            </li>
            <li>
              <t>Sender Signature REQUIRED. The digital signature of the sender.</t>
            </li>
          </ul>
        </section>
      </section>
      <section anchor="examples">
        <name>Examples</name>
        <t>There are several situations when a crash may occur.</t>
        <section anchor="crashing-before-issuing-a-command-to-the-counterparty-gateway">
          <name>Crashing before issuing a command to the counterparty gateway</name>
          <t>The following figure represents the origin gateway (G1) crashing before it issued an init command to the destination gateway (G2).</t>
          <artwork><![CDATA[
   ,--.                           ,--.              ,-------.
     |G1|                           |G2|              |Log API|
     `--'                           `--'              `-------'
       |     [1]: writeLogEntry <1, 1, init-validate>     |
       |------------------------------------------------->|
       |                              |                   |
       |----.                         |                   |
       |    | [2]  Crash              |                   |
       |<---'  ...                    |                   |
       |      [3]recover              |                   |
       |                              |                   |
       |                              |                   |
       |      [4] <1, 2, RECOVER>     |                   |
       |----------------------------->|                   |
       |                              |                   |
       |                              | [5] getLogEntry(i)|
       |                              |------------------>|
       |                              |                   |
       |                              |   [6] logEntries  |
       |                              |< - - - - - - - - -|
       |                              |                   |
       |   [7] <1,3,RECOVER-UPDATE>   |                   |
       |<-----------------------------|                   |
       |                              |                   |
       |----.                         |                   |
       |    | [8] process log         |                   |
       |<---'                         |                   |
       |                              |                   |
       |              [9] <1,4,writeLogEntry>             |
       |------------------------------------------------->|
       |                              |                   |
       | [10] <1,5,RECOVER-UPDATE-ACK>|                   |
       |----------------------------->|                   |
       |                              |                   |
       |   [11] <1,6,RECOVER-SUCESS>  |                   |
       |<-----------------------------|                   |
       |                              |                   |
       |           [12]: <1,7,init-validateNext>          |
       |------------------------------------------------->|
     ,--.                           ,--.             ,-------.
     |G1|                           |G2|             |Log API|
     `--'                           `--'             `-------'

]]></artwork>
        </section>
        <section anchor="crashing-after-issuing-a-command-to-the-counterparty-gateway">
          <name>Crashing after issuing a command to the counterparty gateway</name>
          <t>The second scenario requires further synchronization (figure below). At the retrieval of the latest log entry, G1 notices its log is outdated. It updates it upon necessary validation and then communicates its recovery to G2. The process then continues as defined.</t>
          <artwork><![CDATA[
     ,--.                          ,--.                             ,-------.
     |G1|                          |G2|                             |Log API|
     `--'                          `--'                             `-------'
       |            [1]: writeLogEntry <1,1,init-validate>              |
       |--------------------------------------------------------------->|
       |                             |                                  |
       |   [2]: <1,1,init-validate>  |                                  |
       |---------------------------->|                                  |
       |                             |                                  |
       |----.                        |                                  |
       |    | [3] Crash              |                                  |
       |<---'                        |                                  |
       |                             |                                  |
       |                             |[4]: writeLogEntry <exec-validate>|
       |                             |--------------------------------->|
       |                             |                                  |
       |                             |----.                             |
       |                             |    | [5]: execute validate       |
       |                             |<---'                             |
       |                             |                                  |
       |                             |[6]: writeLogEntry <done-validate>|
       |                             |--------------------------------->|
       |                             |                                  |
       |                             |[7]: writeLogEntry <ack-validate> |
       |                             |--------------------------------->|
       |                             |                                  |
       | [8] <1,2,init-validate-ack> |                                  |
       |  discovers that G1 crashed  |                                  |
       |  via timeout                |                                  |
       |<----------------------------|                                  |
       |                             |                                  |
       |----.                        |                                  |
       |    | [9] Recover            |                                  |
       |<---'                        |                                  |
       |                             |                                  |
       |     [10] <1, 2, RECOVER>    |                                  |
       |----------------------------->                                  |
       |                             |                                  |
       |                             |        [11] getLogEntry(i)       |
       |                             |--------------------------------->|
       |                             |                                  |
       |                             |          [12] logEntries         |
       |                             |<- - - - - - - - - - - - - - - - -|
       |                             |                                  |
       |   [13] <1,3,RECOVER-UPDATE> |                                  |
       |<----------------------------|                                  |
       |                             |                                  |
       |----.                        |                                  |
       |    | [14] process log       |                                  |
       |<---'                        |                                  |
       |                             |                                  |
       |                     [15] <1,4,writeLogEntry>                    |
       |--------------------------------------------------------------->|
       |                             |                                  |
       |[16] <1,5,RECOVER-UPDATE-ACK>|                                  |
       |---------------------------->|                                  |
       |                             |                                  |
       |  [17] <1,6,RECOVER-SUCESS>  |                                  |
       |<----------------------------|                                  |
       |                             |                                  |
       |                  [18]: <1,7,init-validateNext>                 |
       |--------------------------------------------------------------->|
     ,--.                           ,--.                             ,-------.
     |G1|                           |G2|                             |Log API|
     `--'                           `--'                             `-------'

]]></artwork>
        </section>
        <section anchor="rollback-after-counterparty-gateway-crash">
          <name>Rollback after counterparty gateway crash</name>
          <t>At the retrieval of the latest log entry, G1 notices its log is outdated. It updates it upon necessary validation and then communicates its recovery to G2. The process then continues as defined.</t>
          <artwork><![CDATA[
    ,--.                            ,--.                            ,-------.
     |G1|                            |G2|                            |Log API|
     `--'                            `--'                            `-------'
       |              ...              |                                  |
       |                               |                                  |
       |  [1] <3, 1, COMMIT-PREPARE>   |                                  |
       |------------------------------>|                                  |
       |                               |                ...               |
       |----.                          |                                  |
       |    | [2]  Crash               |                                  |
       |<---'                          |                                  |
       |                               |                                  |
       |[3] <3, 2, COMMIT-PREPARE-ACK> |                                  |
       |  discovers that G1 crashed    |                                  |
       |  via timeout                  |                                  |
       |<------------------------------|                                  |
       |                          .----|                                  |
       |             [4]  Timeout |    |                                  |
       |                          '--->|                                  |
       |                               |                                  |
       |                               |[5]: writeLogEntry <exec-rollback>|
       |                               |--------------------------------->|
       |                               |                                  |
       |                               |----.                             |
       |                               |    | [6]: execute rollback       |
       |                               |<---'                             |
       |                               |                                  |
       |                               |[7]: writeLogEntry <done-rollback>|
       |                               |--------------------------------->|
       |                               |                                  |
       |                               |[8]: writeLogEntry <ack-rollback> |
       |                               |--------------------------------->|
       |                               |                                  |
       |                               |                                  |
       |----.                          |                                  |
       |    | [9] Recover              |                                  |
       |<---'                          |                                  |
       |      [10] <3, 3, RECOVER>     |                                  |
       |------------------------------>|                                  |
       |                               |                                  |
       |                               | [11] getLogEntry(i)              |
       |                               |--------------------------------->|
       |                               |                                  |
       |                               |   [12] logEntries                |
       |                               |<- - - - - - - - - - - - - - - - -|
       |                               |                                  |
       |   [13] <3, 4, RECOVER-UPDATE> |                                  |
       |<------------------------------|                                  |
       |                               |                                  |
       |----.                          |                                  |
       |    | [14] process log         |                                  |
       |<---'                          |                                  |
       |                               |                                  |
       |                  [15] <3, 5, writeLogEntry>                      |
       |----------------------------------------------------------------->|
       |                               |                                  |
       |[16] <3, 6, RECOVER-UPDATE-ACK>|                                  |
       |------------------------------>|                                  |
       |                               |                                  |
       |   [17] <3, 7, RECOVER-SUCESS> |                                  |
       |<------------------------------|                                  |
       |                               |                                  |
       |   [18] G1 discovers G2 made   |                                  |
       |        the rollback           |                                  |
       |                               |                                  |
       |----.                          |                                  |
       |    | [19]  Rollback           |                                  |
       |<---'                          |                                  |
       |                               |                                  |
       |  [20] <3, 8, ROLLBACK-ACK>    |                                  |
       |------------------------------>|                                  |
       |                               |                                  |
     ,--.                             ,--.                             ,-------.
     |G1|                             |G2|                             |Log API|
     `--'                             `--'                             `-------'

]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="session-resumption">
      <name>Session Resumption</name>
      <t>This section explains how the primary-backup mode works for crash recovery. First, there is a session resumption phase. After that, the gateways perform the protocol specified in Section 5.</t>
      <section anchor="gateway-replacement">
        <name>Gateway Replacement</name>
        <t>The gateway replacemenet protocol introduces an assumption. We assume every gateway has a valid X.509 certificate that was issued by its owner, which is the entity legally responsible for the gateway.
Moreover, in the extensions field of the certificate, there is a list containing the hash of the authorized backup gateways.
When the primary gateway crashes, a replacement is bootstrapped with the latest version of the local state, and it engages in a protocol with the counterparty gateway.
This protocol aims to establish trust between gateways and the creation of a new TLS session:</t>
        <ol spacing="normal" type="1"><li>
            <t>Validate the backup gateway certificate by running a certification path algorithm, which includes validating all the intermediate certificates up to a trusted root (can be the VASPs CA).</t>
          </li>
          <li>
            <t>The counterparty gateway verifies if the parent certificate of the crashed gateway and the backup gateway is the same (proving they belong to the same authority).</t>
          </li>
          <li>
            <t>Verify if the backup gateway certificate hash belongs to the list specified in the crashed gateway certificate extensions.</t>
          </li>
        </ol>
        <t>The backup gateway, on its turn, defines gateways to replace it in case of a crash (X.509 certificate extensions).</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>We assume a trusted, authenticated, secure, reliable communication channel between gateways (i.e., messages cannot be spoofed and/or altered by an adversary) using TLS/HTTPS <xref target="TLS"/>. Clients support acceptable credential schemes such as OAuth2.0.
We assume the storage service used provides the means necessary to assure the logs' confidentiality and integrity, stored and in transit. The service must provide an authentication and authorization scheme, e.g., based on OAuth and OIDC <xref target="OIDC"/>, and use secure channels based on TLS/HTTPS.
The present protocol is crash fault-tolerant, meaning that it handles gateways that crash for several reasons (e.g., power outage). The present protocol does not support Byzantine faults, where gateways can behave arbitrarily (including being malicious). This implies that both gateways are considered trusted. We assume logs are not tampered with or lost.</t>
      <t>Log entries need integrity, availability, and confidentiality guarantees, as they are an attractive point of attack. Every log entry contains a hash of its payload for guaranteeing integrity.  If extra guarantees are needed (e.g., non-repudiation),  a log entry might be signed by its creator. Availability is guaranteed by the usage of the log storage API that connects a gateway to a dependable storage (local, external, or decentralized). Each underlying storage provides different guarantees. Access control can be enforced via the access control profile that each log can have associated with, i.e., the profile can be resolved, indicating who can access the log entry in which condition. Access control profiles can be implemented with access control lists for simple authorization. The authentication of the entities accessing the logs is done at the Log Storage API level (e.g., username+password authentication in local storage vs. decentralized access control).</t>
      <t>For extra guarantees, the nodes running the log storage API (or the gateway nodes themselves) can be protected by hardening technologies such as Intel SGX.</t>
    </section>
    <section anchor="performance-considerations">
      <name>Performance Considerations</name>
      <t>After the session setup using asymmetric-cryptography, the authenticated messages in the TLS Record Protocol utilize symmetric-key operations (using the session key). Since symmetric-key
operations are much faster than public-key operations, a persistent TLS connection delivers performance suitable for quickly exchange of log entries across gateways. Upon a crash, gateways might employ their best effort for resuming the crashed session.</t>
    </section>
    <section anchor="assumptions">
      <name>Assumptions</name>
      <t>For the protocol to work correctly, a few assumptions are taken: i) the crashed gateways eventually recover, at most for a fixed time (or are replaced); ii) The Log API is reliable - all requests are served up to a pre-defined time bound.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="TLS">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </reference>
        <reference anchor="HTTP2">
          <front>
            <title>HTTP/2</title>
            <author fullname="M. Thomson" initials="M." role="editor" surname="Thomson"/>
            <author fullname="C. Benfield" initials="C." role="editor" surname="Benfield"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>This specification describes an optimized expression of the semantics of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTTP/2). HTTP/2 enables a more efficient use of network resources and a reduced latency by introducing field compression and allowing multiple concurrent exchanges on the same connection.</t>
              <t>This document obsoletes RFCs 7540 and 8740.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9113"/>
          <seriesInfo name="DOI" value="10.17487/RFC9113"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="OIDC" target="http://openid.net/specs/openid-connect-core-1_0.html">
          <front>
            <title>OpenID Connect Core 1.0</title>
            <author initials="N." surname="Sakimura">
              <organization/>
            </author>
            <author initials="J." surname="Bradley">
              <organization/>
            </author>
            <author initials="M." surname="Jones">
              <organization/>
            </author>
            <author initials="B." surname="de Medeiros">
              <organization/>
            </author>
            <author initials="C." surname="Mortimore">
              <organization/>
            </author>
            <date year="2014" month="November"/>
          </front>
        </reference>
        <reference anchor="AD76" target="http://openid.net/specs/openid-connect-core-1_0.html">
          <front>
            <title>A principle for resilient sharing of distributed resources</title>
            <author initials="P." surname="Alsberg">
              <organization/>
            </author>
            <author initials="D." surname="Day">
              <organization/>
            </author>
            <date year="1976"/>
          </front>
        </reference>
        <reference anchor="I-D.draft-ietf-satp-core">
          <front>
            <title>Secure Asset Transfer Protocol (SATP) Core</title>
            <author fullname="Martin Hargreaves" initials="M." surname="Hargreaves">
              <organization>Quant Network</organization>
            </author>
            <author fullname="Thomas Hardjono" initials="T." surname="Hardjono">
              <organization>MIT</organization>
            </author>
            <author fullname="Rafael Belchior" initials="R." surname="Belchior">
              <organization>Tecnico Lisboa</organization>
            </author>
            <author fullname="Venkatraman Ramakrishna" initials="V." surname="Ramakrishna">
              <organization>IBM</organization>
            </author>
            <author fullname="Alexandru Chiriac" initials="A." surname="Chiriac">
              <organization>Quant Network</organization>
            </author>
            <date day="19" month="July" year="2026"/>
            <abstract>
              <t>   This memo describes the Secure Asset Transfer Protocol (SATP) for
   digital assets.  SATP is a protocol operating between two gateways
   that conducts the transfer of a digital asset from one gateway to
   another, each representing their corresponding digital asset
   networks.  The protocol establishes a secure channel between the
   endpoints and implements a 2-phase commit (2PC) to ensure the
   properties of transfer atomicity, consistency, isolation and
   durability.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-satp-core-14"/>
        </reference>
        <reference anchor="I-D.draft-avrilionis-satp-setup-stage-01">
          <front>
            <title>SATP Setup Stage</title>
            <author fullname="Denis Avrilionis" initials="D." surname="Avrilionis">
              <organization>Compellio S.A.</organization>
            </author>
            <author fullname="Thomas Hardjono" initials="T." surname="Hardjono">
              <organization>MIT</organization>
            </author>
            <date day="16" month="December" year="2024"/>
            <abstract>
              <t>   SATP Core defines an unidirectional transfer of assets in three
   stages, namely the Transfer Initiation stage (Stage-1), the Lock-
   Assertion stage (Stage-2) and the Commitment Establishment stage
   (Stage-3).  This document defines the Setup Phase, often called
   "Stage-0", prior to the execution of SATP Core.  During Setup, the
   two Gateways that would participate in the asset transfer are bound
   together via a "transfer context".  The transfer context conveys
   information regarding the assets to be exchanged.  Gateway can
   perform any kind of negotiation based on that transfer context,
   before entering into SATP Core.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-avrilionis-satp-setup-stage-01"/>
        </reference>
      </references>
    </references>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
