<?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.30 (Ruby 3.4.8) -->
<?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-04" category="info" consensus="true" submissionType="IETF" tocDepth="4" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.31.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-04"/>
    <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="January" day="27"/>
    <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">
         </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="2" month="November" year="2025"/>
            <abstract>
              <t>   This memo describes the Secure Asset Transfer (SAT) Protocol for
   digital assets.  SAT 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-12"/>
        </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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
GY0YtpuXCnLU9+7FiAjr527ZuukctwGSss1nx/qXxOP6KdyW9FmUypdLhIfe
J2LuIUs0nJeYKoFZbOI6axZurWU1c0HnVC4PagtyRy7xp7VqtB+dnL587Y1U
1l/4UlEYqhgZ5j+jw8k6UEq3o25RPf96u99oDbsG4/3JoGsZFJ2Qapn0Ncu4
a/BqKfThzjhKxLvUXouJBaTvGLg+kxktOplMXFacdQJbVM+bYucXT5/+cHj0
E6nh9ihW1cNLpcIrFey9LcE64v5JmZtQpiDN0eM6QrIWH0kwh6S08ohOgnbx
bH5w8ZR7/Rxv3/+qfnj96jl7/cIBLhsbxJClSX6y4jgtDrk3TmttordN1EmL
pJAo1/LFGjHqEIOX7bSPeLyFO8qfkvVa9Pv/FQ3bDCAGSUXcfK2ZxcTFQjxK
xLuVbaNoOSU/VOGCI+uYIddnPi2qdWi9xLpRTd8yjicLyujqomlqTILNJ90d
7w9ihy04OfbIlnSsDl9jg4Oeeju+RN0VNTdXX29af1MCZlcqW2xaclOteb1S
Vo77ry8hvVJokqt3uToiH7aOVn34oTzu+pnXPSuNux7vl3/L/7zp/abk1meL
b6UsUKdTO/jV4yqs9GtPlVt/u+7nc3/7Zv83ooZeyx5gHm7w7RV08JlhXv/t
m7u/hckDm/HOxt9+Nnq++ts3B7+h1msjbDf/9nvVrv7fjcH85t5vXKe6fK59
eOW362sP4c/no40bkBv3f3OZpcu5GC/79vJyYv8pXnjz4DeuvV0S9A/XfPul
ZDvsRbsE590KWaHOfIXc+IIy5023S1AftALz0PHp6cOvlReCh2+6Pdj+Afh7
rdJ2/xw06Yd1316bNrbVlz5RXfpEbalS2Kusu7JFfzvV9Yx06SHm0TBDnUZ5
nPn08jbDhbd1SYIM0XAxrPZihypT8+kPt4JzLBpgL2fLRnCqWZ5m6DlvrEcZ
BQwuCms3LMSGiO/Z6yfVKNrQmSIoei8+UmngtiVduns+LG7SE/OHTbzPX5Cn
siYPB3YQsgmwN6GIK2vab0UgVxa134perqxqv0bXlp96lbvbqlG4PXzX58B6
frxKhmySmrYkBUWQrE5jq54uB31LmC5pti1Ma2lxa5g+4Elg0wPI2p4u1Su+
EJ4ubwZniRWqp3hdRyqb9vTFaPwKmC6XV9vARGeVvovRtRjasqerS9l+ASo4
WKUCirj+JqgAjkUrs0MboZeGX/ns8JADQrxXFuJo53y4LZ5GseHwC7ZGg0Zi
HZm27Yk8GsTv9VNmd6m+/a3sLXDSe7VqZvo29hZ7Pqzao25Mw2g/vLSTOpjW
Nrv5nuigWTZgbdnT1ygz/a94GC2Zurbs6fsVe9c17V9b677dvTXmsD/lU1U+
dffrzGjfhnyq/rzp3r3a7rbS1ZVM+gVY+E33YDvL3LVm96UOeLhS97ax4a3t
6Wtk4dV3b7r3N7H6rfR0Q5S59dXpagP6ue5NarXBJ16srjagn9B06GJ62HRY
6/lB2nHjWzHxyTpdupAbvN9ina9c6O3WeZP3ss62//L7lavim2P/a4g3kG57
dKt/9OLZs5Oz9stXxy8PX629sFvb11Ucvh1clzesPli9fN/0fu9amsoaP4Eb
1FW+IE2gDRIpolelCNrRb/Csf5On/ZvcjG9sO+58Wl/oYkGBLTjfD1eMtQ1c
tz87P35KX2TfrLMGWze4je+Ub/BUe8NzvEImbdUX/0PWU2sVdg6D2/Z1Y3bh
m6aJGusp2Ya/IZp4c7/eQuymuCV9fY1z3KavK3jk5iygX3zfZuMlbLl7GzjT
re3rqgXfHq71DW+0r/XGy637+orpfp0Jc+u+bsyWuf0c2ZoJVLrfUp/PnnmT
5pAvL3PqrZpfXOZ8rr7YsAkkcrelrjZtbi6/Nvj5TLzNBk6Y0UGV6G/WxPmF
ZTTbOWGa91qqaun8JnhbsXUTj6D+UPqkp2bRSF+jL/opBVJdH65LG27T1+eQ
X6A0eSvlNfv6euXXm57oXvdbpUC8G749/lK8vYnF/CZN6uqmjerXMau7oMNX
LlNeOfOxJMAzaipJeepyE2N8HCfZKifz6qjHmKS45ZNV1qcqpoo6pfyipURd
EuEnw0t6MJ+7LciSepdj7GzJkleaEsBhhrVGmCMxd8914XuMMXX6aDGkfK+c
EJfgo6RnnB8Xc/j6RLKSfJmuAbicUlgmSSKyI2Oj5AZLzul4keq8JQnSJKuz
JIBJ9ETSA1POgxjzKds0aC7ZxrMs14jdls05p38vdGoobNAlGSIX6rBkU7AC
FO9YyckZFi/CilFZTglOy9llTKfxiy0RVMmp6xM8RwF2KUfNIMsKU+QYlT5a
Seh6LtXNXGYVrktDIFMmywJwM5FEU5SBTRbr0rSlkr7ENY7iGZfrcLmRi3xh
CpeLxVGazWZJKcd8CRV9QYmUhXQ5w9zP1p0Q21cS/IRUgElqF2kqTu7uBdF9
hPk3kwkgu5jOHEnY1H32egm/lNx1WNsFQ10xcD4cxSgYHSYY8cQA0TlgXTUl
ETN++vPh6Uujjg53OL3d2thpWBFkK5dVA97iQoZTsvRVzW8ryKsgI0hcrppY
D0xobhkUunINhPYKTEGDOfN+RmiWFpZL0EwEzB0al9YGCb0kJ+rADnvxrITp
1M5Whmxhei9kYqzf2fJp4S39UD41STpJOSGHkjHThvI2V8WEH5NylKIsWyAG
MJY7SDLf8ELIrXKL8IXCA3saYeIy+FZjWsgkpmzspUSxlEoi1ckq3UuGd5cW
xuedBEGUjSnEd3SHkihSLizK54CVzJB/QQzsSOpi4JI7WKP2VL1/D79jmu+j
JKaoYqn1SPWT5gUD56uXUIkzTfn3pngPSjVOep3dTjBtzmjC2ZYxD3c8lCx2
RFQjSbU00xEIQn9Ji1wB30vSXcwHc3ulXhTnzC30BPHekipR8pQT8cUFs4wd
d4biQ8YlTPh1cAn7RIzyE55gS3E4+iAynCqO5knNX5w8OgKs4X8+fmThh4k2
eUXtyhn/pUN1x2aupUQbfjczQnJU6apdZAlQUlq0CEEuvUGMFQTSUVIiYi6A
Rd9i5VmJTsdqjJQ4lKcwzy6wnOyioIQ2qhYGl9DeLv4Py39FeNutGSqDMk+H
5VBZYFHCnigfxJiXNIYNsclCkYPPKe8+LNwQU6nQ0FgOaYaJVm0FvTAxIoXY
27z+mCWAeSfc1SlLEDZDWDE1GjWkLYZKnFIazKdBshXMjRRSjGT+xsqGy5Yt
MVAisckiQvRr2iINyz8cEWmnwKypnFQ+g05JXhQF5UM5Jn0jzBMmtd8it2Wj
OJoH1Q/dSJTB0MLYoaThIGvyKICFJ01J9+26plnaBhm2GHF24R1MwxkAMIsn
UxYM8ST1Sg1tmFkOSlyACaRBN5bLormgNBFBibawfDDTHhcsMGHKmIySr2Ni
GxId9psmaQwtEqJ5ir8BBkpJ2oFAjjHZclAF1n7s5IZNz1YEqOlIQTolJXVs
UQONeeOGMB2bIi4qN7MV6mgmrmIjfsxUXa65BUocSV5RbelLGQhLQWF62lZY
IfpimlWq0AVrA8KKVQiMkItZdT2shc5VskW2IU3N0ntlNj59rqGmZakmZafL
sk9WllRaqWaMepOvTEiFgimbseRXQc46DYiAy+cJPYIQhIWd6b/MAXVw0BhV
x8Pszq6cIXZxDmtXztNfnhTlFscc3BVm4FVIqSi3VdnqaLRZ1sjlC3gyMxoW
zOxY5KIcdAUwplGOCX6xTz2cphn0Ggcb3gmAkKjTJ7+i4gFawEs+81Dl1Ioi
YM9J2p2lKCGLbMGRWc5m6Pg0bFOx5GwCqvdUsqiX1IUwhyu9RR0XL31yqhXG
InxRxJR3zPdK6ShdKULVDOtKMDjQArjuNEbYS981gu9Q8sxw8uPIyLkvlYyX
lSFa5bIw5ZImsNJJTPapeYAxs4hZxUDK/eciHr6jaoOcSquaOSsa5pnx+19H
vUY3L1fAxe0jLPo0sEFGkizOYZFBDdDjMe5tOBQdal2tBFE0fX6e77A6rpwq
DdFg6UiLVQ2xNi3laBwWmPo+UmM4fPizKOMNc5unfRXv1Cm0pqbQTAtZjTLZ
UiZsOCf+jjthjCo5PuAEMKi3Yg3EGDo+E75Ego+NVyjbdBaRrNVG0tfkmKTS
nkAwSba4sfEIAzhmUPbUdpvU6cb/A9trbr8x3gAA

-->

</rfc>
