Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This Execution Service is designed to support the Execution Plan Addition to the FinP2P Protocol. It adds another layer to the ability of financial institution wanting to trade digital securities with other parties using different underlying DLT solutions (or other cryptographic technologies), thereby contributing to the vision of FinP2P to maximize access to assets, distribution and liquidity across a global financial market using an agnostic interoperability protocol.

Motivation:

As the FinP2P protocol continues to develop, we are adding another mechanism for multi-party, interoperable, highly scalable, transaction orchestration to enable an open environment for developers to build more complex use cases on top of the FinP2P interoperability protocol. This includes more nuanced DVP solutions, custody as a service, various payment solutions including FIAT, Hash Time Lock Contracts (HTLC), multi-DvP use cases (such as Repo), various lending and leverage models, and much more.

...

Finally, the distributed structure of the Execution Plan allows a clear assignment of ownership, determining which party is responsible for executing each step in the plan, as agreed by all parties. This is very useful in building a scalable legal infrastructure for interoperable platforms orchestrating interoperable high-value assets transactions across multiple financial organizations.

Introduction

The Execution Plan is a new core addition to the FinP2P protocol, functioning as a decentralized and asynchronous mechanism to facilitate cryptographically secure transactions across various Distributed Ledger Technology (DLT) platforms. Derived from one or more investor-signed transactions within the FinP2P network, the execution plan is co-created, validated, and approved by FinP2P organizations involved in the financial agreement's implementation.

The execution plan structure

The execution plan's foundation consists of several elements, including a roster of organizations (and potential observers) involved in the plan's execution, each accompanied by their corresponding cryptographic signatures. It also includes a collection of Execution Instructions, each denoting a specific operation, such as Holding, Transferring, or Releasing assets, or Waiting. The nature of these instructions may vary based on the transaction type and execution methodology (e.g., Escrow, HTLC, etc.).

Furthermore, the execution plan comprises cryptographic signatures of involved investors and an immutable, append-only execution state that is updated by each party following each operation execution.

The Execution Plan Lifecycle

Once one or more investors concur on transacting within a financial operation, as indicated by FinP2P's Indication of Interest (IOI), the execution plan originates from the relevant FinP2P organization using a specific signed FinP2P transaction, like a Buying DvP Transaction or Loan Transaction.

Agreement phase

Upon sharing the plan with participating FinP2P organizations, each validates the execution plan structure and sends a signed approval to the other participants. At this point, organizations can inform the DLT Adapter about the plan and optionally involve it in the approval process. Once approved, the plan immutability is governed by the parties signature.

Execution phase

Once the execution plan garners approval from the FinP2P organizations, the implementation begins. Each party, independently and asynchronously, follows a procedure:

...

For instance, consider the execution process for a Delivery versus Payment (DvP) plan for primary asset investment. As always on FinP2P, the execution plan is derived from an IOI, detailing the business agreement between parties. The process assumes both the buyer and seller have a FinP2P account used to manage their assets and currencies across the participating DLTs. Similar examples could be a Loan execution plan, with an On DvP for the initial phase, and the reverse direction DvP activated upon maturity conditions being met.

...

The Execution plan ID

The Execution Plan ID is an integral element of the execution process, being generated and issued by the executing party. The ID is a FinP2P Resource ID, carrying the prefix of the organization ID of the issuing party, succeeded by a type, specifically 106 for Execution Plan, and lastly, a unique raw ID, which typically can be a random (Version 4) UUID string of 36 characters.

This ID can serve as the Unique Transaction Identifier (UTI) of the underlying financial process. Additionally, we may consider incorporating the organization's Legal Entity Identifier (LEI) into the organization token, allowing for a correlation with the organization ID referenced by the Execution Plan ID.

Failure Management and Compensating Procedures

The execution plan allows handling execution failures of any steps in the plan in a systematic and organized manner. The protocol distinguishes between two types of failures - failures at reversible points that activate compensating operations, and all other failures that offer a transparent view of the execution progress.

...

In addition, the execution plan supports transparency in failure management. All parties can monitor the progress of the execution, even when there are delays or instructions fail to execute. By using the Execution State and associated cryptographic proofs, parties can see completed operations and encountered errors, fostering trust among all participants. This transparency in monitoring the progress and robustly managing potential failures is a vital feature of the FinP2P protocol. It contributes significantly to its resilience, transparency, and reliability in managing multi-party, interoperable transactions.

FinP2P Network Interface Specification additions

The APIs additions to the FinP2P protocol provide the nodes on the network tools to coordinate by choreography various financial operation by providing endpoints to express Proposals of said operation to prospect participant and allowing the participant to indicate by Approve or Reject their willingness and ability to take part in the operation.

Utilizing an choreography model for operation allows for flexibility and robustness in the financial operation, the messages are sent between each participant to another thus creating a decentralized trust model where no node acts as a centralized governor of the execution plan lifecycle.

The Proposal-Approval\Reject model is extended further than the Execution Plan approval phase into the Instruction completion propagation where nodes communicate with each other the completion of a plan instruction and its outcome, where the receiving nodes of the completion must Approve or Reject the completion and propagate their decision to all other participant of the plan before the plan can progress to the next instruction.

Execution Plan Service

Code Block
// Distributed decentralized workflow choreography with multi-party approval

service ExecutionService {

  // Proposal of plan or instruction completion event to participants
  rpc Propose (SignedProposeRequest) returns (SignedProposeResponse) {}

  // Approval provided by participant of the plan
  rpc Approve(SignedApproveRequest) returns (SignedApproveResponse) {}

  // Rejection provided by participant of the plan
  rpc Reject(SignedRejectRequest) returns (SignedRejectResponse) {}
}

Request Response Models

Code Block
message SignedRejectRequest {
  RejectRequest request = 1;
  finp2p.common.SealingSignature signature = 2;
}

message RejectRequest {
  finp2p.common.Envelope envelope = 1;
  oneof rejection {
    ExecutionPlanRejection plan = 100;
    InstructionCompletionRejection instructionCompletion = 101;
  }
}

message ExecutionPlanRejection {
  finp2p.common.ResourceID executionPlanId = 1;
  string reason = 3;
}

message InstructionCompletionRejection {
  finp2p.common.ResourceID executionPlanId = 1;
  uint32 instructionSequence = 2;
  string reason = 3;
}

message SignedRejectResponse {
  RejectResponse response = 1;
  finp2p.common.SealingSignature signature = 2;
}

message RejectResponse {
  finp2p.common.Envelope envelope = 1;
  finp2p.common.Status status = 2;
}

message SignedApproveRequest {
  ApproveRequest request = 1;
  finp2p.common.SealingSignature signature = 2;
}

message ApproveRequest {
  finp2p.common.Envelope envelope = 1;
  oneof approval {
    ExecutionPlanApproval plan = 100;
    InstructionCompletionApproval instructionCompletion = 101;
  }
}

message SignedProposeRequest {
  ProposeRequest request = 1;
  finp2p.common.SealingSignature signature = 2;
}

message ProposeRequest {
  finp2p.common.Envelope envelope = 1;
  oneof proposal {
    ExecutionPlanProposal executionPlan = 100;
    InstructionCompletionEvent instructionCompletion = 101;
  }
}

message InstructionCompletionEvent {
  ExecutionInstruction instruction = 1;
  finp2p.common.Status status = 2;
  finp2p.signature.Signature signature = 3;
  oneof output {
    finp2p.receipt.Receipt receipt = 100;
  }
}

message ExecutionPlanProposal {
  ExecutionPlan plan = 1;
}

message SignedProposeResponse {
  ProposeResponse response = 1;
  finp2p.common.SealingSignature signature = 2;
}

message ProposeResponse {
  finp2p.common.Envelope envelope = 1;
  finp2p.common.Status status = 2;
}

message SignedApproveResponse {
  ApproveResponse response = 1;
  finp2p.common.SealingSignature signature = 2;

}

message ApproveResponse {
  finp2p.common.Envelope envelope = 1;
  finp2p.common.Status status = 2;
}
Execution Plan Model
Code Block
message Execution {
  ExecutionPlan plan = 1;
  repeated ExecutionPlanApproval approvals = 2;
  repeated InstructionCompletionEvent events = 3;
  uint32 currentInstructionSequence = 4;
  string executionPlanStatus = 5;
}

message ExecutionPlanApproval {
  finp2p.common.ResourceID executionPlanId = 1;
  string organizationID = 2;
  finp2p.signature.Signature signature = 3;
}

message InstructionCompletionApproval {
  finp2p.signature.Signature signature = 1;
  InstructionCompletionEvent instructionCompletion = 2;
}

message Error {
  int32 code = 1;
  string message = 2;
}


message ExecutionPlanIntent {
  finp2p.intents.AssetTransactionIntent intent = 1;
  uint32  version = 2;
}

message ExecutionPlan {
  reserved 3;
  finp2p.common.ResourceID id = 1;
  ExecutionPlanIntent intent = 2;
  repeated Participant participants = 4;
  repeated ExecutionInstruction instructions = 5;
}

message Participant {
  string organizationID = 1;
  enum Role {
    Unknown = 0;
    Observer = 1; // Read only access to state, gets notified on state changes
    Contributor = 2; // Read Write access, participate in state changes multi-party approval
  }
  repeated Role roles = 2;
}

message ExecutionInstruction {
  finp2p.common.ResourceID planId = 1;
  uint32 sequence = 2; // monotonic increasing sequence (order) number of the instruction
  repeated string organizations = 3; // expected organization that will execute the instruction and provide
  oneof operation {
    HoldInstruction hold = 100;
    TransferInstruction transfer = 101;
    ReleaseInstruction release = 102;
    AwaitInstruction await = 103;
    IssueInstruction issue = 104;
  }
}

message OwnerAccount {
  finp2p.common.ResourceID owner = 1;
  finp2p.accounts.AccountIdentifier account = 2;
}

Execution instructions
Code Block
message IssueInstruction {
  finp2p.common.ResourceID buyer = 1;
  finp2p.accounts.Account destination = 2;
  finp2p.common.Decimal amount = 3;
  finp2p.signature.Signature signature = 4;
}

message HoldInstruction {
  message Account {
    finp2p.common.ResourceID owner = 1;
    finp2p.accounts.AccountIdentifier account = 2;
  }

  Account source = 1;
  Account destination = 2;
  finp2p.accounts.Asset asset = 3; // asset information for which to hold the specified amount, might be different than account asset and potentially trigger a conversion
  finp2p.common.Decimal amount = 4;
  finp2p.signature.Signature signature = 5;
}

message TransferInstruction {
  finp2p.accounts.Account source = 1;
  finp2p.accounts.Account destination = 2;
  finp2p.common.Decimal amount = 3;
  finp2p.signature.Signature signature = 4;
}

message ReleaseInstruction {
  finp2p.accounts.Account source = 1;
  finp2p.accounts.Account destination = 2;
  finp2p.common.Decimal amount = 3;

  uint32 holdInstructionSequence = 10;
}

message AwaitInstruction {
  google.protobuf.Timestamp waitUntil = 1;
}

...