diff --git a/Messaging.md b/Messaging.md index 56b02c5..c8af317 100644 --- a/Messaging.md +++ b/Messaging.md @@ -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 @@ -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 @@ -44,15 +61,109 @@ 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 @@ -60,4 +171,4 @@ Nadav Kohen ![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png "License CC-BY")
-This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/). \ No newline at end of file +This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/). diff --git a/Protocol.md b/Protocol.md index 05dd6b4..73174d9 100644 --- a/Protocol.md +++ b/Protocol.md @@ -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`] @@ -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`] @@ -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 @@ -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: @@ -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. @@ -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`] @@ -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. diff --git a/Transactions.md b/Transactions.md index 279f9d0..f520044 100644 --- a/Transactions.md +++ b/Transactions.md @@ -108,6 +108,7 @@ The actual and expected weights vary for several reasons: * Bitcoin uses DER-encoded signatures, which vary in size. * Bitcoin also uses variable-length integers, so a large number of outputs will take 3 bytes to encode rather than 1. +* Witnesses may be less than `max_witness_len` * The offerer output may be below the dust limit. * The accepter output may be below the dust limit. @@ -115,45 +116,59 @@ Thus, a simplified formula for *expected weight* is used, which assumes: * Signatures are 72 bytes long. * There are a small number of outputs (thus 1 byte to count them). +* All witnesses are of size `max_witness_len` This yields the following *expected weights* (details of the computation below): ``` -Funding Transaction weight: 286 + 4 * total_change_length + 272 * num_inputs -CET/Refund Transaction weight: 500 + 4 * total_output_length +Funding Transaction weight: 214 + (72 + 4*total_change_length) + + sum(164 + 4*script_sig_len + max_witness_len) +CET/Refund Transaction weight: 498 + 4 * total_output_length ``` ### Fee Payment The funding output's value is composed of the sum of both parties' `total_collateral` (from offer/accept messages) plus the `max_fee` of closing transactions. In this way all fees are paid for in the [Funding Transaction](#funding-transaction) so that the funding output's value is inflated and the outputs of CETs and the refund transaction are the exact amounts specified in the offer message's contract information (or total collateral specified in the offer and accept messages for the refund transaction) with no fees subtracted from closing transactions. -All fees are currently paid evenly between the two parties, though this will change in a future version. +Shared fields' fees are paid evenly between the two parties, while fields that belong to a specific party (i.e. funding inputs, change outputs, CET outputs) are paid by the contributing party. Specifically, a party's funding transaction and closing transaction weights are computed as (details of computation below): -Note that if an outcome occurs in which one party's output is below the dust limit of `1000 satoshis`, then the resulting fee rate will be larger than *expected*. +``` +input_weight = sum(164 + 4*script_sig_len + max_witness_len) (over party's funding inputs) +output_weight = 36 + 4*change_spk_script length +total_funding_weight = 107 + output_weight + input_weight -## Expected Weight of the Funding Transaction +cet_weight = 249 + 4*payout_spk length +``` -The *expected weight* of a funding transaction is calculated as follows: +These weights must be divided by `4` (rounding up) to get vbytes after which these numbers are multiplied by the fee rate. The resulting funding fee is subtracted in value from the change output while the CET fee is added to the funding output's value and also subtracted from this party's change output. + +Note that if a CET occurs in which one party's output is below the dust limit of `1000 satoshis`, then the resulting fee rate will be larger than *expected*. + +### Computation of `max_witness_len` + +The `max_witness_len` should be computed to be an upper bound on the byte size of all elements on the witness stack (and no other data). For example, a P2WPKH funding input should have a `max_witness_len` of `108`: ``` -p2wpkh: 22 bytes - - OP_0: 1 byte - - OP_DATA: 1 byte (public_key_HASH160 length) - - public_key_HASH160: 20 bytes +p2wpkh witness: 108 bytes + - number_of_witness_elements: 1 byte + - sig_length: 1 byte + - sig: 72 bytes + - pub_key_length: 1 byte + - pub_key: 33 bytes +``` -p2wsh: 34 bytes - - OP_0: 1 byte - - OP_DATA: 1 byte (witness_script_SHA256 length) - - witness_script_SHA256: 32 bytes +## Expected Weight of the Funding Transaction -funding_input: 41 bytes +The *expected weight* of a funding transaction is calculated as follows: + +``` +funding_input: 41 + script_sig_len bytes - previous_out_point: 36 bytes - hash: 32 bytes - index: 4 bytes - var_int: 1 byte (script_sig length) - - script_sig: 0 bytes - - witness <---- "witness" is used instead of "script_sig" for - transaction validation; however, "witness" is stored + - script_sig: script_sig_len bytes + - witness <---- "witness" is stored separately, and the cost for its size is smaller. So, the calculation of ordinary data is separated from the witness data. @@ -163,13 +178,6 @@ witness_header: 2 bytes - flag: 1 byte - marker: 1 byte -witness: 108 bytes - - number_of_witness_elements: 1 byte - - sig_length: 1 byte - - sig: 72 bytes - - pub_key_length: 1 byte - - pub_key: 33 bytes - change_output: 9 + change_spk_script length bytes - value: 8 bytes - var_int: 1 byte (pk_script length) @@ -180,14 +188,14 @@ funding_output: 43 bytes - var_int: 1 byte (pk_script length) - pk_script (p2wsh): 34 bytes -funding_transaction: 71 + offer_change_spk_script length + accept_change_spk_script length + 41 * num_inputs bytes +funding_transaction: 53 + (9 + offer_change_spk_script length) + (9 + accept_change_spk_script length) + sum(41 + script_sig_len) bytes - version: 4 bytes - witness_header <---- part of the witness data - count_tx_in: 1 byte - - tx_in: 41 bytes * num_inputs - funding_input + - tx_in: sum(41 + script_sig_len) bytes + funding_inputs - count_tx_out: 1 byte - - tx_out: 61 + offer_change_spk_script length + accept_change_spk_script length + - tx_out: 43 + (9 + offer_change_spk_script length) + (9 + accept_change_spk_script length) bytes funding_ouptut (43 bytes), change_output (9 + offer_change_spk_script length bytes), change_output (9 + accept_change_spk_script length bytes) @@ -198,13 +206,19 @@ Multiplying non-witness data by 4 results in a weight of: ``` // total_change_length = offer_change_spk_script length + accept_change_spk_script length -// 284 + 4 * total_change_length + 164 * num_inputs weight +// 212 + (72 + 4*total_change_length) + sum(164 + 4*script_sig_len) weight funding_transaction_weight = 4 * funding_transaction -// 2 + 108 * num_inputs weight +// 2 + sum(offer_max_witness_len) + sum(accept_max_witness_len) weight witness_weight = witness_header + witness * num_inputs -overall_funding_tx_weight = 286 + 4 * total_change_length + 272 * num_inputs weight +overall_funding_tx_weight = 214 + (72 + 4*total_change_length) + sum(164 + 4*script_sig_len + max_witness_len) weight + +offer_funding_tx_weight = 107 + (36 + 4*offer_change_spk_script length) + sum(164 + 4*offer_script_sig_len + offer_max_witness_len) weight +offer_funding_tx_vbytes = Ceil(offer_funding_tx_weight / 4.0) vbytes + +accept_funding_tx_weight = 107 + (36 + 4*accept_change_spk_script length) + sum(164 + 4*accept_script_sig_len + accept_max_witness_len) weight +accept_funding_tx_vbytes = Ceil(accept_funding_tx_weight / 4.0) vbytes ``` ## Expected Weight of the Contract Execution or Refund Transaction @@ -238,13 +252,13 @@ witness_header: 2 bytes - flag: 1 byte - marker: 1 byte -witness: 222 bytes +witness: 220 bytes - number_of_witness_elements: 1 byte - nil_length: 1 byte - sig_offer_length: 1 byte - - sig_offer: 73 bytes + - sig_offer: 72 bytes - sig_accept_length: 1 byte - - sig_accept: 73 bytes + - sig_accept: 72 bytes - witness_script_length: 1 byte - witness_script (multi_sig): 71 bytes @@ -278,10 +292,16 @@ Multiplying non-witness data by 4 results in a weight of: // 276 + 4 * total_output_length weight cet_weight = 4 * cet -// 224 weight +// 222 weight witness_weight = witness_header + witness -overall_cet_weight = overall_refund_tx_weight = 500 + 4 * total_output_length weight +overall_cet_weight = overall_refund_tx_weight = 498 + 4 * total_output_length weight + +offer_cet_weight = 249 + 4 * offer_output_script_length weight +offer_cet_vbytes = Ceil(offer_cet_weight / 4.0) vbytes + +accept_cet_weight = 249 + 4 * accept_output_script_length weight +accept_cet_vbytes = Ceil(accept_cet_weight / 4.0) vbytes ``` # Test Vectors