<?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-06" 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-06"/>
    <author initials="R." surname="Belchior" fullname="Rafael Belchior">
      <organization>INESC-ID</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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
1WY4UoRhYi2DkF6nq8+IsZdiwQQR/E0CxFNCw1VnEa9Ge5QnFNeL4cYrY1Mo
UuCr/IOjQZBA44Dn+sA6RIonPlTkYPeyQIjTc9DJRH5UAxlaQpUBOYP+LTrn
ZacEOmGtX2zk3LIvKIaGI/Qo2JUWJF9gkFyGCjCe/SX8kOkJsIv8HqU170va
NC2Uy/o8Zpf51WOb1RWCi9yqpePw5cmKnSOaxxyBtuKFHXHEzQh4Y4KrYazn
vETvh9w7/FZiC1vhEUlRCh+8dEdEAXgN8seAHYvhVcR3iNLlrIfxt2xSVefA
IPAo5x+1WBLQG3hBrGyHgoRIkQM+PaLgCtbMRB1AurEbnMxEf9nQvrhBu027
urqjxgf1WDworjCmBYFla5scp6N5BkjewIZ26VhfLa4Oyb8/OO+tQQQ0OBmp
dtBQKJm+B4IEdL44PVN3ysbsO33+8McM0/CIOREz/aCWqOfwLPJpj+78w8Ci
fb24eiH++NGl6Pqg4jKi4M+VJk+Oz8IYiDv9uA5Hf2C6ehHGLnCQRWAS8IhA
9e7yKQa4kmiNayDqD4Or4OS6ggjEHBMW7z02H+lR0EQ2oY/boA14bYx9CEJn
2XpEJkxUeV0ANT7Z4PJiu4ueS6H6I6xjJV6nhIgtaN7GA33TNO+DlFYRsRV/
uCaWvm5cuRs5UDPbBWb7+FgNvKKnGHhkqmf3XBeLPEXn0oWoxhydZ7TFEqaE
2EyZu7E53fAPktMrmuc6PQ6p5JWdtziBbkEZn/EHiO5/XvVzdYsv84N4P5Mb
jaUEZ1oZb7nfB0pfdqfb6are7q568ZM6iuBM3T7iI0XfWSweUYa3Z3hBs9tT
zyLMTtfbVbt3+7v3+nt31ZNnZ5hEDXMZtc8o7+SK4vhe3RL36luc1LKlbllq
f4vWhVv9W71b6iPj/YNqYl63dLKzdm3+c2Sw1c8mjOpr3quHV5w2vjKaUe87
nc5HIJs/Ot7PLlXFvzq8/7lXv/CPpZlL4ta/Npr5ZvbqnzzyP//jeGTNQeRP
vH++n+CIw8eVNh9X2uGBp/Hdd995Hf7I+RtahLSH4mxYZ4ZXz16fnsnJR67o
5GA0ZD+AdESYFxedcRQn5Gum8zzL1d1ffyXXOFkMKzzd7YpqAilIotxgEcl1
YRjlmBVwUaCvyyKnKyf/oc2zuiDXNvIb4XR1fLeGt+EzJCa8vFisDtypn607
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
tDI7tBF6bviVzw4POcDEe2UmjnbOh9viaRQbDr9gazRoJNaRadueyKNB/F4/
ZXaX6tvfimyBk96rVTPTtyFb7Pmwao+6MQ2j/fDSTupgWtvs5nuig2bZgLVl
T18jz/S/4mG0ZOrasqfvV+xd17R/ba37dvfWmMP+5E9V/tTdrzOjfRv8qfrz
pnv3arvbSldXbtIvsIXfdA+2s8xda3Zf6oCHK3VvGxve2p6+xi28+u5N9/4m
Vr+Vnm6IMre+Ol1tQD/XvUmtNvjEi9XVBvQTmg5dTA+bDms9P0g7bnwrJj5Z
p0sXcoP3W6zzlQu93Tpv8l7W2fZffr9yVXxz2/8a7A242x7d6h+9ePbs5Kz9
8tXxy8NXay/s1vZ11Q7fDq7LG1YfrF6+b3q/dy1NZY2fwA3qKl+QJtAGiRTR
q1IESfQbPOvf5Gn/JoXxjYnjzqf1hS4WFNiC8/1wxVjbwHX7s+/HT+mL7Jt1
1mDrBrfxnfINnmpveI5X8KSt+uJ/yHpqrcLOYXDbvm7MLnzTNFFjPSXb8DdE
E2/u11uI3RS3pK+vcY7b9HXFHrk5C+gXl9tsvASRu7eBM93avq5a8O3hWt/w
Rvtab7zcuq+vmO7XmTC37uvGbJnbz5GtmUCl+y31+eyZN2kO+fI8p96q+cV5
zufqiw2bQCJ3W+pq0+bm/GuDn8+0t9nACTM6qBL9zZo4vzCPZjsnTPNeS1Ut
nd/E3lZs3cQjqD+UPumpWTTS1+iLfkqBVNeH69KG2/T1OfgXKE3eSnnNvr5e
/vWmJ7rX/VYpEO+Gb4+/1N7exGJ+kyZ1ddNG9euY1V3Q4SuXKa+c+VgS4Bk1
laQ8dbmJMT6Ok2yVk3l11GNMUtzyySrrUxVTRZ1SftFSoi6J8JPhJT2Yz90W
ZEm9yzF2tmTJK00J4DDDWiPMkZi757rwPcaYOn20GFK+V06IS/BR0jPOj4s5
fH0iWUm+TNcAXE4pLJMkEdmRsVFygyXndLxIdd6SBGmS1VkSwCR6IumBKedB
jPmUbRo0l2zjWZZrxG7L5pzTvxc6NRQ26JIMkQt1WLIpWAGKd6zk5AyLF2HF
qCynBKfl7DKm0/jFlgiq5NT1CZ6jALuUo2aQZYUpcoxKH60kdD2X6mYuswrX
pSGQKZNlAbiZSKIpysAmi3Vp2lJJX+IaR/GMy3W43MhFvjCFy8XiKM1ms6SU
Y76Eir6gRMpCupxh7mfrTojtKwl+QirAJLWLNBUnd/eC6D7C/JvJBJBdTGeO
JGzqPnu9hF9K7jqs7YKhrhg4H45iFIwOE4x4YoDoHLCumpKIGT/9+fD0pVFH
hzuc3m5t7DSsCG4rl1UD3uJChlOy9FXNbyvIqyAjSFyumlgPTGhuGRS6cg2E
9gpMQYM5835GaJYWlkvQTATMHRqX1gYJvcQn6sAOe/FbCdOpna0M2cL0XriJ
sX5ny6eFt/RD+dQk6STlhBxKxkwbyttcZRN+TMpRirxsgRjAWO4gyXzDMyG3
yi3CFzIP7GmEicvgW41pIZOYsrGXEsVSKolUJ6t0LxneXVoYn3cSGFE2phDf
0R1Koki5sCifA1Yyw/0LbGBHUhfDLrmDNWpP1fv38Dum+T5KYooqllqPVD9p
XjBwvnoJlTjTlH9vivegVOOk19ntBNPmjCacbRnzcMdDyWJHRDWSVEszHQEj
9Je0uCvge0m6i/lgbq/Ui+KcuYWeIN5bUiVKnnIivrjgLWPHnSH7kHEJE34d
XMI+YaP8hCfYUhyOPogMp4qjeVLzFyePjgBr+J+PH5n5YaJNXlG7csZ/6VDd
sZlrKdGGl2ZGSI4qXbWLLAFKSosWIcilN4ixgkA6SkpEzAWw6FusPCvR6ViN
kRKH8hTm2QWWk10UlNBG1cLgEtrbxf9h+a8Ib7s1Q2WQ5+mwHCozLErYE+WD
GPOSxiAQm8wUOfic8u7Dwg0xlQoNjeWQZpho1VbQCxMjUoi9zeuPWQJ474RS
nbIEYTOEFVOjUUMSMVTilNJgPg2SrWBupJBiJPM3VjZctmyJgRKJTRYRol+T
iDTM/3BEpJ0Cs6ZyUvkMOiV+URSUD+WY9I0wT5jUfoucyEZ2NA+qH7qRKIOh
hbFDScOB1+RRAAtPmpLu23VNs7QNPGwx4uzCO5iGMwBgFk+mzBjiSeqVGhKY
WQ5KXIAJpEE3lsuiuaA0EUGJtrB8MNMeFywwYcqYjJKvY2IbYh32myZpDC1i
onmKvwEGSknagUCOMdlyUAXWfuz4hk3PVgSo6UhBOiUldWxRA41544YwHZsi
Lio3sxXqaCauYiN+zFRdrrkFShxxXlFt6UsZCEtBYXraVlgh+mKaVarQBWsD
zIpVCIyQi1l1PayFzlWyxW1Dmpql98psfPpcQ03LXE3KTpd5n6wsqbRSzRj1
Jl+ZkAoFUzZjya+CO+s0IAIunyf0CEwQFnam/zIH1MFBY1QdD7M7u3KG2MU5
rF05T395UpRbHHNwVzYDr0JKRbmtylZHo82yRi5fwJOZ0bBgZsciF/mgK4Ax
jXJM8It96uE0zaDXOBB4JwBCok6f/IqKB2gBL/nMQ5VTK4qAPSdpd5aihCwi
giOznM3Q8WnYpmLJ2QRU76lkUS+pC2EOV3qLOi5e+uRUK4xZ+KKIKe+Y75XS
UbpShKoZ1pVgcKAF7LrTGGEvfdcIvkPOM8PJjyMj575UMl5WhmiVy8KUS5rA
Sicx2afmAcbMImYVAyn3n4t4+I6qDXIqrWrmrGiYZ8bLv456jW5eroCLkyPM
+jRsg4w4WZzDIoMaoMdjlG04FB1qXa0EUTR9fp7vsDqunCoN0WDpSItVDbE2
LeVoHBaY+j5SYzh8+LMo4w1zm6d9Fe/UKbSmptBMC7caZbKlTNhwTvwdJWGM
Kjk+4AQwqLdiDcQYOj6TfYkEHxuvULbpLCJZq42kr8kxSaU9gWCSbHFj4xEG
cMyg7KntNqnTjf8HWxRzWhPeAAA=

-->

</rfc>
