<?xml version="1.0" encoding="US-ASCII"?>
<!-- This template is for creating an Internet Draft using xml2rfc,
     which is available here: http://xml2rfc.tools.ietf.org. -->
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
     There has to be one entity for each item to be referenced. 
     An alternate method (rfc include) is described in the references. -->

<!ENTITY RFC2119 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2629 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2629.xml">
<!ENTITY RFC3552 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.3552.xml">
<!ENTITY I-D.narten-iana-considerations-rfc2434bis SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml3/reference.I-D.narten-iana-considerations-rfc2434bis.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<!-- used by XSLT processors -->
<!-- For a complete list and description of processing instructions (PIs), 
     please see http://xml2rfc.tools.ietf.org/authoring/README.html. -->
<!-- Below are generally applicable Processing Instructions (PIs) that most I-Ds might want to use.
     (Here they are set differently than their defaults in xml2rfc v1.32) -->
<?rfc strict="yes" ?>
<!-- give errors regarding ID-nits and DTD validation -->
<!-- control the table of contents (ToC) -->
<?rfc toc="yes"?>
<!-- generate a ToC -->
<?rfc tocdepth="4"?>
<!-- the number of levels of subsections in ToC. default: 3 -->
<!-- control references -->
<?rfc symrefs="yes"?>
<!-- use symbolic references tags, i.e, [RFC2119] instead of [1] -->
<?rfc sortrefs="yes" ?>
<!-- sort the reference entries alphabetically -->
<!-- control vertical white space 
     (using these PIs as follows is recommended by the RFC Editor) -->
<?rfc compact="yes" ?>
<!-- do not start each main section on a new page -->
<?rfc subcompact="no" ?>
<!-- keep one blank line between list items -->
<!-- end of list of popular I-D processing instructions -->
<rfc category="info" docName="draft-belchior-gateway-recovery-01" ipr="trust200902">
  <!-- category values: std, bcp, info, exp, and historic
     ipr values: full3667, noModification3667, noDerivatives3667
     you can add the attributes updates="NNNN" and obsoletes="NNNN" 
     they will automatically be output with "(if approved)" -->

  <!-- ***** FRONT MATTER ***** -->

  <front>
    <!-- The abbreviated title is used in the page header - it is only necessary if the 
         full title is longer than 39 characters -->


    <title abbrev="Gateway Crash Recovery">DLT Gateway Crash Recovery Mechanism</title>

    <author fullname="Rafael Belchior" initials="R" surname="Belchior">
      <organization>INESC-ID, Instituto Superior T&eacute;cnico</organization>
      <address>
        <email>rafael.belchior@tecnico.ulisboa.pt</email>
      </address>
    </author>

    <author fullname="Miguel Correia" initials="M" surname="Correia">
      <organization>INESC-ID, Instituto Superior T&eacute;cnico</organization>
      <address>
        <email>miguel.p.correia@tecnico.ulisboa.pt</email>
      </address>
    </author>


    <author fullname="Thomas Hardjono" initials="T" surname="Hardjono">
      <organization>MIT</organization>
      <address>
        <email>hardjono@mit.edu</email>
      </address>
    </author>



    <date day="10" month="March" year="2021"/>

    <!-- If the month and year are both specified and are the current ones, xml2rfc will fill 
         in the current day for you. If only the current year is specified, xml2rfc will fill 
	 in the current day and month for you. If the year is not the current one, it is 
	 necessary to specify at least a month (xml2rfc assumes day="1" if not specified for the 
	 purpose of calculating the expiry date).  With drafts it is normally sufficient to 
	 specify just the year. -->

    <!-- Meta-data Declarations -->

    <area>General</area>

    <workgroup>Internet Engineering Task Force</workgroup>

    <!-- WG name at the upperleft corner of the doc,
         IETF is fine for individual submissions.  
	 If this element is not present, the default is "Network Working Group",
         which is used by the RFC Editor as a nod to the history of the IETF. -->

    <keyword>template</keyword>

    <!-- Keywords will be incorporated into HTML output
         files in a meta tag but they have no effect on text or nroff
         output. If you submit your draft to the RFC Editor, the
         keywords will be used for the search engine. -->

    <abstract>
      <t>This memo describes the crash recovery mechanism for the Open Digital Asset Protocol (ODAP), entitled ODAP-2PC. ODAP-2PC assures that gateways running ODAP are crash-fault tolerant, meaning that the atomicity of asset transfers are assured even if gateways crash. This protocol includes the description of the messaging and logging flow necessary for gateways to keep track of current state, the crash recovery protocol, and a rollback protocol. </t>
    </abstract>
  </front>


  <middle>


   <section anchor="introduction" title="Introduction">
 <t>
	 Gateway systems that perform virtual asset transfers among DLTs must possess a degree of resiliency and fault tolerance in the face of possible crashes. A key component of crash recovery is maintaining logs that enable either the same or other backup gateways to resume partially completed transfers. Another key component is an atomic commit protocol (ACP) that guarantees that the source and target DLTs are modified consistently (atomicity) and permanently (durability), e.g., that assets that are taken from the source DLT are persisted into the recipient DLT. 
 </t>
     
      <t>
      This memo proposes: (i) the parameters that a gateway must retain in the form of logs concerning message flows within asset transfers; (ii) a JSON-based format for logs related to asset transfers.
      </t>

     </section>

          
   <section anchor="terms" title="Terminology">

      <t>There following are some terminology used in the current document:
      <list style="symbols">

      <t>Gateway: The nodes of a DLT system that are functionally capable of handling an asset transfer with another DLT. Gateway nodes implement the gateway-to-gateway asset transfer protocol.
 	</t>

<t>
Primary Gateway: The node of a DLT system that has been selected or elected to act as a gateway in an asset transfer.
 </t>
 
<t>
Backup Gateway: The node of a DLT system that has been selected or elected to act as a backup gateway to a primary gateway.
 </t>

<t>
Message Flow Parameters: The parameters and payload employed in a message flow between a sending gateway and receiving gateway.
</t>

<t>
Source Gateway (or G1): The gateway that initiates the transfer protocol. Acts as a coordinator of the ACP and mediates the message flow.
</t>

<t>
Recipient Gateway (or G2): The gateway that is the target of an asset transfer. It follows instructions from the source gateway.  
</t>

<t>
Source DLT: The DLT of the source gateway.
</t>

<t>
Target DLT: The DLT of the recipient gateway.
</t>


<t>
Log: Set of log entries such that those are ordered by the time of its creation.
</t>

<t>
Public (or Shared) Log: log where several nodes can read and write from it.
</t>

<t>
Private Log: log where only one node can read and write from it.
</t>

<t>
Log data: The log information is retained by a gateway connected to an exchanged message within an asset transfer protocol. 
</t>

<t>
Log entry: The log information generated and persisted by a gateway regarding one specific message flow step.
</t>
 
<t>
Log format: The format of log-data generated by a gateway.
</t>


<t>
Atomic commit protocol (ACP): A protocol that guarantees that assets that are taken from a DLT are persisted into the other DLT. Examples are two and three-phase commit protocols (2PC, 3PC, respectively) and non-blocking atomic commit protocols.
</t>


<t>
Fault: A fault is an event that alters the expected behavior of a system.

</t>

<t>
Crash-fault tolerant models: models allowing a system to keep operating correctly despite having a set of faulty components. 
</t>


<t>
Digital asset: a form of digital medium recordation that is used as a digital representation of a tangible or intangible asset.
</t>

		
        </list></t>
     </section>



<section anchor="lm" title="Logging Model">

<t>
Logs are associated to a process running operations on a certain gateway, and they can be stored in several supports: 1) off-chain storage (with the possibility of a hash of the logs being stored on-chain), where logs are stored on the hard-drive of the computer system performing the role of a gateway; 2) cloud storage; 3) on-chain storage, either storing the logs on the blockchains that gateways are connected, or to a third blockchain.
</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, later presented:


<list style="symbols">
		<t>
		 writeLogEntry(l,L) - writes a log entry l in the log L
		</t>
		
		<t>
		getLogLength - obtains the number of log entries
		</t>
		
		<t>
		getLogEntry(l) - retrieves a log entry l.

		</t>

		</list></t>

<t>
A log entry request typically comes from a single event in a given protocol. Log entry requests have the format (phase, step, operation, gateways), where the field operation corresponds to an arbitrary command, and the field gateways correspond to the parties involved in the protocol. We define four operations types to provide context to the protocol being executed. Operation type (init-) states the intention of a gateway to execute a particular operation, and operation (exec-) expresses that the gateway is excecuting an operation. The operation type (done-) states when an  agent successfully executed a step of the protocol, while (ack-) refers to when a gateway acknowledges a message received from another. Conversely, we use the type (fail-) to refer to when an agent fails to execute a specific step. 
</t>

<section anchor="exlm" title="Example">





		<figure align="center" anchor="gateway-phases">


		<artwork><![CDATA[                                         
        

     ,--.                          ,--.                            ,-------.
     |G1|                          |G2|                            |Log API|
     `--'                          `--'                            `-------'
      |                [1]: writeLogEntry init-validate                |    
      | --------------------------------------------------------------->    
      |                             |                                  |    
      | [2]: initiate ODAP's phase 1|                                  |    
      | ---------------------------->                                  |    
      |                             |                                  |    
      |                             | [3]: writeLogEntry exec-validate |    
      |                             | --------------------------------->    
      |                             |                                  |    
      |                             |----.                                  
      |                             |    | [4]: execute validate from p1    
      |                             |<---'                                  
      |                             |                                  |    
      |                             | [5]: writeLogEntry done-validate |    
      |                             | --------------------------------->    
      |                             |                                  |    
      |                             |  [6]: writeLogEntry ack-validate |    
      |                             | --------------------------------->    
      |                             |                                  |    
      |   [7]: validation complete  |                                  |    
      | <----------------------------                                  |    
     ,--.                          ,--.                            ,-------.
     |G1|                          |G2|                            |Log API|
     `--'                          `--'                            `-------'


		]]></artwork>
      	</figure>

<t>
From step 1 to 7, the generated logs are:


		
		<list style="decimal">
		<t>
		At step 1, LOG: &lt;p1, 1, init-validate, (GS-&gt;GR)&gt;.
		</t>
		
		<t>
		At step 2, GS commands GR to execute validate.
		</t>

		<t>
		At step 3, LOG: &lt;p1, 2, exec-validate, (GR)&gt;.
		</t>

		<t>
		At step 4: GR executes validate
		</t>

		<t>
		At step 5, LOG: &lt;p1,3, done-validate, (GR)&gt;.
		</t>
		
		<t>
		At step 6, LOG: &lt;p1, 4, ack-validate, (GR-&gt;GS)&gt;.
		</t>

		<t>
		At step 7: GS receives an acknoledgment from GR.
		</t>
		


				
		</list>	</t>

			

	</section>

</section>


   <section anchor="gcr" title="Gateway Crash Recovery">

<t>
      The gateway architecture [ODAP] defines two gateway nodes belonging to distinct DLT systems as a means to conduct a virtual asset transfer in a secure and non-repudiable manner while ensuring the asset does not exist simultaneously on both blockchains.
</t>

<t>
One of the key deployment requirements of gateways for asset transfers is a high degree of gateways availability. In this document, we consider two common strategies to increase availability: (1) to support the recovery of the gateways and (2) to employ backup gateways with the ability to resume a stalled transfer. 
</t>
 
<t>
To this end, gateways must retain relevant log information regarding incoming protocol messages (parameters, payloads, etc.) and transmitted messages. In particular, logs are written before operations (write-ahead) to provide atomicity and durability to the asset exchange protocol. The log-data is considered as internal resources to the DLT system, accessible to the backup gateway and possible other gateway nodes.
</t>


		<section anchor="gtm" title="Gateway Transfer Model">

			<t>
					The Open Digital Asset Protocol (ODAP) is a DLT-agnostic gateway-to-gateway protocol used by a sender gateway and a target gateway to perform a virtual asset's unidirectional transfer [ODAP]. The transfer process is started by a client (application) that interacts with the source gateway or both (source and recipient) gateways to provide instructions regarding actions, related resources located in the source DLT system, and resources located in the remote DLT system. The protocol has two modes, but here we consider only the Relay Mode: Client-initiated Gateway to Gateway asset transfer. When we refer to the ODAP protocol in this document, we refer to the ODAP protocol in Relay Mode, although the logging model specified in this memo can also support the Direct mode., although the logging model specified in this memo can also support the Direct mode.
			</t>
			
			<t>
			ODAP has to be instanced with an ACP protocol to guarantee that the source and target DLTs are modified consistently, a property designated Atomicity [BHG87]. ACPs consider two roles: a Coordinator that manages the execution of the protocol and Participants that manage the resources that must be kept consistent. The source gateway plays the ACP role of Coordinator, and the recipient gateway plays the Participant role in relay mode. Gateways exchange messages corresponding to the protocol execution, generating log entries for each one. The message exchange, and corresponding logging procedure is represented in Figure 1.
			</t>

<t>
The simplified message flow format is in the form &lt; ODAP_PHASE, STEP, COMMAND, GATEWAY &gt;, where ODAP_PHASE corresponds to the current phase of ODAP, STEP corresponds to a monotonically increasing integer, COMMAND to the command type being issued by a set of gateways (GATEWAY). However, both two-phase commit and three-phase commit can block in case nodes fail.  The protocol being blocking means that if the coordinator crashes, then gateways may not finish transactions. When a crash happens, gateways will be waiting for a confirmation/abort, and possibly holding the lock regarding a specific digital asset.
</t>
			

	
	</section>


		<section anchor="crm" title="Crash Recovery Model">

		<t>
		We assume gateways fail by crashing, i.e., by becoming silent, not arbitrary or Byzantine faults. We assume authenticated reliable channels obtained using TLS/HTTPS [TLS]. To recover from these crashes, gateways store in persistent storage data about the step of their protocol. This allows the system to recover by getting from the log the first step that may have failed. We consider two recovery models:
	
		
		
		<list style="symbols">
		<t>
		Self-healing mode: assumes that after a crash, a gateway eventually recovers; 
		</t>
		
		<t>
		Primary-backup mode: assumes that after a crash, a gateway may never recover, but that this failure can be detected by timeout [AD76].
		</t>
		</list>	</t>
		
		
		<t>
		In Self-healing mode, when a gateway restarts after a crash, it reads the state from the log and continues executing the protocol from that point on.  We assume the gateway does not lose its long-term keys (public-private key pair) and can reestablish all TLS connections. 
		</t>
		
		<t>
		In Primary-backup mode, we assume that after a period T of the primary gateway failure, 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 value for T. The backup gateway does virtually the same as the gateway in self-healing mode: reads the log and continues the process. The difference is that the log must be shared between the primary and the backup gateways. If there is more than one backup, a leader-election protocol may be executed to decide which backup will take the primary role.
		</t>
			

		
		 </section>

		 
		<section anchor="rp" title="Recovery Procedure">


		<t>
		Gateways can crash at several points of the protocol.
		</t>

		<t>
In 2PC and 3PC, recovery requires that the protocol steps are recorded in a log immediately before sending a message and immediately after receiving a message. Thus, at every step k of the protocol, each gateway writes in the log entry indicating its current state. When a node crashes: 
		
		
		<list style="symbols">
		<t>
		Self-healing mode: the recovered gateway informs the other party of its recovery and continues the protocol execution;

		</t>
		
		<t>
		Primary-backup mode: if a node is crashed indefinitely, a backup is spun off, using the log storage API to retrieve the most recent version of the log. 
		</t>
		</list></t>
		
		
		<t>
		Upon recovery, the recovered node attempts to retrieve the most recent log of operations. Based on the latest log entry last(log), it derives the current state of the asset transfer. This can be confirmed by querying all other nodes involved in such transfer by sending a recovery message rm. After the current state is fetched and agreed upon by all parties, the ODAP protocol continues. There are several situations when a crash may occur. The first one is immediately after starting the transfer, as shown below:
		</t>



		<figure align="center" anchor="gateway-phases-crash-1">


		<artwork><![CDATA[                                         
     ,--.                        ,--.                     ,-------.
     |G1|                        |G2|                     |Log API|
     `--'                        `--'                     `-------'
      | 1: [1]: writeLogEntry <p1, 1, init-validate, (GS->GR)>|    
      | ------------------------------------------------------>    
      |                           |                           |    
      |----.                      |                           |    
      |    | [2]  Crash           |                           |    
      |<---'  ...                 |                           |    
      |      [3]recover           |                           |    
      |                           |                           |    
      |                           |                           |    
      |  [4] <p1, 1, RECOVER, GR> |                           |    
      | -------------------------->                           |    
      |                           |                           |    
      |                           |     [5] getLogEntry(i)    |    
      |                           | -------------------------->    
      |                           |                           |    
      |                           |       [6] logEntries      |    
      |                           | <- - - - - - - - - - - - -     
      |                           |                           |    
      |  [7] send updated log ul  |                           |    
      | <--------------------------                           |    
      |                           |                           |    
      |----.                      |                           |    
      |    | [8] process log      |                           |    
      |<---'                      |                           |    
      |                           |                           |    
      |                   [9] updateLog(ul)                   |    
      | ------------------------------------------------------>    
      |                           |                           |    
      |   [10] confirm recovery   |                           |    
      | -------------------------->                           |    
      |                           |                           |    
      | [11]  acknowledge recovery|                           |    
      | <- - - - - - - - - - - - -                            |    
      |                           |                           |    
      |        [12]: <p1,2,init-validateNext, (GS->GR)>       |    
      | ------------------------------------------------------>    
     ,--.                        ,--.                     ,-------.
     |G1|                        |G2|                     |Log API|
     `--'                        `--'                     `-------'

		]]></artwork>
      	</figure>


<t>			
The source gateway (G1) crashes right before it issued an init command to the recipient gateway (G2). The gateway eventually recovers in self-healing mode, querying the last log entry from the log  storage API. After that, it sends a recovery message to G2, advertising that the    recovery has been completed and asking for an updated version of the    log, i.e., the current state.  In this case, the latest version of   the log corresponds to G1 log.  After synchronization has been achieved, the process can continue.
</t>

<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>

		<figure align="center" anchor="gateway-phases-crash-2">


		<artwork><![CDATA[                                         
     ,--.                          ,--.                        ,-------.
     |G1|                          |G2|                        |Log API|
     `--'                          `--'                        `-------'
      |             1: [1]: writeLogEntry init-validate            |    
      | ----------------------------------------------------------->    
      |                             |                              |    
      | [2]: initiate ODAP's phase 1|                              |    
      | ---------------------------->                              |    
      |                             |                              |    
      |----.                        |                              |    
      |    | [3] Crash              |                              |    
      |<---'                        |                              |    
      |                             |                              |    
      |                             |    [4]: writeLogEntry init   |    
      |                             | ----------------------------->    
      |                             |                              |    
      |                             |----.                              
      |                             |    | [5]: execute init from p1    
      |                             |<---'                              
      |                             |                              |    
      |                             | [6]: writeLogEntry done-init |    
      |                             | ----------------------------->    
      |                             |                              |    
      |                             |  [7]: writeLogEntry ack-init |    
      |                             | ----------------------------->    
      |                             |                              |    
      |   [8] <p1, 1, RECOVER, GR>  |                              |    
      | ---------------------------->                              |    
      |                             |                              |    
      |                             |      [9] getLogEntry(i)      |    
      |                             | ----------------------------->    
      |                             |                              |    
      |                             |        [10] logEntries       |    
      |                             | <- - - - - - - - - - - - - - -    
      |                             |                              |    
      |   [11] send updated log ul  |                              |    
      | <----------------------------                              |    
      |                             |                              |    
      |----.                        |                              |    
      |    | [12] process log       |                              |    
      |<---'                        |                              |    
      |                             |                              |    
      |                     [13] updateLog(ul)                     |    
      | ----------------------------------------------------------->    
      |                             |                              |    
      |    [14] confirm recovery    |                              |    
      | ---------------------------->                              |    
      |                             |                              |    
      |  [15] acknowledge recovery  |                              |    
      | <- - - - - - - - - - - - - -                               |    
      |                             |                              |    
      |                   [16]: init-validateNext                  |    
      | ----------------------------------------------------------->    
     ,--.                          ,--.                        ,-------.
     |G1|                          |G2|                        |Log API|
     `--'                          `--'                        `-------'

	
	]]></artwork>
      	</figure>
      	
      	
      	</section>
		 	     

		<section anchor="ls" title="Log Storage">

		<t>
		Log primitives are translated into log entries, persisted by the log storage API in the format &lt;operation, step, phase, gateways&gt;, where the gateway issuing the operation is implicit. For example, when GS initiates ODAP&apos;s first phase, by sending a message to GR, a log entry specifying the command init given to G2, in the first operation of the phase p1 is translated to a log entry &lt;p1,1,init-validate,GS-GR)&gt;. After that, the log entry is persisted via the log storage API. Thus, log primitives are also translated into log storage API requests. 
		</t>

		<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). Logs can be saved locally (computer?s disk), in an external service (e.g., cloud storage service), or in the DLT the gateway is operating. Saving logs locally is faster than saving them on the respective ledger but delivers weaker integrity and availability guarantees. Saving log entries on a DLT may slow down the protocol because issuing a transaction is several orders of magnitude slower than writing on disk or accessing a cloud service. Self-healing mode is compatible with the three types of logs, but Primary-backup mode requires storage in an external service or the DLT. For critical scenarios where strong accountability and traceability are needed (e.g., financial institution gateways), blockchain-based logging storage may be appropriate. Conversely, for gateways that implement interoperability between blockchains belonging to the same organization (i.e., a legal framework protects the legal entities involved), local storage might suffice.
		</t>

		<t>
		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 [OIDC], and use secure channels based on TLS/HTTPS [TLS].
		</t>
		<t>
		We consider a log storage API that allows developers to abstract from the storage details (e.g., relational vs. non-relational, local vs. cloud) and handles access control if needed.  This is API-TYPE 1, as the gateway uses it to store off-chain resources.
		</t>

		
		 </section>

		 <section anchor="logapi" title ="Logging API">
			<t> The log storage API serves two purposes: 1) it provides a reliable mean to store logs created by all gateways involved in an asset transfer; and 2) promote accountability across parties.</t>
			<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 further operation in future
			   to determine the ultimate status of the operation.
			</t>
			
			<section anchor="logapi-1" title ="POST/saveLogEntry:log">

				<t> Persists a log entry at the default storage environment, by appending it to the current log. Returns the index of the saved log entry.
				</t>


				<t> Response example: </t>
				
				<figure align="center" anchor="logapi-1-response">				

				<artwork><![CDATA[                                         
				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"
				   }
		
				]]></artwork>
		      	</figure>
      	

			</section>



			<section anchor="logapi-2" title ="GET lastEntry">

				<t> Obtains the latest log entry from the log.</t>


				<t> Response example: </t>
				
				<figure align="center" anchor="logapi-2-response">				

				<artwork><![CDATA[                                         
				 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":
				            "log_entry": {...}
				}
		
				]]></artwork>
		      	</figure>
      	

			</section>

			<section anchor="logapi-3" title ="GET getLogEntry/:id">

				<t> Obtains a log entry with specified ID. </t>


				<t> Response example: </t>
				
				<figure align="center" anchor="logapi-3-response">				

				<artwork><![CDATA[                                         
				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":
				            "log_entry": {...}
				}

				]]></artwork>
		      	</figure>
      	

			</section>

			<section anchor="logapi-4" title ="GET getLog">

				<t> Obtains the whole log. </t>


				<t> Response example: </t>
				
				<figure align="center" anchor="logapi-4-response">				

				<artwork><![CDATA[      
				 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":
				            "log": {...}
				}

				]]></artwork>
		      	</figure>
      	

			</section>

			
			<section anchor="logapi-5" title ="POST updateLog">

				<t> Updates the current log. The log is updated if there are new log entries.  </t>
				<t> Returns the index of the last common log entry (common prefix). </t>
			
				<t> Response example: </t>
				
				<figure align="center" anchor="logapi-5-response">				

				<artwork><![CDATA[      
				  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"
				   }


				]]></artwork>
		      	</figure>
      	

			</section>
			
		 </section>

		 	     
     </section>


   <section anchor="format" title=" Format of log entries">

<t>

The log entries are stored by a gateway in its log. Entries account for the current status of one of the three ODAP flows: Transfer Initiation flow, Lock-Evidence flow, and Commitment Establishment flow. 

The recommended format for log entries is JSON [xxx], with protocol-specific mandatory fields,  support for a free format field for plaintext or encrypted payloads directed at the DLT gateway or an underlying DLT. Although the recommended format is JSON, other formats can be used (e.g., XML). 
</t>

<t>

The mandatory fields of a log entry are:

<list style="symbols">

      <t>
      session_ID REQUIRED: unique identifier (UUIDv2) representing an ODAP interaction (corresponding to a particular flow)
      </t>

<t>
seq_number REQUIRED: represents the ordering of steps recorded on the log for a particular session
 </t>
 
<t>
odap_phase REQUIRED: flow to which the logging refers to. Can be Transfer Initiation flow, Lock-Evidence flow, and Commitment Establishment flow.
 </t>

<t>
source_gateway_pubkey REQUIRED: the public key of the gateway initiating a transfer

</t>

<t>
source_gateway_dlt_system REQUIRED: the ID  of the gateway initiating a transfer

</t>

<t>
recipient_gateway_pubkey REQUIRED: the public key of the gateway involved in a transfer

</t>

<t>
recipient_gateway_dlt_system REQUIRED: the ID of the recipient gateway involved in a transfer

</t>

<t>
timestamp REQUIRED: timestamp referring to when the log entry was generated (UNIX format)

</t>

<t>
payload REQUIRED: Message payload. Contains subfields Votes (optional), Msg, Message type. Votes refers to the votes parties need to commit in the 2PC. Msg is the content of the log entry. Message type refers to the different logging actions (e.g., command, backup). Msg and Message type are specific to the ODAP phase  [ODAP].

</t>

<t>
payload_hash REQUIRED: hash of the current message payload
	</t>	
        </list>
</t>

<t>
Optional log entry fields are:
     <list style="symbols">

      <t>
      logging_profile: contains the profile regarding the logging procedure. If not present, a local store for the logs is assumed.
      </t>

<t>
source_gateway_uid: the uid of the source gateway involved in a transfer

 </t>
 
<t>
recipient_gateway_uid : the uid of the recipient gateway involved in a transfer

 </t>

<t>
message_signature: Gateway EDCSA signature over the log entry


</t>

<t>
last_entry_hash: Hash of previous log entry


</t>

<t>
access_control_profile: the profile regarding the confidentiality of the log entries being stored
</t>

        </list></t>

<t>
Example of a log entry created by G1, corresponding to locking an asset (phase 2.3 of the ODAP protocol) :
</t>


		<figure align="center" anchor="log-format-1">


		<artwork><![CDATA[                                         
{
    "sessionId": "4eb424c8-aead-4e9e-a321-a160ac3909ac",
    "seqNumber": 6,
    "phaseId": "lock",
    "sourceGatewayId": "5.47.165.186",
    "sourceDltId": "Hyperledger-Fabric-JusticeChain",
    "targetGatewayId": "192.47.113.116",
    "targetDltId": "Ethereum",
    "timestamp": "1606157330",
    "payload": {
        "messageType": "2pc-log",
        "message": "LOCK_ASSET",
        "votes": "none"
 },
 "payloadHash": "80BCF1C7421E98B097264D1C6F1A514576D6C9F4EF04955FA3AEF1C0664B34E3",
"logEntryHash": "[...]"
}


		]]></artwork>
      	</figure>
      	

<t>
Example of a log entry created by G2, acknowledging G1 locking an asset (phase 2.4 of the ODAP protocol) :
</t>

		<figure align="center" anchor="log-format-2">


		<artwork><![CDATA[                                         
{
    "sessionId": "4eb424c8-aead-4e9e-a321-a160ac3909ac",
    "seqNumber": 7,
    "phaseId": "lock",
    "sourceGatewayId": "5.47.165.186",
    "sourceDltId": "Hyperledger-Fabric-JusticeChain",
    "targetGatewayId": "192.47.113.116",
    "targetDltId": "Ethereum",
    "timestamp": "1606157333",
    "payload": {
        "messageType": "2pc-log",
        "message": "LOCK_ASSET_ACK",
        "votes": "none"
    }
    ,
    "payloadHash": "84DA7C54F12CE74680778C22DAE37AEBD60461F76D381D3CD855B0713BB98D1",
"logEntryHash": "[...]"
}


		]]></artwork>
      	</figure>
      	

     </section>


	
	<section anchor="s" title="Security Considerations">
	
<t>
We assume a trusted, secure communication channel between gateways (i.e., messages cannot be spoofed and/or altered by an adversary) using TLS 1.3 or higher. Clients support ?acceptable? credential schemes such as OAuth2.0.
</t>
<t>
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 [BVC19]. 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 DLT-based). 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. blockchain-based access control in a DLT).
</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 [CD16].
</t>

		</section>	

    <!-- This PI places the pagebreak correctly (before the section title) in the text output. -->

    <?rfc needLines="8" ?>


  </middle>




  <!--  *****BACK MATTER ***** -->

  <back>
    <!-- References split into informative and normative -->

    <!-- There are 2 ways to insert reference entries from the citation libraries:
     1. define an ENTITY at the top, and use "ampersand character"RFC2629; here (as shown)
     2. simply use a PI "less than character"?rfc include="reference.RFC.2119.xml"?> here
        (for I-Ds: include="reference.I-D.narten-iana-considerations-rfc2434bis.xml")

     Both are cited textually in the same manner: by using xref elements.
     If you use the PI option, xml2rfc will, by default, try to find included files in the same
     directory as the including file. You can also define the XML_LIBRARY environment variable
     with a value containing a set of directories to search.  These can be either in the local
     filing system or remote ones accessed by http (http://domain/dir/... ).-->


	<references title="Normative References">
      <!--?rfc include="http://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"?-->
      &RFC2119;

		<reference anchor="ODAP" target="https://datatracker.ietf.org/doc/draft-hargreaves-odap/">
		<front>
			<title>Open Digital Asset Protocol, October 2020, IETF, draft-hargreaves-odap-00.</title>
			<author initials="M." surname="Hargreaves">		</author>
			<author initials="T." surname="Hardjono">		</author>
			<date day="" month="October" year="2020"/>
		</front>
		</reference>

		<reference anchor="TLS" target="https://tools.ietf.org/rfc/rfc8446">
		<front>
			<title>The Transport Layer Security (TLS) Protocol Version 1.3?, RFC 8446.</title>
			<author initials="E." surname="Rescorla">		</author>
			<date day="" month="" year="2018"/>
		</front>
		</reference>




	</references>

	



	<references title="Informative References">

    
		<reference anchor="Clar88">
		<front>
			<title>The Design Philosophy of the DARPA Internet Protocols, ACM Computer Communication Review, Proc SIGCOMM 88, vol. 18, no. 4, pp. 106-114</title>
			<author initials="D." surname="Clark">
			</author>
			<date day="" month="August" year="1988"/>
		</front>
		</reference>


		<reference anchor="SRC84">
		<front>
			<title>End-to-End Arguments in System Design, ACM Transactions on Computer Systems, vol. 2, no. 4, pp. 277-288</title>
			<author initials="J." surname="Saltzer">		</author>
			<author initials="D." surname="Reed">			</author>
			<author initials="D." surname="Clark">			</author>
			<date day="" month="November" year="1984"/>
		</front>
		</reference>

	<reference anchor="HS2019" target="https://doi.org/10.3389/fbloc.2019.00024">
		<front>
			<title>Decentralized Trusted Computing Base for Blockchain Infrastructure Security, Frontiers Journal, Special Issue on Blockchain Technology, Vol. 2, No. 24</title>
			<author initials="T." surname="Hardjono">		</author>
			<author initials="N." surname="Smith">			</author>
			<date day="" month="December" year="2019"/>
		</front>
		</reference>


	<reference anchor="BHG87" target="https://doi.org/10.3389/fbloc.2019.00024">
		<front>
			<title>Concurrency Control and Recovery in Database Systems, Chapter 7. Addison Wesley Publishing Company</title>
			<author initials="P." surname="Bernstein">		</author>
			<author initials="V." surname="Hadzilacos">			</author>
						<author initials="N." surname="Goodman">			</author>
			<date day="" month="" year="1987"/>
		</front>
		</reference>


	
	<reference anchor="AD76" target="978-0-201-10715-9">
		<front>
			<title>A principle for resilient sharing of distributed resources. In Proc. of the 2nd Int. Conf. on Software Engineering</title>
			<author initials="P." surname="Alsberg">		</author>
			<author initials="D." surname="Day">			</author>
			<date day="" month="" year="1976"/>
		</front>
		</reference>	
	
	<reference anchor="BVC19" target="https://aisel.aisnet.org/ecis2020_rp/68/">
		<front>
			<title>Towards Secure, Decentralized, and Automatic Audits with Blockchain. European Conference on Information Systems</title>
			<author initials="R." surname="Belchior">		</author>
			<author initials="A." surname="Vasconcelos">			</author>
			<author initials="M." surname="Correia">			</author>
			<date day="" month="" year="2019"/>
		</front>
		</reference>	

		
	<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">		</author>
			<author initials="J." surname="Bradley">			</author>
			<author initials="M." surname="Jones">			</author>
			<author initials="B." surname="de Medeiros">			</author>
			<author initials="C." surname="Mortimore">			</author>
			<date day="" month="" year="2014"/>
		</front>
		</reference>	


	</references>


    <!-- Change Log

v00 2006-03-15  EBD   Initial version

v01 2006-04-03  EBD   Moved PI location back to position 1 -
                      v3.1 of XMLmind is better with them at this location.
v02 2007-03-07  AH    removed extraneous nested_list attribute,
                      other minor corrections
v03 2007-03-09  EBD   Added comments on null IANA sections and fixed heading capitalization.
                      Modified comments around figure to reflect non-implementation of
                      figure indent control.  Put in reference using anchor="DOMINATION".
                      Fixed up the date specification comments to reflect current truth.
v04 2007-03-09 AH     Major changes: shortened discussion of PIs,
                      added discussion of rfc include.
v05 2007-03-10 EBD    Added preamble to C program example to tell about ABNF and alternative 
                      images. Removed meta-characters from comments (causes problems).  -->
  </back>
</rfc>
