Skip to content

Commit

Permalink
Proposed v0 DLC TLV messages and Deterministic Fee Computation (#81)
Browse files Browse the repository at this point in the history
* Specified DLC TLV messages and added happy-path test vectors

* Responded to Ben's review

* Updated test vectors to use correct Multisignature ordering and up-to-date BIP 340

* Responded to Tibo's review

* Attempted to specify funding inputs and funding signatures in a general way

* Regenerated test vectors as per the updated funding input and funding signature specification

* Specified generalized fee computation and fixed test vectors

* Added oracle signature and signed transactions to test vectors

* Responded to review from Tibo

* Fixed table of contents

* Clarified TLV vs. LN Message format, fixed off-by-one fee computation, updated test vectors for fees, have not yet updated test vectors for LN Message format

* Made offer, accept and sign conform with Lightning Message format

* Added a clarification

* Made contract_info a proper object

* Fixed test vector contract id hashes

* Made redeem script use compact size uint and removed test vectors from this PR
  • Loading branch information
nkohen committed Sep 29, 2020
1 parent dfa2a46 commit 22b23eb
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 57 deletions.
125 changes: 118 additions & 7 deletions Messaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ All data fields are unsigned big-endian unless otherwise specified.
* [Connection Handling and Multiplexing](#connection-handling-and-multiplexing)
* [Message Format](#message-format)
* [Fundamental Types](#fundamental-types)
* [DLC Specific Types](#dlc-specific-types)
* [The `contract_info` Type](#the-contract_info-type)
* [Version 0 `contract_info`](#version-0-contract_info)
* [The `oracle_info` Type](#the-oracle_info-type)
* [Version 0 `oracle_info`](#version-0-oracle_info)
* [The `funding_input` Type](#the-funding_input-type)
* [Temporary `funding_input`](#temporary-funding_input)
* [The `cet_adaptor_signatures` Type](#the-cet_adaptor_signatures-type)
* [Version 0 `cet_adaptor_signatures`](#version-0-cet_adaptor_signatures)
* [The `funding_signatures` Type](#the-funding_signatures-type)
* [Version 0 `funding_signatures`](#version-0-funding_signatures)
* [Authors](#authors)

## Connection Handling and Multiplexing
Expand All @@ -20,7 +31,13 @@ Implementations MUST use a single connection per peer; contract messages (which

## Message Format

We reuse the [Lightning Message Format](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#lightning-message-format) and the [Type-Length-Value Format](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#type-length-value-format)
We reuse the [Lightning Message Format](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#lightning-message-format) and the [Type-Length-Value Format](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#type-length-value-format) (TLV).
To be clear, any encoded binary blob that can be sent over the wire will follow the Lightning Message Format
while all sub-types internal to these messages will follow the Type-Length-Value Format.
This means that types on outer-messages will be represented with `u16` integers (defined below) and their length
is omitted from their encoding because the transport layer has the length in a separate unencrypted field.
Meanwhile all typed sub-messages (which follow TLV format) will have their types represented using `bigsize` integers
(defined below) and their lengths (also `bigsize`) are included in their encodings.

## Fundamental Types

Expand All @@ -44,20 +61,114 @@ The following convenience types are also defined:
* `contract_id`: a 32-byte contract_id (see [Protocol Specification](Protocol.md))
* `sha256`: a 32-byte SHA2-256 hash
* `signature`: a 64-byte bitcoin Elliptic Curve signature
* `ecdsa_adaptor_signature`: a 65-byte ECDSA adaptor signature (TODO: link to doc once [#50](https://github.com/discreetlogcontracts/dlcspecs/issues/50) is done)
* `dleq_proof`: a 97-byte zero-knowledge proof of discrete log equality (TODO: link to doc once [#50](https://github.com/discreetlogcontracts/dlcspecs/issues/50) is done)
* `x_point`: a 32-byte x-only public key with implicit y-coordinate being even as in [BIP 340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design)
* `point`: a 33-byte Elliptic Curve point (compressed encoding as per [SEC 1 standard](http://www.secg.org/sec1-v2.pdf#subsubsection.2.3.3))
* `spk`: A bitcoin script public key encoded as ASM prefixed with a Bitcoin CompactSize unsigned integer
* `script_sig`: A bitcoin script signature encoded as ASM prefixed with a Bitcoin CompactSize unsigned integer
* `short_contract_id`: an 8 byte value identifying a contract funding transaction on-chain (see [BOLT #7](https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#definition-of-short-channel-id))
* `bigsize`: a variable-length, unsigned integer similar to Bitcoin's CompactSize encoding, but big-endian. Described in [BigSize](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#appendix-a-bigsize-test-vectors).
* `contract_info`: ???
* `oracle_info`: ???
* `funding_input`: ???
* `cet_signatures`: ???
* `funding_signatures`: ???

## DLC Specific Types

The following DLC-specific types are used throughout the specification. All type numbers are placeholders subject to change both here and in [Protocol.md](Protocol.md).

### The `contract_info` Type

This type contains information about a contracts outcomes and their corresponding payouts. To save space, only one side's POV is included in this message as the other can be derived using `remote_payout = total_collateral - local_payout`.

#### Version 0 `contract_info`

1. type: 42768 (`contract_info_v0`)
2. data:
* [`sha256`:`outcome_1`]
* [`u64`:`outcome_1_local_payout`]
* ...
* [`sha256`:`outcome_n`]
* [`u64`:`outcome_n_local_payout`]

This type of contract info is a simple enumeration where the value `n` is omitted from being explicitly included as it can be derived from the length field of the TLV.

### The `oracle_info` Type

This type contains information about the oracle(s) to be used in executing a DLC, and possibly the outcomes possible if these are not specified in the corresponding `contract_info`.

#### Version 0 `oracle_info`

1. type: 42770 (`oracle_info_v0`)
2. data:
* [`x_point`:`oracle_public_key`]
* [`x_point`:`oracle_nonce`]

This type of oracle info is for single-oracle, single signature (and hence single nonce) events.

### The `funding_input` Type

This type contains information about a specific input to be used in a funding transaction, as well as its corresponding on-chain UTXO.

#### Version 0 `funding_input`

1. type: 42772 (`funding_input_v0`)
2. data:
* [`u16`:`prevtx_len`]
* [`prevtx_len*byte`:`prevtx`]
* [`u32`:`prevtx_vout`]
* [`u32`:`sequence`]
* [`u16`:`max_witness_len`]
* [`script_sig`:`redeemscript`]

`prevtx_tx` is the serialized transaction whose `prevtx_vout` output is being spent.
The transaction is used to validate this spent output's value and to validate that it is a SegWit output.

`max_witness_len` is the total serialized length of the witness data that will be supplied
(e.g. sizeof(varint) + sizeof(witness) for each) in `funding_signatures`.

`redeemscript` is the script signature field for the input. Only applicable for P2SH-wrapped inputs.
In all native Segwit inputs, `redeemscript` will be a `0` byte (from the `script_sig` size prefix).

### The `cet_adaptor_signatures` Type

This type contains CET signatures and any necessary information linking the signatures to their corresponding outcome.

#### Version 0 `cet_adaptor_signatures`

1. type: 42774 (`cet_adaptor_signatures_v0`)
2. data:
* [`ecdsa_adaptor_signature`:`signature_1`]
* [`dleq_proof`:`dleq_prf_1`]
* ...
* [`ecdsa_adaptor_signature`:`signature_n`]
* [`dleq_proof`:`dleq_prf_n`]

This type should be used with [`contract_info_v0`](#version-0-contract_info) where each indexed signature in the data corresponds to the outcome of the same index. As in [`contract_info_v0`](#version-0-contract_info), the number of signatures is omitted as it can be derived from the length field of the TLV.

### The `funding_signatures` Type

This type contains signatures of the funding transaction and any necessary information linking the signatures to their inputs.

#### Version 0 `funding_signatures`

1. type: 42776 (`funding_signatures_v0`)
2. data:
* [`u16`:`num_witnesses`]
* [`u16`:`num_witness_elems_1`]
* [`num_witness_elems_1*witness_element`:`witness_elements_1`]
* ...
* [`u16`:`num_witness_elems_num_witnesses`]
* [`num_witness_elems_num_witnesses*witness_element`:`witness_elements_num_witnesses`]
3. subtype: `witness_element`
4. data:
* [`u16`:`len`]
* [`len*byte`:`witness`]

`witness` is the data for a witness element in a witness stack. An empty `witness_stack` is an error,
as every input must be Segwit. Witness elements should *not* include their length as part of the witness data.

## Authors

Nadav Kohen <[email protected]>

![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png "License CC-BY")
<br>
This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).
This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/).
27 changes: 14 additions & 13 deletions Protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ This message contains information about a node and indicates its
desire to enter into a new contract. This is the first step toward creating
the funding transaction and CETs.

1. type: ??? (`offer_dlc`)
1. type: 42778 (`offer_dlc_v0`)
2. data:
* [`byte`:`contract_flags`]
* [`chain_hash`:`chain_hash`]
Expand Down Expand Up @@ -154,7 +154,7 @@ acceptance of the new DLC, as well as its CET and refund transaction
signatures. This is the second step toward creating the funding transaction
and closing transactions.

1. type: ??? (`accept_dlc`)
1. type: 42780 (`accept_dlc_v0`)
2. data:
* [`32*byte`:`temporary_contract_id`]
* [`u64`:`total_collateral_satoshis`]
Expand All @@ -163,7 +163,7 @@ and closing transactions.
* [`u16`:`num_funding_inputs`]
* [`num_funding_inputs*funding_input`:`funding_inputs`]
* [`spk`:`change_spk`]
* [`cet_signatures`:`cet_signatures`]
* [`cet_adaptor_signatures`:`cet_adaptor_signatures`]
* [`signature`:`refund_signature`]

#### Requirements
Expand All @@ -173,8 +173,8 @@ The `temporary_contract_id` MUST be the SHA256 hash of the `offer_dlc` message.
The sender MUST:

- set `total_collateral_satoshis` sufficiently large so that the sum of both parties' total collaterals is at least as large as the largest payout in the `offer_dlc`'s `contract_info`.
- set `cet_signatures` to valid adaptor signatures, using its `funding_pubkey` for each CET, as defined in the [transaction specification](Transactions.md#contract-execution-transaction) and using signature public keys computed using the `offer_dlc`'s `contract_info` and `oracle_info` as adaptor points.
- include an adaptor signature in `cet_signatures` for every event specified in the `offer_dlc`'s `contract_info`.
- set `cet_adaptor_signatures` to valid adaptor signatures, using its `funding_pubkey` for each CET, as defined in the [transaction specification](Transactions.md#contract-execution-transaction) and using signature public keys computed using the `offer_dlc`'s `contract_info` and `oracle_info` as adaptor points.
- include an adaptor signature in `cet_adaptor_signatures` for every event specified in the `offer_dlc`'s `contract_info`.
- set `refund_signature` to the valid signature, using its `funding_pubkey` for the refund transaction, as defined in the [transaction specification](Transactions.md#refund-transaction).

The sender SHOULD:
Expand All @@ -186,7 +186,7 @@ The receiver:

- if `total_collateral_satoshis` is not large enough:
- MAY reject the contract.
- if `cet_signatures` or `refund_signature` fail validation:
- if `cet_adaptor_signatures` or `refund_signature` fail validation:
- MUST reject the contract.
- if `funding_inputs` do not contribute at least `total_collateral_satohis` plus [fee payment](Transactions.md#fee-payment)
- MUST reject the contract.
Expand All @@ -201,10 +201,10 @@ all closing transactions.

This message introduces the [`contract_id`](#definition-of-contract_id) to identify the contract.

1. type: ??? (`sign_dlc`)
1. type: 42782 (`sign_dlc_v0`)
2. data:
* [`contract_id`:`contract_id`]
* [`cet_signatures`:`cet_signatures`]
* [`cet_adaptor_signatures`:`cet_adaptor_signatures`]
* [`signature`:`refund_signature`]
* [`funding_signatures`:`funding_signatures`]

Expand All @@ -213,16 +213,17 @@ This message introduces the [`contract_id`](#definition-of-contract_id) to ident
The sender MUST:

- set `contract_id` by exclusive-OR of the `funding_txid` and the `funding_output_index` from the `offer_dlc` and `accept_dlc` messages.
- set `cet_signatures` to valid adaptor signatures, using its `funding_pubkey` for each CET, as defined in the [transaction specification](Transactions.md#contract-execution-transaction) and using signature public keys computed using the `offer_dlc`'s `contract_info` and `oracle_info` as adaptor points.
- include an adaptor signature in `cet_signatures` for every event specified in the `offer_dlc`'s `contract_info`.
- set `cet_adaptor_signatures` to valid adaptor signatures, using its `funding_pubkey` for each CET, as defined in the [transaction specification](Transactions.md#contract-execution-transaction) and using signature public keys computed using the `offer_dlc`'s `contract_info` and `oracle_info` as adaptor points.
- include an adaptor signature in `cet_adaptor_signatures` for every event specified in the `offer_dlc`'s `contract_info`.
- set `refund_signature` to the valid signature, using its `funding_pubkey` for the refund transaction, as defined in the [transaction specification](Transactions.md#refund-transaction).
- set `funding_signatures` to valid input signatures.
- include a signature in `funding_signatures` for every funding input specified in the `offer_dlc` message.
- set `funding_signatures` to contain valid witnesses for every funding input specified in the `offer_dlc` message and in the same order.

The recipient:

- if any `signature` is incorrect:
- if any `signature` or `witness` is incorrect:
- MUST reject the contract.
- if any witness exceeds its corresponding `max_witness_len` from the `offer_dlc` message:
- MAY reject the contract.
- MUST NOT broadcast the funding transaction before receipt of a valid `sign_dlc`.
- on receipt of a valid `sign_dlc`:
- SHOULD broadcast the funding transaction.
Expand Down
Loading

0 comments on commit 22b23eb

Please sign in to comment.