diem / dip Goto Github PK
View Code? Open in Web Editor NEWLibra Improvement Proposals
Home Page: https://lip.libra.org
License: Apache License 2.0
Libra Improvement Proposals
Home Page: https://lip.libra.org
License: Apache License 2.0
As described in DIP 158, the P2M flow involves redirecting a customer from the merchant site to their customer VASP for payment approval. Recap:
The redirect URL is likely to be used in the Web Redirect flow which means that the customer will be redirected from the merchant's checkout page to the wallet's website to review and approve the payment.
The table below specifies the fields that should be encoded into a series of URL parameters appended to the query string.
Field | Type | Required? | Description |
---|---|---|---|
vasp_address | str | Y | Address of receiving VASP. The address is encoded using bech32. For Diem addresses format, refer to the "account identifiers" section in DIP-5. |
reference_id | str | Y | A unique identifier of this payment. It should be a UUID according to RFC4122 with "-"'s included. |
redirect_url | str | N | Encoded URL used by the wallet to redirect the customer back to the merchant |
The redirect_url, and other Customer VASP configuration, is never set, and never stored. This onboarding of Customer VASPs via a registration step is required for any future P2M flows.
A DIP describing a Customer VASP registration step that sets its configuration on-chain within Move, so that Merchant VASPs are able to retrieve and send said P2M configuration data for the Web Redirect Flow. This includes but is not limited to redirect_url
, image_url
.
This issue is to track the development of the DIP for state sync v2. A pull request with a draft DIP will follow shortly. The TL;DR for those interested:
[1] diem/diem#6795
Authors: Joshua Lind (@JoshLind), David Wong (@mimoo)
Status: Rough draft (for discussion)
TCB Overview
Securing TCBs
To reason about the Diem TCB, we first make several assumptions about validators and their components in a blockchain.
Assumptions about validators:
Note: We consider it future work to challenge these assumptions (see the bottom of this document).
Assumed components in a validator:
Next, we assume a simple validator component abstraction (VCA):
In order to analyze the security benefits of a TCB, we propose the following (informal) security definitions:
Types of compromise:
Types of security impact:
The Adversary model:
Consensus assumes that f
validators are byzantine and colluding (i.e., completely compromised). We therefore consider the TCB interesting if it can still provide security properties when h
additional compromises occur (shallow or deep). We consider two adversary models:
f
byzantine validators and h<=f
shallow or deep compromises.f
byzantine validators and h>f
shallow or deep compromises.Types of Attacks:
We consider three high-level types of attacks:
S
, we get the next committed state via execution(S, transaction),
i.e, this is the property we expect from the blockchain. Using this definition, correctness attacks can be divided into two categories:
S
, we can extend it to a state S'
, where S'
is not the result of execution(S, transaction),
for any S
and transaction
. In this attack, honest verifying clients (verifying full nodes and validators) will become stuck and unable to reach the arbitrary state.f
validators are completely compromised, any further compromises will violate liveness globally.To begin reasoning about the TCB in Diem, we take a step by step approach to building a TCB based on the VCA above. For each step, we reason about the security guarantees of the design.
Step 1: TCB = { Consensus key }
To begin, we move only the consensus key into the TCB and propose that consensus asks the TCB to sign data (e.g., votes). Reasoning about security, we see:
f
byzantine nodes. In the quorum adversary model, semantic correctness can also be violated (an attacker can arbitrarily extend the state).Step 2: TCB = { Consensus key + Safety Rules }
To improve on step 1, we focus on hardening the validator against safety attacks. To do this, we partition consensus and move a subset of the consensus module into the TCB, labelled safety rules. Safety rules contains a set of verification constraints that when enforced by enough validators (>= 2f+1
) prevent forks in the consensus protocol (see the Voting Rules in the Consensus specification). Reasoning about security, we now see:
2f+1
validators to certify and commit a non-semantic extension.2f+1
validators can certify and commit a non-semantic extension. This is because a compromised safety rules will agree to vote on any execution state.Step 3: TCB = { Consensus Keys + Safety Rules + Execution }
To prevent attacks on correctness (as seen in step 2 above), we need to ensure that shallow compromises cannot enable voting on proposals that arbitrarily extend state. To achieve this, we observe that one can simply move the execution logic (including the Move VM) into the TCB. This will enforce correct execution of transactions. However, one still needs to ensure that execution extends the correct state. Here, one could move storage into the TCB. However, this is naive as it bloats the TCB. Instead, we observe that it is more beneficial to treat storage as untrusted and instead have execution keep track of valid state root hashes and update them within the TCB. We call this approach execution correctness.
We now reason about the security of this approach:
Today, execution correctness is still a work in progress and not part of the TCB. As such, shallow compromises defend against everything but correctness attacks (see step 2 of the incremental TCB). In this section, we take a look at various implementation details of the TCB as it stands today:
Based on the observations above, we outline the following design and implementation improvements for the TCB (v2):
Design Improvements:
Implementation Improvements:
The list below contains future explorations for the TCB. Each of these requires additional thought and analysis.
HTTP end point in LIP-1 specifies that HTTP urls has the following format:
https://<hostname>:<port>/<protocol_version>/<LocalVASPAddress>/<RemoteVASPAddress>/command
It has been causing some confusion of what LocalVASPAddress
and RemoteVASPAddress
means and it is sort of easy to mix them up. As this URL will also be used in other off chain related LIPs, it's worth discussing whether we want to keep them in the URL.
Pros:
Cons:
I also think it's worthwhile discussing whether we put protocol_version
in the front or rear (i.e. after command
). Because as we add protocols in the future, more keywords will be introduced (e.g. pay
in Libra ID). Logically we want them each to have a version (easier for iterating).
cc @kphfb , @gdanezis , @xli , @sunmilee , @andll , @bmaurer
Sequence numbers today provide a simple mechanism to prevent transactions from being replayed — only a single transaction can ever be processed for a given sequence number/account combination. Additionally, the sequence number provides a way of enforcing sequentiality; a sender can send transactions with sequence numbers 0, 1, 2, and 3 to the network in any order since the sender knows that 1 can only be processed after 0, 2 after 1, etc.
However, sequence numbers today present issues due to sequence number lockup: once a transaction at a given sequence number n is chosen, the sending account will block on being able to process other transactions with sequence numbers greater than n until that transaction has been processed. This issue has cropped up in multiple places so far, and in general will be an issue when any off-chain activity related to signing a full transaction is being considered.
In general we have observed a theme here with sequence numbers: they prevent replays, and ensure strict sequentiality, however this “strict sequentiality” presents serious usability issues in off-chain protocols. This proposal would introduce the idea of a Conflict-Resistant Sequence Number (CRSN) that relaxes this strict sequentiality to allow concurrent processing of transactions while also allowing some level of dependency between transactions sent by the same account to be expressed.
CRSNs would work at the account level and would be an opt-in feature. No breaking changes would be needed to Diem data structures as the transaction's sequence_number
field can be reused.
Currently in the Diem Framework, a transaction acts on behalf of a single on-chain account. However, there is no mechanism for multiple on-chain accounts to agree on a single atomic transaction. This DIP presents a new scheme of transactions--multi-agent transactions--which act on behalf of multiple on-chain accounts. Multi-agent transactions leverage Move’s signer
type to allow essentially any arbitrary atomic actions in one transaction involving multiple on-chain accounts.
DIP PR here: #159
This should describe the following advance payment flows to support P2M scenarios -
Author: Xiao Li (@xli)
Status: Idea (for discussion)
To improve the ability of off-chain service handling network problems and protocol errors, we’d like to introduce a ping command for client to:
The PingCommand object definition:
Field | Type | Required? | Description |
---|---|---|---|
_ObjectType | str | Y | The fixed string PingCommand |
An example CommandRequestObject
JSON message with PingCommand
:
{
"_ObjectType": "CommandRequestObject",
"command_type": "PingCommand",
"command": {
"_ObjectType": "PingCommand",
},
"cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a",
}
And the response of the PingCommand
:
{
"_ObjectType": "CommandResponseObject",
“status”: “success”,
"cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a"
}
Note we don’t need a random message body in PingCommand for the server to response, because the off-chain API protocol already have a cid
field defined in the CommandRequestObject
and CommandResponseObject
to serve the purpose of distinguish different command instance.
There is no command_error
for this command. Server may respond with protocol_error
(with CommandResponseObject.status==“failure”) defined in DIP-1 when processing an invalid HTTP headers, JWS message or CommandRequestObject
payload.
This is a discussion and feedback thread for https://github.com/diem/dip/blob/main/dips/dip-11.md
Starting this issue to discuss options on how to incorporate Libra ID into payment API
There are two general options available
Currently PaymentActorObject is used to specify sender/receiver of the payment.
PaymentActorObject
has a field address
that currently contains address and subaddress of sender/recipient.
We can modify PaymentActorObject so that address
field can contain Libra ID instead of address+subaddress pair.
Similarly, we can update PaymentActorObject
to allow for sharing of the rich data. This can be done by adding field new info
field to the PaymentActorObject
. Info field would have type LIP10::UserObject (we would move this type definition to LIP-1)
(+) Single request for p2p payment. This approach seem to overlay nicely with current LIP-1 design
(-) This approach requires triggering complex payment flow for any p2p transfer that involves Libra ID. This means that VASP that wants to use Libra ID has to implement KYC endpoint.
(-) With this design it becomes impossible to offload Libra ID to 3rd party service(for example service ran by association)
(-) Not clear how info endpoint will look like. Do we still have separate information endpoint just for that like LIP-10 currently suggests? Or do we create dummy payment just to exchange rich data and reuse payments endpoint from LIP-1?
This option means that sender/receiver
fields of the PaymentObject becomes optional (even for payment creation).
In this flow, Libra ID pay
endpoint is used to negotiate reference_id
. Negotiated reference_id
can either be used to submit a payment on the chain right away, or it can be passes as PaymentObject::reference_id
to the KYC endpoint from the LIP-1, to negotiate KYC data.
(+) Libra ID becomes separate from KYC. Libra ID pay endpoint is a simple request-response endpoint and return reference id that can be used immediately for posting payment on the chain.
(+) VASPs do not have to implement KYC endpoint to use Libra ID for sending money below KYC threshold
(+) Libra ID can be separated into 3rd party service
(-) For payments that requires KYC, this design introduces extra 'hop` where reference_id first needs to be negotiated via Libra ID, and only then KYC endpoint can be used to continue the process
What happens if one of the parties loses synchronization?
Scenario 1 - Server out of sync?
The protocol server sends a command to the protocol client and ask to mutate an object.
The command _reads object version 1 in an attempt to write version 2 while the protocol client possess version 5
in such cases what should the client do? fall back to the server version?
Scenario 2 - Client out of sync?
The protocol client sends a command that reads object version 1 and willing to mutate it onto version 2.
The server the last version is already version 5. In that case, since the server is the source of truth how the client is supposed
to fetch the diff and resync it's channel state? (versions 2-5)
Scenario 3 - One of the parties lost channel state completely (disaster recovery)
In the recurring payments scenario recipient VASP (some merchant acquirer) should ask sending VASP (some consumer wallet) for a FundPullPreApprovalCommand (request for consumer consent for a recurring charge by the merchant). After such a request has been submitted the recipient VASP can now use "out-of-band methods" (Some interaction with the wallet user) to approve/reject the pull pre-approval request.
According to my understanding of the process, we may encounter a problem.
Let's say a merchant consumer wants to add Libra as a payment method (i.e to his favorite transportation app who wants to charge him for every trip).
The merchant app will ask it's Libra acquirer service to generate a request for a recurring charge consent. Problem is,
at that point in time nor the merchant or the acquirer can know who is the consumer VASP and who is the specific user (subaddress?) inside the VASP to whom the pre-approval request should be sent to.
Alternative flow might be:
Thoughts?
Right now, we cannot have nested directories in the lip
directory.
8:54:41 AM: > node scripts/createDocsDir.js && docusaurus build
8:54:43 AM: Creating an optimized production build...
8:54:43 AM: Error: EISDIR: illegal operation on a directory, read
8:54:43 AM: npm
8:54:43 AM: ERR! code ELIFECYCLE
8:54:43 AM: npm
8:54:43 AM: ERR! errno 1
8:54:43 AM: npm ERR! [email protected] build: `node scripts/createDocsDir.js && docusaurus build`
8:54:43 AM: npm ERR! Exit status 1
See commits of #7 for an example.
Research team has been working on DiemBFT v4 and one of the major improvement is to achieve 2-chain commit instead of 3-chain leveraging existing round synchronization mechanism.
This issue is intended to track the development of the corresponding DIP https://github.com/diem/dip/blob/main/dips/dip-201.md.
This issue is intended to track the development of DIP-10.
Create a DIP describing Refunds flow
placeholder for now
The following format in the header front matter of a lip causes a Docusaurus build error, I think due to the plugin that renders the lips
05-29-2020
You have to use
05/29/2020
Error: Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=Thu%20May%2028%202020%2017%3A00%3A00%20GMT-0700%20(Pacific%20Daylight%20Time)&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
(undefined) Error: Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=Thu%20May%2028%202020%2017%3A00%3A00%20GMT-0700%20(Pacific%20Daylight%20Time)&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
at T (main:25138:94)
at V (main:25138:229)
at X (main:25139:321)
at toArray (main:25140:398)
at a.b.renderDOM (main:25216:460)
at a.b.render (main:25209:326)
at a.b.read (main:25208:18)
at Object.renderToString (main:25218:364)
at render (main:51820:252)
Error: Failed to compile with errors.
at /Users/joelm/dev/lip-primary/node_modules/@docusaurus/core/lib/commands/build.js:37:24
at finalCallback (/Users/joelm/dev/lip-primary/node_modules/webpack/lib/MultiCompiler.js:254:12)
at /Users/joelm/dev/lip-primary/node_modules/webpack/lib/MultiCompiler.js:277:6
at done (/Users/joelm/dev/lip-primary/node_modules/neo-async/async.js:2931:13)
at runCompilers (/Users/joelm/dev/lip-primary/node_modules/webpack/lib/MultiCompiler.js:181:48)
at /Users/joelm/dev/lip-primary/node_modules/webpack/lib/MultiCompiler.js:188:7
at /Users/joelm/dev/lip-primary/node_modules/webpack/lib/MultiCompiler.js:270:7
at finalCallback (/Users/joelm/dev/lip-primary/node_modules/webpack/lib/Compiler.js:257:39)
at /Users/joelm/dev/lip-primary/node_modules/webpack/lib/Compiler.js:273:13
at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/joelm/dev/lip-primary/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:40:1)
at AsyncSeriesHook.lazyCompileHook (/Users/joelm/dev/lip-primary/node_modules/tapable/lib/Hook.js:154:20)
at onCompiled (/Users/joelm/dev/lip-primary/node_modules/webpack/lib/Compiler.js:271:21)
at /Users/joelm/dev/lip-primary/node_modules/webpack/lib/Compiler.js:681:15
at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/joelm/dev/lip-primary/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:4:1)
at AsyncSeriesHook.lazyCompileHook (/Users/joelm/dev/lip-primary/node_modules/tapable/lib/Hook.js:154:20)
at /Users/joelm/dev/lip-primary/node_modules/webpack/lib/Compiler.js:678:31
error Command failed with exit code 1.
See #7 for an example.
DIP-4 indicates that the parties explicitly define a to and a from subaddress in the metadata. In order for this to be useful the parties would need to assign pseudonyms internally and exchange those externally. This requires an unmentioned protocol. I would propose that instead the recipient simply indicate unique subaddress for each "from". Using the flows in the doc:
NC => NC
No need
C => NC
Recipient NC would share a distinct subaddress so that it can track the submitter
NC => C
No need
C => C
Recipient VASP would share a distinct subaddress so that it can track the submitter
This information can then be stored easily within a one-time use QR code, bech32 encoded identifier requiring minimal interaction to generate verifiable payment for both payer and payee.
In any case (as proposed in LIP-4 or mentioned here), there is no way to prevent either party from leaky information or ensuring that they choose an identifier dynamically.
dip: 161
title: Off-Chain Protocol: Optional Result Field
author: Xiao Li (@xli), SunMi Lee (@sunmilee), David Wolinsky (@davidiw)
type: Informational
discussion-to: #161
created: 2021-04-07
updated: 2021-04-07
Both the Off-Chain Protocol and Travel Rule Exchange (or PaymentCommand) are defined in DIP-1. The Off-Chain Protocol was defined in such a way as to support the minimal requirements for these exchanges, specifically, in this case, asynchronous responses to requests. Many types of communication benefit from synchronous responses as it provides for both protocol simplicity and reduced latency. In order to support synchronous commands, the CommandResponseObject
can leverage an optional field: result
. The result
field, if defined, must contain __ObjectType
that should uniquely define the shape or other fields within the result
.
Here's an example from DIP-10:
{
"_ObjectType": "CommandResponseObject",
"status": "success",
"result": {
"_ObjectType": "ReferenceIDCommandResponse",
"recipient_address": "c5ab123458df0003415689adbb47326d",
},
"cid": "12ce83f6-6d18-0d6e-08b6-c00fdbbf085a",
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.