<?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.18 (Ruby 3.3.3) -->
<?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-02" category="info" consensus="true" submissionType="IETF" tocDepth="4" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.22.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-02"/>
    <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="2024" month="July" day="22"/>
    <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. 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>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",
    "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>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>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>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>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>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) Calls to the log API do not fail.</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>
            <date day="5" month="April" year="2024"/>
            <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.  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-04"/>
        </reference>
      </references>
    </references>
  </back>
  <!-- ##markdown-source:
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
AKalHRLz8SKZdjod0o8b/w/U24P8uNoAAA==

-->

</rfc>
