Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

URI format for event ids #63

Closed
wants to merge 9 commits into from
Closed
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions oracle-uri-proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# Oracle Event URI proposal

This is a proposal for a _Uniform Resource Identifier_ (URI) format for oracle _event identifiers_ (event id).
We take URI to mean a character string that uniquely defines a resource without implying its location or how to access it.
From the URI style event id, a client can determine all the event outcomes attach semantics to each.

## Motivation

When executing a _Discreet Log Contract_ two parties agree on an event and a proportion of coins each party will receive for each event outcome.
In addition they must also agree on an _oracle_ who will cryptographically attest to the outcome of an event.
To do this correctly, the oracle and the two parties have precisely the same understanding of the event.

A single URI string that uniquely identifies an event has the following benefits:

1. Copy pasteable: A user can easily copy paste the event id into a chat app/DLC software/browser address bar.
2. Trivially serializable: It is easy to byte encode the event id for signing purposes.
3. Human readable: A user who is sufficiently familiar with event namespace does not need software to understand the event.

## Specification

An event identifier (_event id_) is a relative URI reference (a URI without the scheme and authority) with a query string.
The path of the URI is interpreted as a description of an event in time and space.
The query string is interpreted as an _measurement_ and describes a certain fact that will be observed by an oracle on the object described by the path.

If applicable, the path should start with the human organization responsible for the event.
If it is a price then the name of the exchange where the price is being measured e.g. `binance` or if it's a sporting competition then the name of the competition e.g. `NBA`.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little worried about capitalization

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that proper nouns should be in capitals. So Binance and NBA. What do you think?

If there is no applicable organization because the measurement is being taken on some natural phenomenon like the weather or the passage of time then the first segment of the path should just be the name of this phenomenon e.g. `weather` or `time`.

Each following segment, should narrow the event id until it focuses on a particular event in space and time.
Oracles are free to define the structure for this themselves with the following considerations:

1. The event type of the event may require the path has a certain structure.
2. Rules and conventions may be attached to namespaces and in general oracles should try and follow them.

### Announcement

Oracles must announce their intention to attest to the outcome of an event ahead of time.
This is done by signing a message which includes the event id.
Additionally it usually involves committing to some auxiliary cryptographic data (e.g. nonces) which allows the clients to _anticipate_ the final signature for any message.
The announcement signature is made by suffixing the event id with `!` and appending the cryptographic data.

_how to encode the data is left for a future revision_

### Attestation

When attesting to a particular outcome for the event the oracle appends `=` and the outcome text onto the event id and signs the result.
For example, if the outcome of `NBA/s2019/2020-08-11/PHI_PHX?vs` is `PHX_win` then the oracle signs `NBA/s2019/2020-08-11/PHI_PHX?vs=PHX_win`.

### Source Identifiers

If the first segment of a path contains an `@` symbol then the text that precedes it is a _source identifier_.
Copy link
Member

Choose a reason for hiding this comment

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

@ is already a reserved character in URI syntax, it would probably be better not to reuse it otherwise it would make it difficult to use existing parsing libraries.

Copy link
Contributor Author

@LLFourn LLFourn Aug 22, 2020

Choose a reason for hiding this comment

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

This is a good point. I think it's only reserved in the authority section strictly speaking? I'll have to experiment to see if it confuses parsers.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah it might depend on implementations, but from my understanding of the rfc if you want to use "@" it needs to be percentage encoded.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It also might be annoying on twitter. Perhaps the url can just have a fragment and after the # we just serialize metadata like this that doesn't affect the outcomes in some way. So it doesn't appear in the URL but is signed in the announcement message.

The source identifier describes a third party that the oracle is using to decide the outcome.
This allows an oracle to explicitly state that it is vulnerable to manipulation from this party and therefore abdicate part of its usual responsibility.
The oracle is conveying that it may blindly attest to whatever the source tells it without verifying it.

An oracle who does not provide a source identifier is asserting that it will take the measurement of the event itself or otherwise verify it somehow before attesting to it.
It is completely acceptable from the point of view of this specification for an oracle to omit a source identifier even if in reality it is only using one online source to decide the outcome; it is simply a question of whether the oracle finds it advantageous to inform its users of this fact.

Clients should interpret the event that the event id is describing as if the source identifier were absent.

Examples:

- `espn.com@NBA/s2019/2020-08-11/PHI_PHX?vs` indicates the oracle is using `espn.com` to determine the outcome of the `NBA` match (it is not watching the match itself).
- `wttr.in@Earth/Paris/2020-08-19?weather` indicates that the oracle is using `wttr.in` to determine the weather in Paris on the date (it is not using its own weather satellite).

### Event Types

The _event type_ occupies the _query string_ part of the URI.
Event types will be introduced in their own separate RFCs and all event types mentioned here are just an example.
The event type is a kebab-case identifier which may be followed by _parameters_ enclosed in parenthesis.
The parameters are a list of comma separated values.
Each event type defines its parameters and together they determine the outcomes for the event.

The event type will usually define how to interpret the preceding path segments.
For example, for a `vs` event type may require that the final path segment be in the form `<team1>_<team2>` or a `weather` event type may require the last two segments to be in the form `<location>/<date>`.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it may be beneficial to add a version to the URI to make things more extensible

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I missed this comment.
In my experience, versions in general make things less extensible because as soon as a client sees a version it does not understand it fails to parse whatever comes next. What kind of extensibility do you have in mind?

Copy link
Contributor

Choose a reason for hiding this comment

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

Related to #88


We explicitly disallow the oracle to communicate what the outcomes are for a particular event explicitly.
Outcomes are always determined implicitly from the event type.
This is done to avoid oracles independently creating events with similar but not precisely the same semantics and structure.
For example, one oracle might have a weather event that has outcomes `sunny`, `cloudy`, `rainy` while another may have `light-rain` in addition.
The hope is that this restriction will encourage the public collaboration on new event types and rich client support for them.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that there should be a built-in (so as to encourage use) versioning of event types in the URI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would hope explicit versions will not be necessary. If we screw up specifying weather, you can always make weather2 or perhaps weather.2 if we want to make visually clear it's a version.

(as side not weather is a bad example since I think it is not the type of thing people will actually use this for)


Oracles should communicate to clients which specifications they are following for their event types but this is outside the scope of this document.
Oracles who wish to control their own event type namespace partially or entirely may therefore link to their own specifications defining their own event types.

### Event Fragments

An event that describes a cardinal quantity like a price will have a large number of discrete outcomes.
Normally, users will have to arrange a transactions to cover each outcome even if they only care about a small subset of outcomes.
It is possible to optimize this by splitting up the quantity into some function of multiple sub-outcomes.

For example, a price between \$0 and \$99,999 could be expressed as `10000×e + 1000×d + 100×c + b×10 + a` whereas a..e are in the range 0..10.
Copy link
Member

Choose a reason for hiding this comment

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

I considered this as well, but I think the mantissa exponent as described in the original paper is actually better because you only need 2 R-values for any case and you don't have issues of going out of bounds.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made an issue to discuss further: #65

This means that two users who want to make a BTC/USDT trade with boundaries of \$4,000 and \$20,000 and with increments of \$100 would only have to compute contracts for 7 + 5 + 3×5×9 = 147 possible relevant outcomes instead of the usual 100,000 outcomes.

The oracle will have to declare cryptographically its intention to release signature for each of the decimal decomposed values a..e.
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason we shouldn't have the oracle specify its base (e.g. 10) to allow for binary or hex in the future should there be events where this makes sense to do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No the digits event type could indeed take a base parameter.

We treat all these values as related "fragments" of an event rather than separate events as they are semantically related to the same object.

An event type may determine that an event is made up of several event fragments.
When announcing an event with `n` event fragments the oracle creates only one announcement signature which signs all the cryptographic data together:

`<event_id>!<fragment_nonce_1>..<fragment_nonce_n>`

When attesting to a notional outcome (which is composed of the outcomes of each fragment) each fragment message is determined by the message:

`<event_id>.<i>=<fragment_outcome_i>`

## Example Event Types
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be nice to have test vectors for parsing these examples, and in the future when encoding is specified it might also be nice to have serialization and de-serialization test vectors along with signature point computation ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I think there could be some basic ones in the URI format. Each document that specifies new event types should have have some more e.g. a vs parser should extract the team names.

I would like to do this soon but I want to avoid doing this inside this not very well focused document. I think each event type should be in its own document with test etc.


### `occur`

This trial event type only has one outcome `true`.
It can be used to mark the occurrence of some event (that may or may not ever happen).
For example, it can be useful to mark the passage of time itself.

- Example event id: `time/2020-08-16T08:00:00?occur`
- Example outcome sting: `time/2020-08-16T08:00:00?occur=true` (after the event has happened)

### `weather`

The weather has a number of discrete outcomes e.g. cloudy, raining, snowing, clear etc.
Since these categories are somewhat subjective it is probably a good idea to add a source identifier and defer to the definition of the source.

- Example event id: `wttr.in@Earth/Australia/Sydney?weather`
- Example outcome id: `wttr.in@Earth/Australia/Sydney?weather=☀️` (if there's sunny weather).

### `digits(n_digits,least_significant_digit)`

A positive number decomposed into its decimal digits.
Each decimal digit is an event fragment i.e. the oracle will release a signature for each digit.

It has two parameters:

- `n_digits`: the number of digits to the left of the lowest digit.
- `least_significant_digit`: (default=0) the position the lowest digit e.g. -1 for a number like `12.3` and 0 for `123`.

If the actual value is above or equal to the maximum number expressible by the digits then the oracle must attest to the maximum number.

For example, to attest to the bid price of Bitcoin on Binance between \$0 and \$99,999 the oracle would announce `binance/BTC_USDT/bid/2021-05-16T08:00:00?digits(5)`.
If the bid price on the date is \$20,421 the oracle would release five signatures on the following messages:

1. `binance/BTC_USDT/bid-price/2021-05-16T08:00:00?digits(5).0=1`
2. `binance/BTC_USDT/bid-price/2021-05-16T08:00:00?digits(5).1=2`
3. `binance/BTC_USDT/bid-price/2021-05-16T08:00:00?digits(5).2=4`
4. `binance/BTC_USDT/bid-price/2021-05-16T08:00:00?digits(5).3=0`
5. `binance/BTC_USDT/bid-price/2021-05-16T08:00:00?digits(5).4=2`

If `digits(5)` turns out to be insufficient later on because the bitcoin price appreciates too much the oracle can always announce a new `digits(6)` event on the same path.
Copy link
Member

Choose a reason for hiding this comment

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

How can a client make use of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Clients wanting to make a bet after digits(6) has been announced can use it. Clients who have already made bets on digits(5) have to just carry on with that and its possibly truncated outcome.

However, this new event would not share any of the same signatures/nonces; it would be a completely separate event.

If a path ends in `<name1>_<name2>/bid-price/<datetime>` and has an event type of `digits` or `int` then the events value represents the bid price of `<name1>` in terms of `<name2>` at `<datetime>`.

### `above(threshold)`

This binary event type asserts that the quantity measured will be above a certain threshold.

### `vs`

This event type is for competitive matches where the one team wins and one team loses or there is a draw.
Competitions where drawing is impossible can still use the `vs` event type and just use the `draw` outcome to indicate the match being cancelled due to some act of god.

The `vs` event type requires that the path segment preceding it be in the form `<team1>_<team2>` where `<team1>_<team2>` are the competing teams.
For example, `NBA/s2019/2020-08-11/PHI_PHX?vs` describes a team named `PHI` is playing against another team named `PHX`.
Additionally the client can infer the date of the match.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Tibo-lg made a point last meeting that you can have competitions with multiple entities. e.g. Top scorer in a competition. For this you could do /FIFA-world-cup/2021/top-scoring-player/Messi_Mbappe_Ronaldo?vs(3).


Clients that are familiar with the `NBA` namespace will be able to infer that the game is part of the 2019 season and that `PHI` refers to the Phoenix Suns and `PHX` refers to the Philadelphia 76ers.

The outcomes for this event are `PHI_win`, `PHX_win` or `draw`.
Note that the team names are somewhat redundantly included to make the winning team explicit rather than using something like `left-team-won`.
Although `left-team-won` is not ambiguous, it is easy to imagine a a programmer error in some part of an oracle system that does something like:

```
if winning_team == "PHI" {
return "left-team-won"
} else {
return "right-team-won"
}
```

This would return "left-team-won" even if `winning_team` was null for example.
Instead this piece of code can be written as `return "{winning_team}_win"` and another part of the system can verify that that is a valid outcome for the event.

### `left-win/right-win`

These are just like `vs` except they assert a particular team will win and are therefore binary.
For the event `NBA/s2019/2020-08-11/PHI_PHX?left-win` the outcomes are `PHI_win` or `PHX_win-or-draw`.

## Extensibility

The goal of the format is to allow extension of the event space through new event types and new namespaces.
The idea is that new event types will generally involve a lot formal collaboration between oracles through the authoring of new specification documents.
This is because clients and servers must all implement the specific logic of the event type.

On the other hand, oracles can create new namespaces independently.
Obviously it would be ideal if the namespaces are consistent across oracles but we hope that this can happen through ad-hoc cooperation.
We expect that useful namespace conventions will emerge across oracles and if those conventions becomes widespread enough and clients rely on them then they can be specified later.