* 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
11 KiB
Peer Protocol for Contract Negotiation
Table of Contents
Contract
Definition of contract_id
Prior to a contract being accepted, a temporary_contract_id is used,
which is the SHA256 hash of the offer message.
Most messages use a contract_id to identify the contract. It's
derived from the funding transaction and the offer by combining the funding_txid
and the funding_output_index and the temporary_contract_id, using big-endian
exclusive-OR (i.e. funding_output_index alters the last 2 bytes of
funding_txid XOR temporary_contract_id).
Contract Negotiation
Contract Negotiation consists of the initiator (aka offerer) sending an offer_dlc message,
followed by the responding node (aka accepter) sending accept_dlc. With the
contract parameters locked in, both parties are able to create the funding
transaction and subsequently all contract execution transactions (CETs) and the refund transaction, as described in the transaction specification. As such, the accepter includes its signatures of the CETs and refund transaction in the accept_dlc message.
The initiator is now able to generate signatures for all CETs and the refund transaction, as well as the funding transaction, and send them over using the sign_dlc message.
Once the accepter receives the sign_dlc message, it
must broadcast the funding transaction to the Bitcoin network.
+-------+ +-------+
| | | |
| |---- (1) offer --->| |
| | | |
| |<--- (2) accept ----| |
| A | | B |
| |---- (3) sign --->| |
| | | |
| | | (4) broadcast fund-tx
| | | |
+-------+ +-------+
- where node A is 'offerer' and node B is 'accepter'
If this fails at any stage, or if one node decides the contract terms offered by the other node are not suitable, the contract negotiation fails.
Note that multiple contracts can be open in parallel, as all DLC
messages are identified by either a temporary_contract_id (before the
funding transaction is created) or a contract_id (derived from the
funding transaction).
The offer_dlc Message
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.
- type: 42778 (
offer_dlc_v0) - data:
- [
byte:contract_flags] - [
chain_hash:chain_hash] - [
contract_info:contract_info] - [
oracle_info:oracle_info] - [
point:funding_pubkey] - [
spk:payout_spk] - [
u64:total_collateral_satoshis] - [
u16:num_funding_inputs] - [
num_funding_inputs*funding_input:funding_inputs] - [
spk:change_spk] - [
u64:feerate_per_vb] - [
u32:contract_maturity_bound] - [
u32:contract_timeout]
- [
No bits of contract_flags are currently defined, this field should be ignored.
The chain_hash value denotes the exact blockchain that the DLC will
reside within. This is usually the genesis hash of the respective blockchain.
The existence of the chain_hash allows nodes to open contracts
across many distinct blockchains as well as have contracts within multiple
blockchains opened to the same peer (if it supports the target chains).
contract_info specifies the sender's payouts for all events. oracle_info
specifies the oracle(s) to be used as well as their commitments to events.
funding_pubkey is the public key in the 2-of-2 multisig script of
the funding transaction output. payout_spk specifies the script
pubkey that CETs and the refund transaction should use in the sender's output.
total_collateral_satoshis is the amount the sender is putting into the
contract. num_funding_inputs is the number of funding inputs contributed by
the sender and funding_inputs contains outputs, outpoints, and expected weights
of the sender's funding inputs. change_spk specifies the script pubkey that funding
change should be sent to.
feerate_per_vb indicates the fee rate in satoshi per virtual byte that both
sides will use to compute fees in the funding transaction, as described in the
transaction specification.
contract_maturity_bound is the nLockTime to be put on CETs. contract_timeout is the nLockTime to be put on the refund transaction.
Requirements
The sending node MUST:
- set undefined bits in
contract_flagsto 0. - ensure the
chain_hashvalue identifies the chain it wishes to open the contract within. - set
funding_pubkeyto a valid secp256k1 pubkey in compressed format. - set
total_collateral_satoshisto a value greater than or equal to 1000. - set
contract_maturity_boundandcontract_timeoutto either both be UNIX timestamps, or both be block heights as distinguished here. - set
contract_maturity_boundto be less thancontract_timeout.
The sending node SHOULD:
- set
feerate_per_vbto at least the rate it estimates would cause the transaction to be immediately included in a block. - set
contract_maturity_boundto no later than the earliest expected oracle signature time. - set
contract_timeoutsufficiently long after the latest possible oracle signature added to all other delays to closing the contract. - set
payout_spkto a previously unused script public key. - set
change_spkto a previously unused script public key.
The receiving node MUST:
- ignore undefined bits in
contract_flags.
The receiving node MAY reject the contract if:
- it does not agree to the terms in
contract_info. - the
contract_infois missing relevant events. - it does not want to use the oracle(s) specified in
oracle_info. total_collateral_satoshisis too small.feerate_per_vbis too small.feerate_per_vbis too large.
The receiving node MUST reject the contract if:
- the
chain_hashvalue is set to a hash of a chain that is unknown to the receiver. - the
contract_inforefers to events unknown to the receiver. - the
oracle_inforefers to an oracle unknown or inaccessible to the receiver. - it considers
feerate_per_vbtoo small for timely processing or unreasonably large. funding_pubkeyis not a valid secp256k1 pubkey in compressed format.funding_inputsdo not contribute at leasttotal_collateral_satohisplus full fee payment.
The accept_dlc Message
This message contains information about a node and indicates its 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.
- type: 42780 (
accept_dlc_v0) - data:
- [
32*byte:temporary_contract_id] - [
u64:total_collateral_satoshis] - [
point:funding_pubkey] - [
spk:payout_spk] - [
u16:num_funding_inputs] - [
num_funding_inputs*funding_input:funding_inputs] - [
spk:change_spk] - [
cet_adaptor_signatures:cet_adaptor_signatures] - [
signature:refund_signature]
- [
Requirements
The temporary_contract_id MUST be the SHA256 hash of the offer_dlc message.
The sender MUST:
- set
total_collateral_satoshissufficiently large so that the sum of both parties' total collaterals is at least as large as the largest payout in theoffer_dlc'scontract_info. - set
cet_adaptor_signaturesto valid adaptor signatures, using itsfunding_pubkeyfor each CET, as defined in the transaction specification and using signature public keys computed using theoffer_dlc'scontract_infoandoracle_infoas adaptor points. - include an adaptor signature in
cet_adaptor_signaturesfor every event specified in theoffer_dlc'scontract_info. - set
refund_signatureto the valid signature, using itsfunding_pubkeyfor the refund transaction, as defined in the transaction specification.
The sender SHOULD:
- set
payout_spkto a previously unused script public key. - set
change_spkto a previously unused script public key.
The receiver:
- if
total_collateral_satoshisis not large enough:- MAY reject the contract.
- if
cet_adaptor_signaturesorrefund_signaturefail validation:- MUST reject the contract.
- if
funding_inputsdo not contribute at leasttotal_collateral_satohisplus fee payment- MUST reject the contract.
Other fields have the same requirements as their counterparts in offer_dlc.
The sign_dlc Message
This message gives all of the initiator's signatures, which allows the receiver to broadcast the funding transaction with both parties being fully committed to all closing transactions.
This message introduces the contract_id to identify the contract.
- type: 42782 (
sign_dlc_v0) - data:
- [
contract_id:contract_id] - [
cet_adaptor_signatures:cet_adaptor_signatures] - [
signature:refund_signature] - [
funding_signatures:funding_signatures]
- [
Requirements
The sender MUST:
- set
contract_idby exclusive-OR of thefunding_txidand thefunding_output_indexfrom theoffer_dlcandaccept_dlcmessages. - set
cet_adaptor_signaturesto valid adaptor signatures, using itsfunding_pubkeyfor each CET, as defined in the transaction specification and using signature public keys computed using theoffer_dlc'scontract_infoandoracle_infoas adaptor points. - include an adaptor signature in
cet_adaptor_signaturesfor every event specified in theoffer_dlc'scontract_info. - set
refund_signatureto the valid signature, using itsfunding_pubkeyfor the refund transaction, as defined in the transaction specification. - set
funding_signaturesto contain valid witnesses for every funding input specified in theoffer_dlcmessage and in the same order.
The recipient:
- if any
signatureorwitnessis incorrect:- MUST reject the contract.
- if any witness exceeds its corresponding
max_witness_lenfrom theoffer_dlcmessage:- 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.
Authors
Nadav Kohen nadavk25@gmail.com
[ FIXME: Add Authors ]
This work is licensed under a Creative Commons Attribution 4.0 International License.