mirror of
https://github.com/aljazceru/dlcspecs.git
synced 2025-12-17 06:14:23 +01:00
Rewording and Renaming clean-up (#142)
Responded to review Cleaned up a couple sentences
This commit is contained in:
@@ -71,33 +71,35 @@ announcement and `s(1..m)` is sufficient information to generate a fraud proof i
|
||||
|
||||
## 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))`
|
||||
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)
|
||||
first splits the domain into buckets 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.
|
||||
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 intervals of equal payout, and then applies the compression algorithm from this
|
||||
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
|
||||
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
|
||||
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
|
||||
`n` (being signed by the oracle) and returns an array of arrays of integers (which will all be in the range `[0, B-1]`).
|
||||
An array of integers corresponds to a single event equal to the concatenation of these integers (interpreted in base `B`).
|
||||
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 a list of digit prefixes serialized as an array of arrays of integers
|
||||
(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
|
||||
|
||||
Before generalizing or specifying the algorithm, let us run through a concrete example.
|
||||
|
||||
We will consider the range `[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
|
||||
the remainder of this example as we can simply examine the range `[5677, 8621]` and prepend a `13` to all results.
|
||||
We will consider the interval `[135677, 138621]`, in base `10`.
|
||||
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 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
|
||||
`5677`, `8621` and the following cases:
|
||||
To cover all cases while looking at as few digits as possible in this interval we need only consider
|
||||
`5677`, `8621` individually in addition to the following cases:
|
||||
|
||||
```
|
||||
5678, 5679,
|
||||
@@ -111,12 +113,13 @@ To cover all cases while looking at as few digits as possible in this range we n
|
||||
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`).
|
||||
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!
|
||||
|
||||
Here it is again in binary (specifically the range `[5677, 8621]`, not the original range with the `13` prefix in base 10):
|
||||
Outliers are `5677 = 01011000101101` and `8621 = 10000110101101` with cases:
|
||||
Let us reconsider this example in binary (specifically the interval `[5677, 8621]`, not the original interval with the `13` prefix in base 10):
|
||||
The individual outliers are `5677 = 01011000101101` and `8621 = 10000110101101` with cases:
|
||||
|
||||
```
|
||||
0101100010111_,
|
||||
@@ -134,7 +137,7 @@ Outliers are `5677 = 01011000101101` and `8621 = 10000110101101` with cases:
|
||||
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
|
||||
|
||||
@@ -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`.
|
||||
|
||||
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),
|
||||
@@ -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.
|
||||
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`).
|
||||
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.
|
||||
|
||||
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)`
|
||||
corresponds to the number of unique digits between the start and end of the range and for each unique digit a row is
|
||||
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 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.
|
||||
|
||||
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
|
||||
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 capture the same range in base 2 we need 10 digit binary numbers.
|
||||
To help with intuition on this matter, consider an arbitrary interval of three digit numbers in base 10.
|
||||
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!
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
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,
|
||||
@@ -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
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
def groupByIgnoringDigits(start: Long, end: Long, base: Int, numDigits: Int): Vector[Vector[Int]] = {
|
||||
|
||||
@@ -11,115 +11,111 @@
|
||||
|
||||
## Abstract
|
||||
|
||||
DLC allows two parties to conduct stateful bitcoin contracts by giving each
|
||||
of the parties *cross-signed range of CET transactions*. These CETs transactions
|
||||
are all spending the same output from a funding transaction and thus only one of
|
||||
CET can confirm. A CET is finalized according to the outcome signed by the previously
|
||||
selected oracle.
|
||||
DLCs allow two parties to conduct stateful bitcoin contracts by giving each
|
||||
other a *counter-signed set of CETs*.
|
||||
These CETs all spend the same output from a funding transaction and thus only one
|
||||
CET can be confirmed.
|
||||
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,
|
||||
from then a party should assume counterparty non-cooperation and ensure either
|
||||
confirmation of the funding or double-spend of its collatral inputs to avoid exploitation.
|
||||
The contract is established once funding transaction signatures have been exchanged.
|
||||
From that point on each party should assume their counter-party is non-cooperative and should ensure either
|
||||
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
|
||||
to interact anymore. They are three scenarios to consider:
|
||||
Once funding transaction signatures are exchanged, DLC parties aren't required to interact anymore.
|
||||
There are three scenarios to consider:
|
||||
|
||||
1. The funding transaction doesn't confirm, a party must either bump its feerate
|
||||
to confirm before DLC maturing or double-spend its funding collateral, thus cancelling the
|
||||
DLC.
|
||||
|
||||
2. The funding transaction confirms, the oracle releases the outcome signature, a
|
||||
participant must broadcast the DLC transaction paired with the outcome.
|
||||
|
||||
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.
|
||||
1. The funding transaction doesn't confirm, and so a party must either bump its fee-rate to confirm
|
||||
before the earliest DLC maturation or else double-spend its funding collateral canceling the 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
|
||||
participant must broadcast the CET corresponding to the oracle 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.
|
||||
|
||||
# General Requirements
|
||||
|
||||
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>
|
||||
|
||||
We recommend to not produce local non-adaptor signatures for transaction until their broadcast
|
||||
is required to avoid their misuage in case of site compromise, assuming an external signer.
|
||||
We recommend that clients should not produce local (non-adaptor) signatures for CETs until they are about
|
||||
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
|
||||
counterparty honest behavior in case of primary storage failure.
|
||||
Furthermore, we recommend duplicated backups of counter-party signatures be stored to avoid relying on
|
||||
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
|
||||
|
||||
An onchain state machine must take actions based on different timers parameterized by three
|
||||
values: `congestion_bump_frequency`/`security_bump_frequency`/`security_point`/`refund_security_point`.
|
||||
Their definition and setting recommendations are laid out in this section, their usage is precised
|
||||
in following sections.
|
||||
A state machine following on-chain events must take actions based on different clocks parameterized by three
|
||||
values: `congestion_bump_frequency`/`security_bump_frequency`/`funding_security_point`/`refund_security_point`.
|
||||
These values' definitions and setting recommendations are laid out in this section and their usage is made
|
||||
more precise in following sections.
|
||||
|
||||
A `security_point` is a client heuristic after which the confirmation of the funding transaction
|
||||
is a matter of contract safety, otherwise the user is exposed to a bad-player double-spend if either
|
||||
the outcome odds are modified or a signature oracle is released. This point is function of event
|
||||
signing time, which may be static or dynamic, we defer point qualification to client.
|
||||
A `security_point` is a client-side heuristic time/block-stamp after which the confirmation of a corresponding
|
||||
transaction is a matter of contract safety.
|
||||
If confirmation does not occur soon after this point, the user can be vulnerable to a malicious double-spend if either
|
||||
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
|
||||
`security_point` with a confirmation buffer of 20 blocks compared to signing time.
|
||||
If the `security_point` time is static (block height, epoch) or predictable, we recommend setting
|
||||
`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
|
||||
transaction is a matter of contract safety, otherwise the user is exposed to a malicious CET spend
|
||||
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.
|
||||
A client's `congestion_bump_frequency`/`security_bump_frequency` can be scheduled on at least three
|
||||
different kinds of events:
|
||||
|
||||
Client's `congestion_bump_frequency`/`security_bump_frequency` can be scheduled at least on three different basis:
|
||||
- a block height
|
||||
- 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
|
||||
to pad any criteria with a random delay to diminish risks of tx-relay jamming.
|
||||
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 the risks of tx-relay jamming.
|
||||
|
||||
We don't provide recommendations for the `congestion delay` as its settings depends of user
|
||||
liquidity preferences and available local data to predict the feerate. Confirmation of non
|
||||
time-sensitive transactions should happen but a user may prefer to delay them in case of
|
||||
mempool-congestion.
|
||||
We don't provide recommendations for the `congestion_bump_frequency` as its settings depends on user
|
||||
liquidity preferences and the availability of local data to predict the fee-rate.
|
||||
Confirmation of non-time-sensitive transactions should happen eventually, but a user may prefer to delay
|
||||
confirmation in the case of mempool-congestion.
|
||||
|
||||
We provide recommendations for the `security_bump_frequency` as any transaction under this fee-bumping
|
||||
policy has a time-sensitive confirmation. A delay of 1 block and a fast-confirmation feerate
|
||||
as reported by fee-estimator should be preferred.
|
||||
We recommend a `security_bump_frequency` of 1 block, preferably with a fast-confirmation fee-rate as reported
|
||||
by a fee-estimator if possible.
|
||||
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
|
||||
fees in case of mempool spikes, while anticipating that at some point during DLC execution, the
|
||||
confirmation of the funding is a security concern.
|
||||
Having different fee-bumping frequencies for congestion and security avoids a client overpaying in
|
||||
fees in the case of mempool spikes, while anticipating that at some point during DLC execution, the
|
||||
confirmation of certain transactions is a security concern.
|
||||
|
||||
# Funding Phase
|
||||
|
||||
A party always starts the protocol in the funding phase. The funding phase can
|
||||
terminate by either a transition to the execution phase or a protocol abort.
|
||||
A DLC participant always begins the protocol in the funding phase.
|
||||
The funding phase can terminate either to the execution phase by a transition to the execution phase or to an abort.
|
||||
|
||||
## Requirements
|
||||
|
||||
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 broadcast the funding transaction
|
||||
- MUST start a fee-bumping timer of length `congestion_bump_frequency`
|
||||
|
||||
A node:
|
||||
|
||||
- if a funding signature has been sent or a funding transaction broadcast and there is no confirmation after 6 blocks:
|
||||
- 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 a funding signature has been sent or a funding transaction broadcast and there is no confirmation:
|
||||
- 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 reschedule timer for next bump
|
||||
- if `security_point` is reached:
|
||||
- MUST spend a funding input with a higher-feerate transaction/absolute fee than any previously propagated package feerate
|
||||
- if `funding_security_point` is reached:
|
||||
- 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 disable `congestion_bump_frequency` timer
|
||||
- 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 reschedule timer for next bump
|
||||
- MUST NOT spend more in bumping fees than its collateral input value
|
||||
@@ -130,37 +126,39 @@ A node:
|
||||
|
||||
- if the funding transaction confirms:
|
||||
- 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
|
||||
|
||||
A node:
|
||||
|
||||
- if the funding input double-spend confirms:
|
||||
- MUST abort the DLC and prevent further interactions with counterparty
|
||||
- if a counter-party funding input double-spend confirms:
|
||||
- MUST abort the DLC and prevent further interactions with that counter-party
|
||||
|
||||
## Rationale
|
||||
|
||||
Funding transaction must be confirmed to consider the off-chain state initialized. As mempools
|
||||
congestion may fluctuate between fees negotiation and transaction propagation, party must adjust
|
||||
unilaterally the package feerate (CPFP) according to their confirmation preferences. A party may
|
||||
choose to wait for mempools draining before to adjust the feerate to avoid a fee waste as block
|
||||
height of transition to execution phase doesn't matter, assuming it's before `contract_maturity_bound`.
|
||||
The funding transaction must be confirmed to consider the off-chain state initialized.
|
||||
As mempool congestion may fluctuate between fee negotiation and transaction propagation, parties
|
||||
must unilaterally adjust the package fee-rate (using CPFP) according to their confirmation preferences.
|
||||
A party may choose to wait for mempools to drain before adjusting the fee-rate to avoid over-paying in
|
||||
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
|
||||
now a security matter. After oracle signature release, a malicious party could try to double-spend
|
||||
an unconfirmed funding transaction to avoid losing its collateral, and thus without assuming deceitful
|
||||
cooperation with the oracle.
|
||||
As the earliest possible (expected) contract execution approaches, the funding transaction must
|
||||
be confirmed quickly as a matter of security.
|
||||
After the oracle releases a signature, a malicious party could try to double-spend an unconfirmed funding
|
||||
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
|
||||
at this level. E.g a DLC implementation feeded with a _correct_ signature whereas the contract is
|
||||
invalid but still displaying an incorrect information to the user. A double-spending counterparty
|
||||
is also "breaking" the previously negotiated DLC and agreed by its signature exchange. Thus further
|
||||
interactions should be warranted with this buggy/malicious peer.
|
||||
In the case that a counter-party double-spends a funding input, cleaning off-chain state prevents
|
||||
further exploitation at this level.
|
||||
For example, a DLC implementation that has received _correct_ signatures but where the contract is
|
||||
invalid could still be displaying incorrect information to the user.
|
||||
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
|
||||
|
||||
The execution phase transitions to the terminal phase either by a CET or a refund
|
||||
transaction confirmations.
|
||||
The execution phase transitions to the terminal phase by confirming either a CET or a refund transaction.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -169,44 +167,44 @@ A node:
|
||||
- if an oracle signature is received:
|
||||
- MUST finalize the CET with a local `SIGHASH_ALL` signature
|
||||
- MUST broadcast the CET
|
||||
- MAY spend its outcome output with a CPFP increasing package feerate to shorten confirmation time
|
||||
- if the CET is not confirmed and `contract_timeout` is 20 blocks ahead of local tip:
|
||||
- MAY spend its outcome output with a CPFP increasing package fee-rate to shorten confirmation time
|
||||
- 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 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`
|
||||
- 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 reschedule timer for next bump
|
||||
- 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:
|
||||
- MAY disable CET fee-bumping
|
||||
|
||||
A node:
|
||||
|
||||
- if a CET transaction confirms:
|
||||
- if a CET confirms:
|
||||
- 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:
|
||||
|
||||
- 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 broadcast the refund transaction
|
||||
- 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`
|
||||
- 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 reschedule timer for next bump
|
||||
- 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 disable `refund_congestion_bump_frequency` timer
|
||||
- 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 reschedule timer for next bump
|
||||
|
||||
@@ -214,18 +212,18 @@ A node:
|
||||
|
||||
- if a refund transaction confirms:
|
||||
- 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
|
||||
|
||||
Reaching near `contract_timeout` requires to confirm the valid CET quickly as it's now a security
|
||||
matter. A malicious party could try to cancel a lost DLC by confirming the refund transaction.
|
||||
As `refund_locktime` approaches, a CET must be confirmed quickly as a matter of security.
|
||||
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
|
||||
the oracle key material is toxic, as in case of compromise, a CET could be signed and confirmed
|
||||
by a malicious counterparty. This confirmation should be managed in function of the user trust
|
||||
towards the oracle.
|
||||
A refund transaction confirmation is less sensitive but it should be noted that while participants are
|
||||
waiting for refund confirmations, the oracle key material is toxic.
|
||||
In case of oracle key compromise, a CET could be signed and confirmed by a malicious counter-party.
|
||||
Refund transaction confirmation should be managed as a function of the user's trust towards the oracle.
|
||||
|
||||
# Reorgs
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ when interacting with lowest-level core DLC logic.
|
||||
|
||||
## 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
|
||||
compress the CETs required by that interval to be logarithmic in size compared to using one CET per outcome on that interval.
|
||||
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,
|
||||
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
|
||||
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
|
||||
@@ -91,11 +91,11 @@ If `begin_interval_1` is strictly greater than `0`, then the interval between `0
|
||||
## 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
|
||||
of digits (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
|
||||
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 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.
|
||||
|
||||
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`.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
in the array of integers and the Satoshi payout is equal to the output of the modified function for that `event_outcome`.
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ This necessary information is committed to in a so-called [_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.
|
||||
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.
|
||||
Two kinds of event outcomes are defined (note that a single event can be composed of several types).
|
||||
|
||||
@@ -137,7 +137,7 @@ Given a potential `event_outcome` compute the `outcome_payout` as follows:
|
||||
|
||||
#### 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
|
||||
|
||||
|
||||
30
Protocol.md
30
Protocol.md
@@ -72,15 +72,15 @@ the funding transaction and CETs.
|
||||
* [`point`:`funding_pubkey`]
|
||||
* [`spk`:`payout_spk`]
|
||||
* [`u64`:`payout_serial_id`]
|
||||
* [`u64`:`total_collateral_satoshis`]
|
||||
* [`u64`:`offer_collateral_satoshis`]
|
||||
* [`u16`:`num_funding_inputs`]
|
||||
* [`num_funding_inputs*funding_input`:`funding_inputs`]
|
||||
* [`spk`:`change_spk`]
|
||||
* [`u64`:`change_serial_id`]
|
||||
* [`u64`:`fund_output_serial_id`]
|
||||
* [`u64`:`feerate_per_vb`]
|
||||
* [`u32`:`contract_maturity_bound`]
|
||||
* [`u32`:`contract_timeout`]
|
||||
* [`u32`:`cet_locktime`]
|
||||
* [`u32`:`refund_locktime`]
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -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
|
||||
[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
|
||||
|
||||
@@ -125,17 +125,17 @@ The sending node MUST:
|
||||
- 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 `funding_pubkey` to a valid secp256k1 pubkey in compressed format.
|
||||
- set `total_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 `contract_maturity_bound` to be less than `contract_timeout`.
|
||||
- set `offer_collateral_satoshis` to a value greater than or equal to 1000.
|
||||
- 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 `cet_locktime` to be less than `refund_locktime`.
|
||||
- use a unique `input_serial_id` for each input
|
||||
- set `change_serial_id` and `fund_output_serial_id` to different values
|
||||
|
||||
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 `contract_maturity_bound` 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 `cet_locktime` to no later than the earliest expected oracle signature time.
|
||||
- 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 `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`.
|
||||
- the `contract_info` is missing relevant events.
|
||||
- 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 large.
|
||||
|
||||
@@ -175,7 +175,7 @@ and closing transactions.
|
||||
1. type: 42780 (`accept_dlc_v0`)
|
||||
2. data:
|
||||
* [`32*byte`:`temporary_contract_id`]
|
||||
* [`u64`:`total_collateral_satoshis`]
|
||||
* [`u64`:`accept_collateral_satoshis`]
|
||||
* [`point`:`funding_pubkey`]
|
||||
* [`spk`:`payout_spk`]
|
||||
* [`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:
|
||||
|
||||
- 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 `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`.
|
||||
@@ -210,7 +210,7 @@ The sender SHOULD:
|
||||
|
||||
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.
|
||||
- if `payout_spk` or `change_spk` are not a [standard script pubkey](#script-pubkey-standardness-definition)
|
||||
- MUST reject the contract.
|
||||
@@ -218,7 +218,7 @@ The receiver:
|
||||
- MUST reject the contract.
|
||||
- if `cet_adaptor_signatures` or `refund_signature` fail validation:
|
||||
- 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.
|
||||
- if any `input_serial_id` is duplicated
|
||||
- MUST reject the contract.
|
||||
|
||||
@@ -64,14 +64,14 @@ The funding transaction's change outputs should pay to the address specified in
|
||||
Also known as a CET.
|
||||
|
||||
* version: 2
|
||||
* locktime: `contract_maturity_bound`
|
||||
* locktime: `cet_locktime`
|
||||
* txin count: 1
|
||||
* `txin[0]` outpoint: `txid` of funding transaction and `output_index` 0
|
||||
* `txin[0]` sequence: 0xFFFFFFFE
|
||||
* `txin[0]` script bytes: 0
|
||||
* `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.
|
||||
|
||||
@@ -93,7 +93,7 @@ This output sends funds won by the accepter corresponding to this CET's outcome
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user