-
Notifications
You must be signed in to change notification settings - Fork 2
[SPEC ONLY] Clarify unregistering data sources #1207
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -32,11 +32,45 @@ cash_settled_future.value(quote) { | |||||
|
||||||
## 4. Lifecycle triggers | ||||||
|
||||||
### 4.1 Settlement data and settlement | ||||||
|
||||||
Data point `cash_settled_future.settlement_data` stores settlement data once it is received. | ||||||
This is used as soon as the market settles which may not be on receipt, if trading terminated was not also received. | ||||||
|
||||||
Initially: | ||||||
``` | ||||||
cash_settled_future.settlement_data := None | ||||||
``` | ||||||
|
||||||
The following logic applies to settle the market, this can either be triggered by the receipt of settlement data or the trading terminated trigger. | ||||||
See the logic in 4.2, 4.3 below for more details. | ||||||
|
||||||
|
||||||
```javascript | ||||||
cash_settled_future.do_settlement() { | ||||||
assertcash_settled_future.settlement_data != None) | ||||||
final_cashflow = cash_settled_future.value(cash_settled_future.settlement_data) - cash_settled_future.value(market.mark_price) | ||||||
settleMarket(cash_settled_future.settlement_asset, final_cashflow) | ||||||
setMarkPrice(settlement_data) | ||||||
setMarketStatus(SETTLED) | ||||||
} | ||||||
``` | ||||||
|
||||||
|
||||||
### 4.1 Termination of trading | ||||||
|
||||||
```javascript | ||||||
cash_settled_future.trading_termination_trigger(event) { | ||||||
|
||||||
// Only ever trigger trading terminated once | ||||||
unregister_data_source_and_stop_listening(cash_settled_future.trading_termination_trigger) | ||||||
setMarketStatus(TRADING_TERMINATED) | ||||||
|
||||||
// If we already got settlement data, we can stop listening for updated settlement data and settle now | ||||||
if cash_settled_future.settlement_data != None { | ||||||
unregister_data_source_and_stop_listening(cash_settled_future.settlement_data) | ||||||
cash_settled_future.do_settlement() | ||||||
} | ||||||
} | ||||||
``` | ||||||
|
||||||
|
@@ -45,16 +79,15 @@ cash_settled_future.trading_termination_trigger(event) { | |||||
|
||||||
```javascript | ||||||
cash_settled_future.settlement_data(event) { | ||||||
|
||||||
// If settlement data was received prior to trading termination use the last value received, otherwise use the first value received after trading is terminated | ||||||
while market.status != TRADING_TERMINATED { | ||||||
waitForMarketStatus(TRADING_TERMINATED) | ||||||
|
||||||
// Store settlement data (replaces data from previous event so always use latest event up to the point we settle) | ||||||
cash_settled_future.settlement_data = event.data | ||||||
|
||||||
// Id trading is already terminated, stop listening for data and settle now | ||||||
if market.status == TRADING_TERMINATED { | ||||||
unregister_data_source_and_stop_listening(cash_settled_future.settlement_data) | ||||||
cash_settled_future.do_settlement() | ||||||
} | ||||||
|
||||||
final_cashflow = cash_settled_future.value(event.data) - cash_settled_future.value(market.mark_price) | ||||||
settle(cash_settled_future.settlement_asset, final_cashflow) | ||||||
setMarkPrice(event.data) | ||||||
setMarketStatus(SETTLED) | ||||||
} | ||||||
``` | ||||||
|
||||||
|
@@ -74,3 +107,7 @@ cash_settled_future.settlement_data(event) { | |||||
1. Lifecycle events are processed atomically as soon as they are triggered, i.e. the above condition always holds even for two or more transactions arriving at effectively the same time - only the transaction that is sequenced first triggers final settlement (<a name="0016-PFUT-010" href="#0016-PFUT-010">0016-PFUT-010</a>) | ||||||
1. Once a market is finally settled, the mark price is equal to the settlement data and this is exposed on event bus and market data APIs (<a name="0016-PFUT-011" href="#0016-PFUT-011">0016-PFUT-011</a>) | ||||||
1. Assure [settment-at-expiry.feature](https://github.com/vegaprotocol/vega/blob/develop/core/integration/features/verified/0002-STTL-settlement_at_expiry.feature) executes correctly (<a name="0016-PFUT-012" href="#0016-PFUT-012">0016-PFUT-012</a>) | ||||||
1. After trading termination has been triggered the trading terminated data source is no longer active (assuming it is not used anywhere else) and data from that source is no longer processed. (<a name="0016-PFUT-013" href="#0016-PFUT-013">0016-PFUT-013</a>) | ||||||
1. After settlement data has been recieved and the market has settled, the settlement data source is no longer active (assuming it is not used anywhere else) and data from that source is no longer processed. (<a name="0016-PFUT-014" href="#0016-PFUT-014">0016-PFUT-014</a>) | ||||||
1. After settlement data has been recieved and the market has not settled yet because trading termination has not been triggered, the settlement data source is remains active (assuming it is not used anywhere else) and data from that source is still processed (because each updated data event recieved is stored and eventually used for settlement up until trading terminated it triggered). (<a name="0016-PFUT-015" href="#0016-PFUT-015">0016-PFUT-015</a>) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this test I think it needs to no be used elsewhere rather than left up to the implementer whether it is or not. Or perhaps there should even be 2 ACs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe two ACs. |
||||||
1. Where the same oracle definition is used for trading terminated and settlement, and data has been recieved. Trading is terminated and the market is settled with the same data event (a single message does both). The data source is no longer active (assuming it is not used anywhere else) and data from that source is no longer processed. (<a name="0016-PFUT-016" href="#0016-PFUT-016">0016-PFUT-016</a>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder whether we always want to do that. Imagine data that are of the form
[timestamp, price]
. Now imagine I receive first[2022-09-01-23:59, price1]
and later I receive something with earlier timestamp[2022-09-01-12:00, price2]
. In this case I doubt we'd want to replace the settlement data with the newer event.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was the thinking behind the original spec attempts — normally settlement, valuation, etc. happen with the first price printed after or exactly for the appropriate timestamp. I've never seen a system where if you want to expire something and you have two prices in a feed that are after the fixing time you'd use the later one. If you want more recent data, usually you would specify that (with a filter or by having a data source that doesn't send data that is too old at all). But here we are…
There have been three iterations of the spec for this:
1st attempt: take the first data that matches and is received after you are in a state where you are ready to settle the market.
2nd attempt: take the first data that matches and is received after the enactment of the market whether or not it is ready to settle yet
3rd attempt (now): take the most recent data received after the enactment of the market (if trading is terminated before any data is received, this will also be the first data received)
Note that my preference and the original design was for (1). Though it was vulnerable to potentially dropping the real preferred data due to a late trading termination trigger, and perhaps even never settling at all:
We then went via iteration (2) to always use the first data, which, like (1) avoids the problem you mention in your comment but with trade-off of less likely to need governance but more likely to suffer whatever issues out of order termination vs settlement might cause. I am not sure why this change was made but it may simply have been to try to align with what we thought had been built and because it seeemed "good enough".
Now we have (3), which I'm pretty sure boils down to discovering it doesn't work like (2) either and agreeing to change the spec to match implementation. I can't remember if anyone argued it was actually preferable to (1) or (2) but I think there might have been some discussion in that direction…
Anyhow:
So I don't know if we want to change anything now. But I do agree what we have isn't particularly good, doesn't compose well with other features, adds complexity, etc. (though it clearly is workable).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want to go back to (1). I wouldn't require it for "enable trading" but we may want to do it anyway... (because writing one set of tests now and rewriting is a pain.
My reasoning: it's better to miss a settlement data transaction (this can be fixed be governance) than a situation where someone can try to submit an "old coinbase price" on a market without a filter just before trading terminated.