Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed v0 DLC TLV messages and Deterministic Fee Computation #81

Merged
merged 16 commits into from
Sep 29, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 111 additions & 6 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 Down Expand Up @@ -44,20 +55,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)
Tibo-lg marked this conversation as resolved.
Show resolved Hide resolved
* `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
* `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`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it's temporary can you assign them in the LN's messages waiting rooms : lightning/bolts#716 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll wait a while longer on this until we are sure we will actually be using LN message format long-term (e.g. does #96 work as an approach) before adding to here but I will do so if it becomes clear we won't be using an incompatible variant.

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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A side-note, we should make mandatory in the Oracle spec-side to verify public key ownership to avoid someone impersonating the oracle and thus blocking the state of your contract.

Though I don't know the state of oracle discovery, if we rely on common public key infrastructure.

cc @LLFourn

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#97

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A side-note, we should make mandatory in the Oracle spec-side to verify public key ownership to avoid someone impersonating the oracle and thus blocking the state of your contract.

I didn't understand what this meant. How can you impersonate the oracle?
Note I made a comment here: #61 about how I don't think it makes sense to send oracle_nonce. If you do you the oracle must sign it along with the event data it is associated with. Perhaps this is what you are getting at.


### 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`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite confusing, in contract_info_v0 we have a single TLV record for many outcomes. Here we have one TLV record for each input.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because contract information follows a uniform type (all outcomes fall under the same version, and if they don't a future version will have separate TLV records) whereas different inputs are independent (e.g. taproot input could be funding_input_v1 and not have prev_tx at the same time as another input is v0)

2. data:
* [`u16`:`prevtx_len`]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in theory not needed, as a parser knows how big is a transaction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is to allow clients which don't have transaction parser to make external calls to one after having parsed the transaction. Regardless of why I have made this record as close to this as possible: https://github.com/niftynei/lightning-rfc/pull/1/files#diff-3369c5aa1774fef2ff1e246979f223eaR169

* [`prevtx_len*byte`:`prevtx`]
* [`u32`:`prevtx_vout`]
* [`u32`:`sequence`]
* [`u16`:`max_witness_len`]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing the script field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what you are referring to? If you're talking about p2sh that is the redeem script below and if not then you definitely must not include a witness script when giving your funding input as funding signatures must be delayed until after CET signatures are received.

Copy link

@NicolasDorier NicolasDorier Sep 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, I don't understand the purpose of max_witness_len.
I can see what it is, but why is it needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For deterministic fee computation

* [`u16`:`redeemscript_len`]
nkohen marked this conversation as resolved.
Show resolved Hide resolved
* [`redeemscript_len*byte`:`script`]

`prevtx_tx` is the serialized transaction whose `prevtx_vout` output is being spent.
Copy link

@NicolasDorier NicolasDorier Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a deal breaker for me.

In BTCPay Server, we don't have the prevtx, because if the user restored his wallet, it is through scantxoutsetinfo and we work on pruned node, so no way to get back this data.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this requirement can be dropped, because the signatures already cover the input value (it's a segwit feature).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well it was not needed in the non-TLV version of the spec, why has it been added?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a receiver you have to verify that announced inputs aren't malleable ones, how do you combine this with pruning mode ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@devrandom it covers your own input value but not the others https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#specification

If you don't include the full prev tx they can give you a valid txid pointing to a non-segwit address and convince you it is segwit (because you're trusting them by not requiring the full prevtx) once you sign the funding tx, they can include a script signature you weren't expecting, your signatures are still valid but the txid changes and all CETs and refund tx become invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh and I think I misunderstood, if I now understand correctly, with this new versioned approach you should be able to be trustless if your counter-party accepts txid+vout instead of prevtx (if they are a full node for example) as the issue for you is getting your own prevtx, not validating the counter party's if you are given a prevtx right?

Copy link

@NicolasDorier NicolasDorier Sep 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nkohen so I searched a bit:

  • Bitcoin core is including previous transaction when creating a new PSBT for the wallet since 0.20.1. (latest version)
  • So I swtiched BTCPay Server to mirror the same behavior by default. Sadly, this won't work for restored wallet.

as the issue for you is getting your own prevtx, not validating the counter party's if you are given a prevtx right?

Correct.

Stepping back a bit, I think the best reason for allowing witness_utxo in the protocol, is not about making it easier for wallets with the full utxo set. But to prepare taproot. Once we have taproot, the non_witness_utxo won't be needed in any case. So I think it makes sense to allow it in the protocol for this reason.
On my side, my implementation of this protocol I would allow witness_utxo even for segwit v0 as we have the utxo set, but still try to add non_witness_utxo, if possible, to offer/accept.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great news :) Lmk if there's anything I can do to help. And also to clarify, you're cool with moving forward with prevtx and adding a non-prevtx version in the near future (potentially the subsequent PR to this one)?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, seems good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#98

The transaction is used to validate this output's value and to validate that it is a SegWit output.
nkohen marked this conversation as resolved.
Show resolved Hide resolved

`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`.

`script` is the script signature field for the input. Only applicable for P2SH-wrapped inputs.
The length of the script should not be included in the transmitted script data.

### 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`)
Tibo-lg marked this conversation as resolved.
Show resolved Hide resolved
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Christewart Can we tag as a V0.2 to reject malleable witness scripts ? I don't think Miniscript compilers have the interface yet but that something to consider in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, I'm not sure this is a feasible constraint seeing as one party never sees the other's witnesses before they see them on-chain. Is there any reason witness malleability is an issue in this context as it doesn't invalidate future txs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes witness malleability is a pinning vector and as such you can prevent confirmation of the funding transaction and escape the contract in case of non-favorable outcome.

In theory you can parse a witnessScript and decide if a solving witness is malleable. But as pointed IIRC Miniscript isn't supporting this.


## 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
82 changes: 51 additions & 31 deletions Transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,52 +108,67 @@ 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.

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
Funding Transaction weight: 214 + (72 + 4*total_change_length)
+ sum(164 + 4*script_sig_len + max_witness_len)
CET/Refund Transaction weight: 500 + 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 = 250 + 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.
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -282,6 +296,12 @@ cet_weight = 4 * cet
witness_weight = witness_header + witness

overall_cet_weight = overall_refund_tx_weight = 500 + 4 * total_output_length weight

offer_cet_weight = 250 + 4 * offer_output_script_length weight
offer_cet_vbytes = Ceil(offer_cet_weight / 4.0) vbytes

accept_cet_weight = 250 + 4 * accept_output_script_length weight
accept_cet_vbytes = Ceil(accept_cet_weight / 4.0) vbytes
```

# Test Vectors
Expand Down
Loading