Rewording and Renaming clean-up (#142)

Responded to review

Cleaned up a couple sentences
This commit is contained in:
Nadav Kohen
2021-02-24 00:51:44 -06:00
committed by GitHub
parent 48ea01bc5e
commit 898e81a23c
7 changed files with 158 additions and 157 deletions

View File

@@ -71,33 +71,35 @@ announcement and `s(1..m)` is sufficient information to generate a fraud proof i
## CET Compression ## CET Compression
Anytime there is a range of numeric outcomes `[start, end]` which result in the same payouts for all parties, Anytime there is an interval of numeric outcomes `[start, end]` (inclusive) which result in the same payouts for all parties,
then a compression function described in this section can be run to reduce the number of CETs from `O(L)` to `O(log(L))` then a compression function described in this section can be run to reduce the number of CETs from `O(L)` to `O(log(L))`
where `L = end - start + 1` is the length of the interval being compressed. where `L = end - start + 1` is the length of the interval of outcomes being compressed.
Because this compression of CETs only works for intervals which result in the same payout, the [CET calculation algorithm](NumericOutcome.md#contract-execution-transaction-calculation) Because this compression of CETs only works for intervals with constant payouts, the [CET calculation algorithm](NumericOutcome.md#contract-execution-transaction-calculation)
first splits the domain into buckets of equal payout, and then applies the compression algorithm from this first splits the domain into intervals of equal payout, and then applies the compression algorithm from this
document to individual intervals, `[start, end]` where all values in this interval have some fixed payout. document to the individual intervals, `[start, end]` where all values in each interval have some fixed payout.
Most contracts are expected to be concerned with some subset of the total possible domain and every Most contracts are expected to be concerned with some subset of the total possible domain and every
outcome before or after that range will result in some constant maximal or minimal payout. outcome before or after that likely subset will result in some constant maximal or minimal payout.
This means that compression will drastically reduce the number of CETs to be of the order of the size This means that compression will drastically reduce the number of CETs to be of the order of the size
of the probable domain, with further optimizations available when parties are willing to do some [rounding](NumericOutcome.md#rounding-intervals). of the probable domain, with further optimizations available when parties are willing to do some [rounding](NumericOutcome.md#rounding-intervals).
The compression algorithm takes as input a range `[start, end]`, a base `B`, and the number of digits The compression algorithm takes as input an interval `[start, end]`, a base `B`, and the number of digits
`n` (being signed by the oracle) and returns an array of arrays of integers (which will all be in the range `[0, B-1]`). `n` (being signed by the oracle) and returns a list of digit prefixes serialized as an array of arrays of integers
An array of integers corresponds to a single event equal to the concatenation of these integers (interpreted in base `B`). (which will all be in the range `[0, B-1]`).
An array of integers represents a digit prefix corresponding to a single event equal to the concatenation of
these integers (interpreted in base `B`) where all digits not used may be any value.
### Concrete Example ### Concrete Example
Before generalizing or specifying the algorithm, let us run through a concrete example. Before generalizing or specifying the algorithm, let us run through a concrete example.
We will consider the range `[135677, 138621]`, in base `10`. We will consider the interval `[135677, 138621]`, in base `10`.
Note that they both begin with the prefix `13` which must be included in every CET, for this purpose I omit these digits for Note that the `start` and `end` both begin with the prefix `13` which must be included in every digit prefix, for this purpose we will omit these digits for
the remainder of this example as we can simply examine the range `[5677, 8621]` and prepend a `13` to all results. the remainder of this example as we can simply examine the interval `[5677, 8621]` and prepend a `13` to all results to get a result for our original interval.
To cover all cases while looking at as few digits as possible in this range we need only consider To cover all cases while looking at as few digits as possible in this interval we need only consider
`5677`, `8621` and the following cases: `5677`, `8621` individually in addition to the following cases:
``` ```
5678, 5679, 5678, 5679,
@@ -111,12 +113,13 @@ To cover all cases while looking at as few digits as possible in this range we n
8620 8620
``` ```
where `_` refers to an ignored digit (an omission from the array of integers). where `_` refers to an ignored digit (an omission from the array of integers representing the digit prefix).
(Recall that all of these are prefixed by `13`). (Recall that all of these are prefixed by `13`).
Each of these digit prefixes can be used to construct a single CET.
Thus, we are able to cover the entire interval of `2944` outcomes using only `20` CETs! Thus, we are able to cover the entire interval of `2944` outcomes using only `20` CETs!
Here it is again in binary (specifically the range `[5677, 8621]`, not the original range with the `13` prefix in base 10): Let us reconsider this example in binary (specifically the interval `[5677, 8621]`, not the original interval with the `13` prefix in base 10):
Outliers are `5677 = 01011000101101` and `8621 = 10000110101101` with cases: The individual outliers are `5677 = 01011000101101` and `8621 = 10000110101101` with cases:
``` ```
0101100010111_, 0101100010111_,
@@ -134,7 +137,7 @@ Outliers are `5677 = 01011000101101` and `8621 = 10000110101101` with cases:
10000110101100 10000110101100
``` ```
And so again we are able to cover the entire interval of `2944` outcomes using only `14` CETs this time. And so again we are able to cover the entire interval (of `2944` outcomes) using only `14` CETs this time.
### Abstract Example ### Abstract Example
@@ -145,7 +148,7 @@ Consider the range `[(prefix)wxyz, (prefix)WXYZ]` where `prefix` is some string
are the unique digits of `end` in base `B`. are the unique digits of `end` in base `B`.
To cover all cases while looking at as few digits as possible in this (general) range we need only consider To cover all cases while looking at as few digits as possible in this (general) range we need only consider
`(prefix)wxyz`, `(prefix)WXYZ` and the following cases: `(prefix)wxyz`, `(prefix)WXYZ` independently along with the following cases:
``` ```
wxy(z+1), wxy(z+2), ..., wxy(B-1), wxy(z+1), wxy(z+2), ..., wxy(B-1),
@@ -175,11 +178,11 @@ That is to say, `B-1` minus the last digit is the number of elements in the firs
Likewise the number of elements in each row of the back groupings is equal to the corresponding digit. Likewise the number of elements in each row of the back groupings is equal to the corresponding digit.
That is to say, the last digit corresponds to the last row, second to last digit is the second to last row and so on. That is to say, the last digit corresponds to the last row, second to last digit is the second to last row and so on.
This covers all but the first digit of both `start` and `end` (as well as the two outliers `wxyz` and `WXYZ`). This covers all but the first digit of both `start` and `end` (as well as the two outliers `wxyz` and `WXYZ`).
Thus the total number of CETs required to cover the range will be equal to the sum of the unique digits of `end` except the first, Thus the total number of CETs required to cover the interval will be equal to the sum of the unique digits of `end` except the first,
plus the sum of the unique digits of `start` except for the first subtracted from `B-1` plus the difference of the first digits plus one. plus the sum of the unique digits of `start` except for the first subtracted from `B-1` plus the difference of the first digits plus one.
A corollary of this is that the number of CETs required to cover a range of length `L` will be `O(B*log_B(L))` because `log_B(L)` A corollary of this is that the number of CETs required to cover an interval of length `L` will be `O(B*log_B(L))` because `log_B(L)`
corresponds to the number of unique digits between the start and end of the range and for each unique digit a row is corresponds to the number of unique digits between the start and end of the interval and for each unique digit a row is
generated in both the front and back groupings of length at most `B-1 ` which corresponds to the coefficient in the order bound. generated in both the front and back groupings of length at most `B-1 ` which corresponds to the coefficient in the order bound.
This counting also shows us that base 2 is the optimal base to be using in general cases as it will, in general, outperform all larger bases This counting also shows us that base 2 is the optimal base to be using in general cases as it will, in general, outperform all larger bases
@@ -187,8 +190,8 @@ in both large and small intervals.
Note that the concrete example above was chosen to be easy to write down in base 10 (large digits in `start`, small digits in `end`) and so it should not Note that the concrete example above was chosen to be easy to write down in base 10 (large digits in `start`, small digits in `end`) and so it should not
be thought of as a general candidate for this particular consideration. be thought of as a general candidate for this particular consideration.
To help with intuition on this matter, consider an arbitrary range of three digit numbers in base 10. To help with intuition on this matter, consider an arbitrary interval of three digit numbers in base 10.
To capture the same range in base 2 we need 10 digit binary numbers. To capture the same interval in base 2 we need 10 digit binary numbers.
However, a random three digit number in base 10 is expected to have a digit sum of 15, while a random ten digit binary number expects a digit sum of only 5! However, a random three digit number in base 10 is expected to have a digit sum of 15, while a random ten digit binary number expects a digit sum of only 5!
Thus we should expect base 2 to outperform base 10 by around 3x on average. Thus we should expect base 2 to outperform base 10 by around 3x on average.
This is because using binary results in a compression where each row in the diagram above has only a single element, which corresponds This is because using binary results in a compression where each row in the diagram above has only a single element, which corresponds
@@ -208,7 +211,7 @@ resulting in some number near 3.3 times fewer CETs on average.
Because `start` and `end` are outliers to the general grouping pattern, there are optimizations that could potentially be made when they are added. Because `start` and `end` are outliers to the general grouping pattern, there are optimizations that could potentially be made when they are added.
Consider the example in base 10 of the range `[2200, 4999]` which has the endpoints `2200` and `4999` along with the groupings Consider the example in base 10 of the interval `[2200, 4999]` which has the endpoints `2200` and `4999` along with the groupings
``` ```
2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209,
@@ -222,7 +225,7 @@ Consider the example in base 10 of the range `[2200, 4999]` which has the endpoi
4990, 4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998 4990, 4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998
``` ```
This grouping pattern captures the exclusive range `(2200, 4999)` and then adds the endpoints in ad-hoc to get the inclusive range `[2200, 4999]`. This grouping pattern captures the exclusive interval `(2200, 4999)` and then adds the endpoints in ad-hoc to get the inclusive range `[2200, 4999]`.
But this method misses out on a good amount of compression as re-introducing the endpoints allows us to replace the first two rows with But this method misses out on a good amount of compression as re-introducing the endpoints allows us to replace the first two rows with
a single `22__` and the last 3 rows with just `4___`. a single `22__` and the last 3 rows with just `4___`.
@@ -334,7 +337,7 @@ def middleGrouping(
} }
``` ```
Finally we are able to use all of these pieces to compress a range to an approximately minimal number of outcomes (by ignoring digits). Finally we are able to use all of these pieces to compress an interval to an approximately minimal number of outcomes (by ignoring digits).
```scala ```scala
def groupByIgnoringDigits(start: Long, end: Long, base: Int, numDigits: Int): Vector[Vector[Int]] = { def groupByIgnoringDigits(start: Long, end: Long, base: Int, numDigits: Int): Vector[Vector[Int]] = {

View File

@@ -11,115 +11,111 @@
## Abstract ## Abstract
DLC allows two parties to conduct stateful bitcoin contracts by giving each DLCs allow two parties to conduct stateful bitcoin contracts by giving each
of the parties *cross-signed range of CET transactions*. These CETs transactions other a *counter-signed set of CETs*.
are all spending the same output from a funding transaction and thus only one of These CETs all spend the same output from a funding transaction and thus only one
CET can confirm. A CET is finalized according to the outcome signed by the previously CET can be confirmed.
selected oracle. A single CET is finalized when an outcome is signed by a previously chosen set of oracles.
As the contract is established once funding transaction signatures have been exchanged, The contract is established once funding transaction signatures have been exchanged.
from then a party should assume counterparty non-cooperation and ensure either From that point on each party should assume their counter-party is non-cooperative and should ensure either
confirmation of the funding or double-spend of its collatral inputs to avoid exploitation. confirmation of the funding transaction or else double-spend its collateral inputs to avoid exploitation.
Once funding transaction signatures are exchanged, DLC parties aren't required Once funding transaction signatures are exchanged, DLC parties aren't required to interact anymore.
to interact anymore. They are three scenarios to consider: There are three scenarios to consider:
1. The funding transaction doesn't confirm, a party must either bump its feerate 1. The funding transaction doesn't confirm, and so a party must either bump its fee-rate to confirm
to confirm before DLC maturing or double-spend its funding collateral, thus cancelling the before the earliest DLC maturation or else double-spend its funding collateral canceling the DLC.
DLC. * Child Pays For Parent (CPFP) with BIP 125 Replace by Fee (RBF) enabled is used for fee bumping.
2. The funding transaction confirms, and the oracle releases the outcome signature, so a
2. The funding transaction confirms, the oracle releases the outcome signature, a participant must broadcast the CET corresponding to the oracle outcome.
participant must broadcast the DLC transaction paired with the outcome. 3. The funding transaction confirms, and the oracle doesn't release an outcome signature
before the `refund_locktime`, so a party must broadcast the refund transaction.
3. The funding transaction confirms, oracle doesn't release the outcome signature, independently
of counterparty behavior, the party must broadcast the refund transaction after its timelock
expiration.
# General Requirements # General Requirements
A DLC client should have censorship-resistant access to the blockchain, use a A DLC client should have censorship-resistant access to the blockchain, use a
local fee-estimator and ensure it's well-connected to the tx-relay network. local fee-estimator and ensure it is well-connected to the tx-relay network.
We recommend to not react on any mempool event as otherwise it would be a source of We recommend that clients should register no callbacks on mempool events as doing so may be a source of
cross-layer mapping. <sup>[Cross-layer Mapping](https://arxiv.org/pdf/2007.00764.pdf)</sup> cross-layer mapping. <sup>[Cross-layer Mapping](https://arxiv.org/pdf/2007.00764.pdf)</sup>
We recommend to not produce local non-adaptor signatures for transaction until their broadcast We recommend that clients should not produce local (non-adaptor) signatures for CETs until they are about
is required to avoid their misuage in case of site compromise, assuming an external signer. to be broadcast in order to avoid their misuse in case of site compromise, assuming an external signer.
Further, we recommend duplicate backups of counterparty signatures to avoid relying on Furthermore, we recommend duplicated backups of counter-party signatures be stored to avoid relying on
counterparty honest behavior in case of primary storage failure. honest counter-party behavior in the case of primary storage failure.
Transaction finalization is not implying a mandatory key material access.[ FIXME: Client Key Management. ] Transaction finalization does not imply a mandatory key material access. [ FIXME: Client Key Management. ]
# Fee bumping policy # Fee bumping policy
An onchain state machine must take actions based on different timers parameterized by three A state machine following on-chain events must take actions based on different clocks parameterized by three
values: `congestion_bump_frequency`/`security_bump_frequency`/`security_point`/`refund_security_point`. values: `congestion_bump_frequency`/`security_bump_frequency`/`funding_security_point`/`refund_security_point`.
Their definition and setting recommendations are laid out in this section, their usage is precised These values' definitions and setting recommendations are laid out in this section and their usage is made
in following sections. more precise in following sections.
A `security_point` is a client heuristic after which the confirmation of the funding transaction A `security_point` is a client-side heuristic time/block-stamp after which the confirmation of a corresponding
is a matter of contract safety, otherwise the user is exposed to a bad-player double-spend if either transaction is a matter of contract safety.
the outcome odds are modified or a signature oracle is released. This point is function of event If confirmation does not occur soon after this point, the user can be vulnerable to a malicious double-spend if either
signing time, which may be static or dynamic, we defer point qualification to client. the outcome odds change or an oracle signature is released.
The `funding_security_point` is determined as a function of the earliest possible event signing time, which may be static or dynamic.
The `refund_security_point` is determined as a function of the user's trust towards the oracle.
We defer the exact determination of `security_point`s to the client.
If the signing time is static (block height, epoch) or predictable we recommend setting the If the `security_point` time is static (block height, epoch) or predictable, we recommend setting
`security_point` with a confirmation buffer of 20 blocks compared to signing time. `security_point`s to have a confirmation buffer of 20 blocks from that time.
The `refund_security_point` is a client heuristic after which the confirmation of the refund A client's `congestion_bump_frequency`/`security_bump_frequency` can be scheduled on at least three
transaction is a matter of contract safety, otherwise the user is exposed to a malicious CET spend different kinds of events:
if the oracle key material is compromised. This point is function of the level of trust in the
oracle, we defer point qualification to client.
Client's `congestion_bump_frequency`/`security_bump_frequency` can be scheduled at least on three different basis:
- a block height - a block height
- a local clock - a local clock
- an observed feerate fluctuation - an observed fee-rate fluctuation
Note, these criterias might be observable by an adversary and we recommend to implementations Note that these criteria may be observable by an adversary and we recommend for implementations
to pad any criteria with a random delay to diminish risks of tx-relay jamming. to pad any criteria with a random delay to diminish the risks of tx-relay jamming.
We don't provide recommendations for the `congestion delay` as its settings depends of user We don't provide recommendations for the `congestion_bump_frequency` as its settings depends on user
liquidity preferences and available local data to predict the feerate. Confirmation of non liquidity preferences and the availability of local data to predict the fee-rate.
time-sensitive transactions should happen but a user may prefer to delay them in case of Confirmation of non-time-sensitive transactions should happen eventually, but a user may prefer to delay
mempool-congestion. confirmation in the case of mempool-congestion.
We provide recommendations for the `security_bump_frequency` as any transaction under this fee-bumping We recommend a `security_bump_frequency` of 1 block, preferably with a fast-confirmation fee-rate as reported
policy has a time-sensitive confirmation. A delay of 1 block and a fast-confirmation feerate by a fee-estimator if possible.
as reported by fee-estimator should be preferred. This recommendation is made because any transaction under this fee-bumping policy has a time-sensitive confirmation.
Dividing the fee-bumping occurence between different frequencies avoid a client overpaying in Having different fee-bumping frequencies for congestion and security avoids a client overpaying in
fees in case of mempool spikes, while anticipating that at some point during DLC execution, the fees in the case of mempool spikes, while anticipating that at some point during DLC execution, the
confirmation of the funding is a security concern. confirmation of certain transactions is a security concern.
# Funding Phase # Funding Phase
A party always starts the protocol in the funding phase. The funding phase can A DLC participant always begins the protocol in the funding phase.
terminate by either a transition to the execution phase or a protocol abort. The funding phase can terminate either to the execution phase by a transition to the execution phase or to an abort.
## Requirements ## Requirements
A node: A node:
- if a counterparty's funding signature is received: - if all counter-party CET and funding signatures are received:
- MUST finalize the funding transaction with a local `SIGHASH_ALL` signatures - MUST finalize the funding transaction with a local `SIGHASH_ALL` signatures
- MUST broadcast the funding transaction - MUST broadcast the funding transaction
- MUST start a fee-bumping timer of length `congestion_bump_frequency`
A node: A node:
- if a funding signature has been sent or a funding transaction broadcast and there is no confirmation after 6 blocks: - if a funding signature has been sent or a funding transaction broadcast and there is no confirmation:
- MUST spend the change output with a CPFP increasing package feerate to shorten confirmation time
- MUST start a fee-bumping timer of length `congestion_bump_frequency`
- if `congestion_bump_frequency` expires: - if `congestion_bump_frequency` expires:
- MUST spend the change output with a CPFP increasing package feerate to shorten confirmation time - MUST spend the change output with a CPFP increasing package fee-rate to shorten confirmation time
- MUST replace the CPFP transaction according to BIP 125 - MUST replace the CPFP transaction according to BIP 125
- MUST reschedule timer for next bump - MUST reschedule timer for next bump
- if `security_point` is reached: - if `funding_security_point` is reached:
- MUST spend a funding input with a higher-feerate transaction/absolute fee than any previously propagated package feerate - MUST spend a funding input with a higher-fee-rate transaction/absolute fee than any previously propagated package fee-rate
- MUST start a fee-bumping timer of length `security_bump_frequency` - MUST start a fee-bumping timer of length `security_bump_frequency`
- MUST disable `congestion_bump_frequency` timer - MUST disable `congestion_bump_frequency` timer
- if `security_bump_frequency` expires: - if `security_bump_frequency` expires:
- MUST spend a funding input with a higher-feerate transaction/absolute fee than any previously propagated package feerate - MUST spend a funding input with a higher-fee-rate transaction/absolute fee than any previously propagated package fee-rate
- MUST replace the CPFP transaction according to BIP 125 - MUST replace the CPFP transaction according to BIP 125
- MUST reschedule timer for next bump - MUST reschedule timer for next bump
- MUST NOT spend more in bumping fees than its collateral input value - MUST NOT spend more in bumping fees than its collateral input value
@@ -130,37 +126,39 @@ A node:
- if the funding transaction confirms: - if the funding transaction confirms:
- MUST track spend of the funding output - MUST track spend of the funding output
- MUST advances its off-chain state to the execution phase - MUST advance its off-chain state to the execution phase
- MUST note its change output for later spend - MUST note its change output for later spend
A node: A node:
- if the funding input double-spend confirms: - if a counter-party funding input double-spend confirms:
- MUST abort the DLC and prevent further interactions with counterparty - MUST abort the DLC and prevent further interactions with that counter-party
## Rationale ## Rationale
Funding transaction must be confirmed to consider the off-chain state initialized. As mempools The funding transaction must be confirmed to consider the off-chain state initialized.
congestion may fluctuate between fees negotiation and transaction propagation, party must adjust As mempool congestion may fluctuate between fee negotiation and transaction propagation, parties
unilaterally the package feerate (CPFP) according to their confirmation preferences. A party may must unilaterally adjust the package fee-rate (using CPFP) according to their confirmation preferences.
choose to wait for mempools draining before to adjust the feerate to avoid a fee waste as block A party may choose to wait for mempools to drain before adjusting the fee-rate to avoid over-paying in
height of transition to execution phase doesn't matter, assuming it's before `contract_maturity_bound`. fees seeing as the block height of a transition to the execution phase doesn't matter, so long as it's
before the earliest possible (expected) contract execution.
Reaching near `contract_maturity_bound` requires to confirm the funding transaction quickly as it's As the earliest possible (expected) contract execution approaches, the funding transaction must
now a security matter. After oracle signature release, a malicious party could try to double-spend be confirmed quickly as a matter of security.
an unconfirmed funding transaction to avoid losing its collateral, and thus without assuming deceitful After the oracle releases a signature, a malicious party could try to double-spend an unconfirmed funding
cooperation with the oracle. transaction to avoid losing their collateral without the use of deceitful cooperation with the oracle.
In case of counterparty funding input double-spend, cleaning offchain state reduce further exploitation In the case that a counter-party double-spends a funding input, cleaning off-chain state prevents
at this level. E.g a DLC implementation feeded with a _correct_ signature whereas the contract is further exploitation at this level.
invalid but still displaying an incorrect information to the user. A double-spending counterparty For example, a DLC implementation that has received _correct_ signatures but where the contract is
is also "breaking" the previously negotiated DLC and agreed by its signature exchange. Thus further invalid could still be displaying incorrect information to the user.
interactions should be warranted with this buggy/malicious peer. A double-spending counter-party is "breaking" the previously negotiated DLC that has been agreed to
by its signature exchange.
Thus further interactions should be avoided with this buggy/malicious peer.
# Execution Phase # Execution Phase
The execution phase transitions to the terminal phase either by a CET or a refund The execution phase transitions to the terminal phase by confirming either a CET or a refund transaction.
transaction confirmations.
## Requirements ## Requirements
@@ -169,44 +167,44 @@ A node:
- if an oracle signature is received: - if an oracle signature is received:
- MUST finalize the CET with a local `SIGHASH_ALL` signature - MUST finalize the CET with a local `SIGHASH_ALL` signature
- MUST broadcast the CET - MUST broadcast the CET
- MAY spend its outcome output with a CPFP increasing package feerate to shorten confirmation time - MAY spend its outcome output with a CPFP increasing package fee-rate to shorten confirmation time
- if the CET is not confirmed and `contract_timeout` is 20 blocks ahead of local tip: - if the CET is not confirmed and `refund_locktime` is 20 blocks ahead of local tip:
- MUST spend its outcome output with a CPFP increasing package fee-rate to shorten confirmation time
- MUST rebroadcast the CET - MUST rebroadcast the CET
- MUST spend its outcome output with a CPFP increasing package feerate to shorten confirmation time
- MUST start a fee-bumping timer of length `security_bump_frequency` - MUST start a fee-bumping timer of length `security_bump_frequency`
- if `security_bump_frequency` expires: - if `security_bump_frequency` expires:
- MUST spend the change output with a replacing CPFP increasing package feerate to shorten confirmation time - MUST spend the change output with a replacing CPFP increasing package fee-rate to shorten confirmation time
- MUST replace the CPFP transaction according to BIP 125 - MUST replace the CPFP transaction according to BIP 125
- MUST reschedule timer for next bump - MUST reschedule timer for next bump
- MUST NOT spend more in bumping fees than its outcome value - MUST NOT spend more in bumping fees than its outcome value
- MAY NOT spend more in bumping fees than its outcome value - refund value if oracle is trusted - MAY NOT spend more in bumping fees than its outcome value - refund value if the oracle is trusted
- if the outcome realization is unfavorable: - if the outcome realization is unfavorable:
- MAY disable CET fee-bumping - MAY disable CET fee-bumping
A node: A node:
- if a CET transaction confirms: - if a CET confirms:
- MUST note its outcome output for later spend - MUST note its outcome output for later spend
- MUST advances its off-chain state to terminal phase - MUST advance its off-chain state to the terminal phase
A node: A node:
- if no oracle signature has been received and `contract_timeout` is reached: - if no oracle signature has been received and `refund_locktime` is reached:
- MUST finalize the refund transaction with a local `SIGHASH_ALL` signature - MUST finalize the refund transaction with a local `SIGHASH_ALL` signature
- MUST broadcast the refund transaction - MUST broadcast the refund transaction
- if the refund is not confirmed after `congestion_bump_frequency`: - if the refund is not confirmed after `congestion_bump_frequency`:
- MUST spend the change output with a CPFP increasing package feerate to shorten confirmation time - MUST spend the change output with a CPFP increasing package fee-rate to shorten confirmation time
- MUST start a fee-bumping timer of length `refund_congestion_bump_frequency` - MUST start a fee-bumping timer of length `refund_congestion_bump_frequency`
- if `refund_congestion_bump_frequency` expires: - if `refund_congestion_bump_frequency` expires:
- MUST spend the change output with a replacing CPFP increasing package feerate to shorten confirmation time - MUST spend the change output with a replacing CPFP increasing package fee-rate to shorten confirmation time
- MUST replace the CPFP transaction according to BIP 125 - MUST replace the CPFP transaction according to BIP 125
- MUST reschedule timer for next bump - MUST reschedule timer for next bump
- if `refund_security_point` is reached: - if `refund_security_point` is reached:
- MUST spend a funding input with a higher-feerate transaction/absolute fee than any previously propagated package feerate - MUST spend a funding input with a higher-fee-rate transaction/absolute fee than any previously propagated package fee-rate
- MUST start a fee-bumping timer of length `security_bump_frequency` - MUST start a fee-bumping timer of length `security_bump_frequency`
- MUST disable `refund_congestion_bump_frequency` timer - MUST disable `refund_congestion_bump_frequency` timer
- if `security_bump_frequency` expires: - if `security_bump_frequency` expires:
- MUST spend a funding input with a higher-feerate transaction/absolute fee than any previously propagated package feerate - MUST spend a funding input with a higher-fee-rate transaction/absolute fee than any previously propagated package fee-rate
- MUST replace the CPFP transaction according to BIP 125 - MUST replace the CPFP transaction according to BIP 125
- MUST reschedule timer for next bump - MUST reschedule timer for next bump
@@ -214,18 +212,18 @@ A node:
- if a refund transaction confirms: - if a refund transaction confirms:
- MUST note its outcome output for later spend - MUST note its outcome output for later spend
- MUST advances its off-chain state to terminal phase - MUST advances its off-chain state to the terminal phase
## Rationale ## Rationale
Reaching near `contract_timeout` requires to confirm the valid CET quickly as it's now a security As `refund_locktime` approaches, a CET must be confirmed quickly as a matter of security.
matter. A malicious party could try to cancel a lost DLC by confirming the refund transaction. A malicious party could try to cancel an unfavorable DLC by confirming the refund transaction.
A refund transaction confirmation is less sensitive but it should noted that in the meanwhile A refund transaction confirmation is less sensitive but it should be noted that while participants are
the oracle key material is toxic, as in case of compromise, a CET could be signed and confirmed waiting for refund confirmations, the oracle key material is toxic.
by a malicious counterparty. This confirmation should be managed in function of the user trust In case of oracle key compromise, a CET could be signed and confirmed by a malicious counter-party.
towards the oracle. Refund transaction confirmation should be managed as a function of the user's trust towards the oracle.
# Reorgs # Reorgs

View File

@@ -43,8 +43,8 @@ when interacting with lowest-level core DLC logic.
## Rounding Intervals ## Rounding Intervals
As detailed in the [CET compression](CETCompression.md#cet-compression), any time some continuous interval of the domain results in the same payout value, we can As detailed in the [CET compression document](CETCompression.md#cet-compression), any time some continuous interval of the domain results in the same payout value,
compress the CETs required by that interval to be logarithmic in size compared to using one CET per outcome on that interval. we can compress the CETs required for that interval to be logarithmic in size compared to using one CET per outcome on the interval.
As such, it can be beneficial to round the outputs of the payout function to allow for bounded approximation of pieces of the payout As such, it can be beneficial to round the outputs of the payout function to allow for bounded approximation of pieces of the payout
curve by constant-payout intervals. curve by constant-payout intervals.
For example, if two parties are both willing to round payout values to the nearest 100 satoshis, they can have significant savings For example, if two parties are both willing to round payout values to the nearest 100 satoshis, they can have significant savings
@@ -91,11 +91,11 @@ If `begin_interval_1` is strictly greater than `0`, then the interval between `0
## Contract Execution Transaction Calculation ## Contract Execution Transaction Calculation
Given the offerrer's [payout function](PayoutCurve.md), a `total_collateral` amount and [rounding intervals](#rounding-intervals), we wish to compute a list of pairs Given the offerrer's [payout function](PayoutCurve.md), a `total_collateral` amount and [rounding intervals](#rounding-intervals), we wish to compute a list of pairs
of digits (i.e. arrays of integers) and Satoshi values. of digit prefixes (i.e. arrays of integers) and Satoshi values.
Each of these pairs will then be turned into a CET whose adaptor point is [computed from the list of integers](CETCompression.md#adaptor-points-with-multiple-signatures) and whose Each of these pairs will then be turned into a CET whose adaptor point is [computed from the digit prefix](CETCompression.md#adaptor-points-with-multiple-signatures) and whose
output values will be equal to the Satoshi payout and `total_collateral` minus that payout. output values will be equal to the Satoshi payout and `total_collateral` minus that payout.
We must first modify the pure function given to us (e.g. by interpolating points) by applying rounding, as well as setting all We must first modify the pure function given to us (e.g. by interpolating points) by applying rounding, and then setting all
negative payouts to `0` and all computed payouts above `total_collateral` to equal `total_collateral`. negative payouts to `0` and all computed payouts above `total_collateral` to equal `total_collateral`.
Next, we split the function's domain into two kinds of intervals: Next, we split the function's domain into two kinds of intervals:
@@ -109,10 +109,10 @@ There are countless ways to go about making this process more efficient such as
at the unmodified function's derivatives. at the unmodified function's derivatives.
Regardless of how these intervals are computed, it is required that the constant-valued intervals be as large as possible. Regardless of how these intervals are computed, it is required that the constant-valued intervals be as large as possible.
For example if you have two constant-valued intervals in a row with the same value, these must be merged. For example, if you have two constant-valued intervals in a row with the same value, these must be merged.
Finally, once these intervals have been computed, the [CET compression](CETCompression.md#cet-compression) algorithm is run on each constant-valued interval which generates Finally, once these intervals have been computed, the [CET compression](CETCompression.md#cet-compression) algorithm is run on each constant-valued interval which generates
a list of integers to be paired with the (constant) payout for that interval. a digit prefix (list of integers) to be paired with the (constant) payout for that interval.
For variable-payout intervals, a unique CET is constructed for every `event_outcome` where all digits of that `event_outcome` are included For variable-payout intervals, a unique CET is constructed for every `event_outcome` where all digits of that `event_outcome` are included
in the array of integers and the Satoshi payout is equal to the output of the modified function for that `event_outcome`. in the array of integers and the Satoshi payout is equal to the output of the modified function for that `event_outcome`.

View File

@@ -28,7 +28,7 @@ This necessary information is committed to in a so-called [_event descriptor_](#
## Event descriptor ## Event descriptor
An event descriptor provides information to clients about an event for which an oracle plans on releasing a signature over its outcome. An event descriptor provides information to clients about an event for which an oracle plans on releasing a signature over its outcome.
The provided information should be sufficient for a client to create a set of adaptors signatures for some CETs that will cover all possible outcomes of the event. The provided information should be sufficient for a client to create a set of adaptor signatures for some CETs that will cover all possible outcomes of the event.
Here we assume that an event outcome can be represented either as a set of strings or numbers. Here we assume that an event outcome can be represented either as a set of strings or numbers.
Two kinds of event outcomes are defined (note that a single event can be composed of several types). Two kinds of event outcomes are defined (note that a single event can be composed of several types).

View File

@@ -137,7 +137,7 @@ Given a potential `event_outcome` compute the `outcome_payout` as follows:
#### Reference Implementations #### Reference Implementations
* [bitcoin-s](https://github.com/bitcoin-s/bitcoin-s/blob/adaptor-dlc/core/src/main/scala/org/bitcoins/core/protocol/dlc/DLCPayoutCurve.scala#L324) * [bitcoin-s](https://github.com/bitcoin-s/bitcoin-s/blob/adaptor-dlc/core/src/main/scala/org/bitcoins/core/protocol/dlc/DLCPayoutCurve.scala#L365)
### Optimized Evaluation During CET Calculation ### Optimized Evaluation During CET Calculation

View File

@@ -72,15 +72,15 @@ the funding transaction and CETs.
* [`point`:`funding_pubkey`] * [`point`:`funding_pubkey`]
* [`spk`:`payout_spk`] * [`spk`:`payout_spk`]
* [`u64`:`payout_serial_id`] * [`u64`:`payout_serial_id`]
* [`u64`:`total_collateral_satoshis`] * [`u64`:`offer_collateral_satoshis`]
* [`u16`:`num_funding_inputs`] * [`u16`:`num_funding_inputs`]
* [`num_funding_inputs*funding_input`:`funding_inputs`] * [`num_funding_inputs*funding_input`:`funding_inputs`]
* [`spk`:`change_spk`] * [`spk`:`change_spk`]
* [`u64`:`change_serial_id`] * [`u64`:`change_serial_id`]
* [`u64`:`fund_output_serial_id`] * [`u64`:`fund_output_serial_id`]
* [`u64`:`feerate_per_vb`] * [`u64`:`feerate_per_vb`]
* [`u32`:`contract_maturity_bound`] * [`u32`:`cet_locktime`]
* [`u32`:`contract_timeout`] * [`u32`:`refund_locktime`]
No bits of `contract_flags` are currently defined, this field should be ignored. No bits of `contract_flags` are currently defined, this field should be ignored.
@@ -96,7 +96,7 @@ blockchains opened to the same peer (if it supports the target chains).
the funding transaction output. `payout_spk` specifies the script the funding transaction output. `payout_spk` specifies the script
pubkey that CETs and the refund transaction should use in the sender's output. 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 `offer_collateral_satoshis` is the amount the sender is putting into the
contract. `num_funding_inputs` is the number of funding inputs contributed by contract. `num_funding_inputs` is the number of funding inputs contributed by
the sender and `funding_inputs` contains outputs, outpoints, and expected weights 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 of the sender's funding inputs. `change_spk` specifies the script pubkey that funding
@@ -115,7 +115,7 @@ Outputs in the funding transaction will be sorted by `change_serial_id` and `fun
sides will use to compute fees in the funding transaction, as described in the sides will use to compute fees in the funding transaction, as described in the
[transaction specification](Transactions.md). [transaction specification](Transactions.md).
`contract_maturity_bound` is the nLockTime to be put on CETs. `contract_timeout` is the nLockTime to be put on the refund transaction. `cet_locktime` is the nLockTime to be put on CETs. `refund_locktime` is the nLockTime to be put on the refund transaction.
#### Requirements #### Requirements
@@ -125,17 +125,17 @@ The sending node MUST:
- ensure the `chain_hash` value identifies the chain it wishes to open the contract within. - ensure the `chain_hash` value identifies the chain it wishes to open the contract within.
- set `payout_spk` and `change_spk` to a [standard script pubkey](#script-pubkey-standardness-definition) - set `payout_spk` and `change_spk` to a [standard script pubkey](#script-pubkey-standardness-definition)
- set `funding_pubkey` to a valid secp256k1 pubkey in compressed format. - set `funding_pubkey` to a valid secp256k1 pubkey in compressed format.
- set `total_collateral_satoshis` to a value greater than or equal to 1000. - set `offer_collateral_satoshis` to a value greater than or equal to 1000.
- set `contract_maturity_bound` and `contract_timeout` to either both be UNIX timestamps, or both be block heights as distinguished [here](https://en.bitcoin.it/wiki/NLockTime). - set `cet_locktime` and `refund_locktime` to either both be UNIX timestamps, or both be block heights as distinguished [here](https://en.bitcoin.it/wiki/NLockTime).
- set `contract_maturity_bound` to be less than `contract_timeout`. - set `cet_locktime` to be less than `refund_locktime`.
- use a unique `input_serial_id` for each input - use a unique `input_serial_id` for each input
- set `change_serial_id` and `fund_output_serial_id` to different values - set `change_serial_id` and `fund_output_serial_id` to different values
The sending node SHOULD: The sending node SHOULD:
- set `feerate_per_vb` to at least the rate it estimates would cause the transaction to be immediately included in a block. - set `feerate_per_vb` to at least the rate it estimates would cause the transaction to be immediately included in a block.
- set `contract_maturity_bound` to no later than the earliest expected oracle signature time. - set `cet_locktime` to no later than the earliest expected oracle signature time.
- set `contract_timeout` sufficiently long after the latest possible oracle signature added to all other delays to closing the contract. - set `refund_locktime` sufficiently long after the latest possible release of oracle signatures added to all other delays to closing the contract.
- set `payout_spk` to a previously unused script public key. - set `payout_spk` to a previously unused script public key.
- set `change_spk` to a previously unused script public key. - set `change_spk` to a previously unused script public key.
@@ -148,7 +148,7 @@ The receiving node MAY reject the contract if:
- it does not agree to the terms in `contract_info`. - it does not agree to the terms in `contract_info`.
- the `contract_info` is missing relevant events. - the `contract_info` is missing relevant events.
- it does not want to use the oracle(s) specified in `contract_info`. - it does not want to use the oracle(s) specified in `contract_info`.
- `total_collateral_satoshis` is too small. - `offer_collateral_satoshis` is too small.
- `feerate_per_vb` is too small. - `feerate_per_vb` is too small.
- `feerate_per_vb` is too large. - `feerate_per_vb` is too large.
@@ -175,7 +175,7 @@ and closing transactions.
1. type: 42780 (`accept_dlc_v0`) 1. type: 42780 (`accept_dlc_v0`)
2. data: 2. data:
* [`32*byte`:`temporary_contract_id`] * [`32*byte`:`temporary_contract_id`]
* [`u64`:`total_collateral_satoshis`] * [`u64`:`accept_collateral_satoshis`]
* [`point`:`funding_pubkey`] * [`point`:`funding_pubkey`]
* [`spk`:`payout_spk`] * [`spk`:`payout_spk`]
* [`u64`:`payout_serial_id`] * [`u64`:`payout_serial_id`]
@@ -193,7 +193,7 @@ The `temporary_contract_id` MUST be the SHA256 hash of the `offer_dlc` message.
The sender MUST: 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 `accept_collateral_satoshis` to equal the `offer_dlc`'s `contract_info` `total_collateral` minus the `offer_collateral_satoshis`.
- set `payout_spk` and `change_spk` to a [standard script pubkey](#script-pubkey-standardness-definition) - set `payout_spk` and `change_spk` to a [standard script pubkey](#script-pubkey-standardness-definition)
- 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. - 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`. - include an adaptor signature in `cet_adaptor_signatures` for every event specified in the `offer_dlc`'s `contract_info`.
@@ -210,7 +210,7 @@ The sender SHOULD:
The receiver: The receiver:
- if `total_collateral_satoshis` is not large enough: - if `accept_collateral_satoshis` is not `total_collateral - offer_collateral_satoshis`:
- MAY reject the contract. - MAY reject the contract.
- if `payout_spk` or `change_spk` are not a [standard script pubkey](#script-pubkey-standardness-definition) - if `payout_spk` or `change_spk` are not a [standard script pubkey](#script-pubkey-standardness-definition)
- MUST reject the contract. - MUST reject the contract.
@@ -218,7 +218,7 @@ The receiver:
- MUST reject the contract. - MUST reject the contract.
- if `cet_adaptor_signatures` or `refund_signature` fail validation: - if `cet_adaptor_signatures` or `refund_signature` fail validation:
- MUST reject the contract. - MUST reject the contract.
- if `funding_inputs` do not contribute at least `total_collateral_satoshis` plus [fee payment](Transactions.md#fee-payment) - if `funding_inputs` do not contribute at least `accept_collateral_satoshis` plus [fee payment](Transactions.md#fee-payment)
- MUST reject the contract. - MUST reject the contract.
- if any `input_serial_id` is duplicated - if any `input_serial_id` is duplicated
- MUST reject the contract. - MUST reject the contract.

View File

@@ -64,14 +64,14 @@ The funding transaction's change outputs should pay to the address specified in
Also known as a CET. Also known as a CET.
* version: 2 * version: 2
* locktime: `contract_maturity_bound` * locktime: `cet_locktime`
* txin count: 1 * txin count: 1
* `txin[0]` outpoint: `txid` of funding transaction and `output_index` 0 * `txin[0]` outpoint: `txid` of funding transaction and `output_index` 0
* `txin[0]` sequence: 0xFFFFFFFE * `txin[0]` sequence: 0xFFFFFFFE
* `txin[0]` script bytes: 0 * `txin[0]` script bytes: 0
* `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>` * `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>`
The output script public keys and `contract_maturity_bound` are negotiated in the offer and accept messages. The output script public keys and `cet_locktime` are negotiated in the offer and accept messages.
In the witness `pubkey1` is the lexicographically lesser of `offer_funding_pubkey` and `accept_funding_pubkey`, and where `pubkey2` is the lexicographically greater of the two. In the witness `pubkey1` is the lexicographically lesser of `offer_funding_pubkey` and `accept_funding_pubkey`, and where `pubkey2` is the lexicographically greater of the two.
@@ -93,7 +93,7 @@ This output sends funds won by the accepter corresponding to this CET's outcome
# Refund Transaction # Refund Transaction
The refund transaction is exactly the same as a [Contract Execution Transaction](#contract-execution-transaction) except that its locktime is `contract_timeout` (as negotiated in the offer message) instead of `contract_maturity_bound` and the output values for the offerer and the accepter are their respective total collateral values from their offer/accept messages. The refund transaction is exactly the same as a [Contract Execution Transaction](#contract-execution-transaction) except that its locktime is `refund_locktime` (as negotiated in the offer message) instead of `cet_locktime` and the output values for the offerer and the accepter are their respective total collateral values from their offer/accept messages.
# Fees # Fees