diff --git a/Messaging.md b/Messaging.md index 54cf2bf..8cb10b3 100644 --- a/Messaging.md +++ b/Messaging.md @@ -56,6 +56,7 @@ Various fundamental types are referred to in the message specifications: * `u32`: a 4 byte unsigned integer * `u64`: an 8 byte unsigned integer * `int32`: a 4 byte signed integer +* `bool`: a boolean value represented as a `byte` which can have only two value, `0x01` to represent `true` and `0x00` to represent false (any other value should be considered invalid). Inside TLV records which contain a single value, leading zeros in integers can be omitted: @@ -78,7 +79,8 @@ The following convenience types are also defined: * `script_sig`: A bitcoin script signature encoded as ASM prefixed a `u16` value indicating its length. * `short_contract_id`: an 8 byte value identifying a contract funding transaction on-chain (see [BOLT #7](https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#definition-of-short-channel-id)) * `bigsize`: a variable-length, unsigned integer similar to Bitcoin's CompactSize encoding, but big-endian. Described in [BigSize](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#appendix-a-bigsize-test-vectors). -* `string`: a UTF-8 encoded string using [NFC for normalization](https://github.com/discreetlogcontracts/dlcspecs/issues/89) +* `string`: a UTF-8 encoded string using [NFC for normalization](https://github.com/discreetlogcontracts/dlcspecs/issues/89), prefixed by a `bigsize` value indicating its length in bytes. + ## DLC Specific Types @@ -175,78 +177,6 @@ This type contains signatures of the funding transaction and any necessary infor `witness` is the data for a witness element in a witness stack. An empty `witness_stack` is an error, as every input must be Segwit. Witness elements should *not* include their length as part of the witness data. -### The `event_descriptor` Type - -This type contains information about the *exact* and fully specified outcomes in an event for which an oracle plans on releasing a signature over. - -#### Version 0 `external_event_descriptor` - -1. type: 55300 (`external_event_descriptor_v0`) -2. data: - * [`string`:`external_name`] - -`external_name` can refer to anything here and it is up to the oracle and user to agree on how to interpret it. - -#### Version 0 `enum_event_descriptor` - -1. type: 55302 (`enum_event_descriptor_v0`) -2. data: - * [`u16`:`num_outcomes`] - * [`u16`:`outcome_1_len`] - * [`string`:`outcome_1`] - * ... - * [`u16`:`outcome_n_len`] - * [`string`:`outcome_n`] - -This type of event descriptor is a simple enumeration where the value `n` is the number of outcomes in the event. - -Each `outcome_i` corresponds to the pre-image of a possible outcome that the oracle could sign. - -#### Version 0 `range_event_descriptor` - -1. type: 55304 (`range_event_descriptor_v0`) -2. data: - * [`int32`:`start`] - * [`int32`:`stop`] - * [`u16`:`step`] - -`start` refers to the first possible outcome number - -`end` refers to the last possible outcome number - -`step` refers to the increment between each outcome - -### The `oracle_event` Type - -This type contains information about an event for which an oracle plans on releasing a signature over. - -#### Version 0 `oracle_event` - -1. type: 55330 (`oracle_event_v0`) -2. data: - * [`x_point`:`oracle_public_key`] - * [`x_point`:`oracle_nonce`] - * [`u32`:`event_maturity_epoch`] - * [`event_descriptor`:`event_descriptor`] - * [`string`:`event_uri`] - -`event_maturity_epoch` refers to the earliest time this event (UTC) is expected to be signed, in epoch seconds. - -`event_uri` is a name and/or categorization of this event given by the oracle. - -### The `oracle_announcement` Type - -This type contains information about an announcement of an oracle to attest to an event in the future. - -#### Version 0 `oracle_announcement` - -1. type: 55332 (`oracle_announcement`) -2. data: - * [`signature`:`annoucement_signature`] - * [`oracle_event`:`oracle_event`] - -The `annoucement_signature` is a signature of the hash of the serialized `oracle_event` that is valid with respect to `oracle_public_key`. This can be shared with peers that have already verified this oracle's public key. - ## Authors Nadav Kohen diff --git a/Oracle.md b/Oracle.md new file mode 100644 index 0000000..63821ec --- /dev/null +++ b/Oracle.md @@ -0,0 +1,197 @@ +# Oracle specifications + +## Introduction + +For the purpose of these specifications, an event is a digital representation of a real world fact. +An [oracle](./Introduction.md#Oracle) is an entity that commits to publishing one or more signatures over a (number of) event outcome(s) ahead of time by releasing one or more [R-values](./Introduction.md#R-value) as well as necessary information for two parties to build a set of [CETs](./Introduction.md#Contract-Execution-Transaction-(CET)). +This necessary information is committed to in a so-called [_event descriptor_](#Event-descriptor) that will be further detailed in this document. + +## Table of Contents + +- [Event descriptor](#event-descriptor) + - [Simple enumeration](#simple-enumeration) + - [Example: Weather tomorrow](#example-weather-tomorrow) + - [Range](#range) + - [Example: tomorrow's temperature](#example-tomorrows-temperature) + - [Digit decomposition](#digit-decomposition) + - [Example: BTC/USD rate](#example-btcusd-rate) + - [Serialization and signing of outcome values](#serialization-and-signing-of-outcome-values) + - [Serialization of event descriptors](#serialization-of-event-descriptors) + - [Version 0 `enum_event_descriptor`](#version-0-enum_event_descriptor) + - [Version 0 `range_event_descriptor`](#version-0-range_event_descriptor) + - [Version 0 `digit_decomposition_event_descriptor`](#version-0-digit_decomposition_event_descriptor) + - [Oracle events](#oracle-events) + - [Version 0 `oracle_event`](#version-0-oracle_event) +- [Oracle announcements](#oracle-announcements) + - [Version 0 `oracle_announcement`](#version-0-oracle_announcement) + +## 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. + +Here we assume that an event outcome can be represented either as a set of strings or numbers. +Three kinds of event outcomes are defined (note that a single event can be composed of several types). + +### Simple enumeration + +For events that have a narrow range of possible outcomes, the outcomes can simply be enumerated. + +#### Example: Weather tomorrow + +Tomorrow's weather can be represented as the set of strings `[sunny, cloudy, rainy]`. + +### Range + +When an event has numerical outcomes that cannot be easily enumerated, they can be represented as a series with: + +- start: the first possible outcome number +- count: the number of possible outcomes +- step: the increment +- unit: the unit of the outcome value +- precision: the precision of the outcome representing the base 10 exponent by which to multiply the signed number to obtain the actual outcome value. + +#### Example: tomorrow's temperature + +``` +start: -100 +count: 201 +step: 1 +unit: °C +precision: 0 +``` + +### Digit decomposition + +When a range of a numerical outcomes is large or unbounded, the oracle can represent the outcome using digit decomposition. + +The event descriptor should include: + +- base: a number representing the base in which the outcome value is decomposed and which will indicate the possible range of each digit that will be signed (e.g. 2 for binary, 10 for decimal, 16 for hex-decimal). +- is-signed: a boolean value indicating whether the outcomes can be negative. +- unit: the unit of the outcome value +- precision: the precision of the outcome representing the base exponent by which to multiply the number represented by the composition of the digits to obtain the actual outcome value. +- number of digits: the number of digits that the oracle will sign (if `is-signed` is set to true, the number of R-values for the event will be `number of digits + 1`). + +In the case where the number of digits that make up the outcome value exceeds the number of r-values that the oracle committed to, the oracle should sign the maximal possible value that it can attest to. +In the case where the outcome value became negative but the oracle did not provide an extra R-value, it should sign the value 0. +The minimum and maximum values that can be attested to by an oracle should thus be interpreted as `max_value or more` and `min_value or less`. +This enables contracting party to specify payouts for the overflow and underflow cases, and avoid having to use the refund path which in most cases would be unfair. +More complex constructions where considered to handle these, but the simplicity of the currently specified approach is the reason that it was chosen. + +The oracle must separately provide an array of R values, one for each of the digit that will be signed, with the first value of the array being used for signing the leftmost digit. If the is-signed value is true, an additional R-value must be provided as the first element in this array, which will be used to sign the string "+" in case of an outcome with a positive value or zero value and the string "-" in case of an outcome with a negative one. +In practice this array is provided as part of the [Oracle events](#Oracle-events) structure. + +When the outcome is not the same order of magnitude as the maximum possible outcome, leading zeros must be signed. + +#### Example: BTC/USD rate + +The following example illustrates how numerical decomposition can help reduce the number of required CETs while covering a large range of possible outcomes. + +Alice and Bob wish to enter into a DLC at time `t` when BTC/USD ~= $10000 with a maturity time of `t+1`. +The oracle provides 6 R-values `R0-5`, meaning that it will sign six digits `D0-5`, enabling him to attest to outcomes in the range `[000000,999999]`: + +``` +base: 10 +isSigned: false +RValues: [R0, R1, R2, R3, R4, R5] +unit: dollars +precision: 0 +``` + +Alice and Bob create a DLC with "relevant" outcomes between $10000 and $10999. +Below $10000 Alice gets everything, and above $10999 Bob gets everything. +They use the `R0` and `R1` values to cover the cases where BTC/USD < $10000 using `D0=0` and `D1=0`. +They use `R0`, `R1` and `R2` to cover the cases where BTC/USD > $10999 and <= $19999, using `D1=0`, `D1=1` and `D2 in [0-9]`. +They use `R0` and `R1` to cover the cases where BTC/USD >= $20000 and < $99999, using `D0=0` and `D1 in [2,9]`. +Finally, they use only `D0` to cover the cases where BTC/USD >= $100000 and <= $999999, using `D0 in [1-9]`. + +At maturity time, if the BTC/USD rate is less than $999999, the oracle signs each of the digits representing the outcome value using the digits' corresponding R value. +For example, if the rate at maturity time is $20000, the oracle will sign the digits `0`, `2`, `0`, `0`, `0`, `0`. + +If the rate is greater than $999999, the oracle signs the digits `9`, `9`, `9`, `9`, `9`, `9`. + +### Serialization and signing of outcome values + +Every outcome value should be encoded as [a UTF-8 string with NFC normalization](./Messaging.md#Fundamental-types), before being passed to the signing algorithm. +UTF-8 is chosen as being a widely supported and easy to implement encoding format. + +For numerical outcomes represented in bases greater than 10, each digit should be converted to base 10 before being encoded (note that base 10 numbers in UTF-8 take values in the 0x0030-0x0039 range). +This helps preventing any confusion about the capitalization of letters or the introduction of non-standard characters. + +### Serialization of event descriptors + +Event descriptors should be serialized using [TLV format](https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md#type-length-value-format) as described bellow. + +#### Version 0 `enum_event_descriptor` + +1. type: 55302 (`enum_event_descriptor_v0`) +2. data: + * [`u16`:`num_outcomes`] + * [`string`:`outcome_1`] + * ... + * [`string`:`outcome_n`] + +This type of event descriptor is a simple enumeration where the value `n` is the number of outcomes in the event. + +Note that `outcome_i` is the outcome value itself and not its hash that will be signed by the oracle. + +#### Version 0 `range_event_descriptor` + +1. type: 55304 (`range_event_descriptor_v0`) +2. data: + * [`int32`:`start`] + * [`u32`:`count`] + * [`u16`:`step`] + * [`string`:`unit`] + * [`int32`:`precision`] + +#### Version 0 `digit_decomposition_event_descriptor` + +1. type: 55306 (`digit_decomposition_event_descriptor_v0`) +2. data: + * [`bigsize`:`base`] + * [`bool`:`is_signed`] + * [`string`:`unit`] + * [`int32`:`precision`] + * [`uint16`:`nb_digits`] + +### Oracle events + +For users to be able to create DLCs based on a given event, they also need to obtain information about the oracle and the time at which it plans on releasing a signature over the event outcome. +Oracle events contain such information, which includes: +* the nonce(s) that will be used to sign the event outcome(s) +* the earliest time (UTC) at which it plans on releasing a signature over the event outcome, in epoch seconds, +* the event descriptor, +* the event ID which can be a name or categorization associated with the event by the oracle. + +The TLV serialization for oracle events is as follow: + +#### Version 0 `oracle_event` + +1. type: 55330 (`oracle_event_v0`) +2. data: + * [`u16`:`nb_nonces`] + * [`nb_nonces*x_point`:`oracle_nonces`] + * [`u32`:`event_maturity_epoch`] + * [`event_descriptor`:`event_descriptor`] + * [`string`:`event_id`] + +## Oracle announcements + +In order to make it possible to hold oracles accountable in cases where they do not release a signature for an event outcome, there needs to be a proof that an oracle has committed to a given outcome. +This proof is given in a so-called oracle announcement, which contains an oracle event together with the oracle public key and a signature over its serialization, which must be valid with respect to the specified public key. + +This also makes it possible for users to obtain oracle event information from an un-trusted peer while being guaranteed that it originates from a given oracle. + +The TLV serialization of oracle announcements is as follow. + +#### Version 0 `oracle_announcement` + +1. type: 55332 (`oracle_announcement`) +2. data: + * [`signature`:`annoucement_signature`] + * [`x_point`:`oracle_public_key`] + * [`oracle_event`:`oracle_event`] + +where `signature` is a Schnorr signature over a sha256 hash of the serialized `oracle_event`.