-
Notifications
You must be signed in to change notification settings - Fork 221
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
TimerService emits branded TimeStampRecord/RelativeTimeRecord #6904
Conversation
@@ -301,7 +301,7 @@ export function makeOnewayPriceAuthorityKit(opts) { | |||
return quote; | |||
}, | |||
async quoteAtTime(deadline, amountIn, brandOut) { | |||
assert.typeof(deadline, 'bigint'); | |||
assert.typeof(deadline, 'object'); // Timestamp |
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.
fit(deadline, TIMESTAMP_SHAPE);
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.
@Chris-Hibbert I've got a patch for this:
async quoteAtTime(deadline, amountIn, brandOut) {
+ mustMatch(deadline, TimestampShape);
AmountMath.coerce(actualBrandIn, amountIn);
assertBrands(amountIn.brand, brandOut);
but I'm worried that it will impose a change on the clients of Zoe that they may not be prepared to handle yet. We decided to reduce the goals of this PR: have the timerService return branded timestamps, but accept either. So a lot of the changes are to ensure that when Zoe receives a timestamp, it can deal with it, but we want to keep everything tolerant of code that' still sending plain BigInts into time stuff, including zoe. If we can get that into the Vaults release, then contracts can begin to write code that matches our long-term goals (always use brands), because both "send bigints, accept brands" and "send brands, accept brands" will work.
Do you think I should apply this mustMatch
change?
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.
For this one, we decided to use deadline = coerceToTimestampRecord(deadline, timerBrand)
, which will accept any of number | bigint | TimestampRecord (with correct brand)
, but reject TimestampRecords with the wrong brand.
This will succeed or fail in exactly the same situations as the current PR's lack of any assertions, but the failure will happen as the first line of quoteAtTime
, instead of happening inside the timer service a moment later.
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.
Actually, this is turning out to be awkward to implement. The enclosing function (makeOnewayPriceAuthorityKit
) is not async
, which means I can't do timerBrand = await E(timerService).getTimerBrand()
outside of each call to quoteAtTime
call (which would add some overhead that I'd like to avoid). The next earliest place to fetch the brand is in the four callers to makeOnewayPriceAuthorityKit()
:
- zoe/src/contracts/priceAggregator.js
- inter-protocol/src/price/fluxAggregatorKit.js
- zoe/tools/manualPriceAuthority.js
- zoe/tools/scriptedPriceAuthority.js
The first two are async, and not a problem. The zoe/tools/
ones are sync, but it probably also use a local (manual)TimerService, so in theory I can just do timerBrand = timerService.getTimerBrand()
, but the typechecker complains because it thinks that timerService
is an ERef.
I think I'm not going to fix this one, and rely upon TimerService complaining about a mismatched brand, instead of trying to catch it slightly earlier.
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.
Since the two sync calls are from test tools, it would be fine to // @ts-expect-error
them.
b7c6492
to
f69d791
Compare
f69d791
to
0ba5adc
Compare
0ba5adc
to
a4274dd
Compare
@warner I've rebased and refreshed this PR, and think I've fixed the zoe tests but not yet the inter-protocol ones. Can you check that it's on the right track? |
amountIn: { brand: remotable('$ATOM brand'), value: 1n }, | ||
amountOut: { brand: remotable('$USD brand'), value: 1020n }, | ||
timer: remotable('ManualTimer'), | ||
timestamp: { timerBrand: remotable('timerBrand'), absValue: 1n }, |
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.
this should probably use the coerce
or toAbs
-type helper, so we can keep the property names (timerBrand
and absValue
) semi-private to the implementation
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.
This makes sense, but not in a time crunch IMO (especially since there are other similar flavors). How would you feel about deferral?
@warner @Chris-Hibbert I just pushed changes that should resolve everything outside of inter-protocol, but I'm going to be away all weekend and don't know if I'll have a chance to address that package before Monday. I'll try to do more tonight, but please feel free to take the baton. |
I pushed a couple of changes to address those issues, and to fix the inter-protocol tests. We'll see how CI feels about them. |
1f94a77
to
a586df9
Compare
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.
CI is green!
packages/inter-protocol/test/price/snapshots/test-fluxAggregatorKit.js.md
Show resolved
Hide resolved
Ok @erights said to go ahead without his review. I'll rebase and squash now. |
e992f54
to
d6989a4
Compare
fcc8e42
to
ead3251
Compare
The service still accepts both branded and unbranded (i.e. bigint) TimestampValue and RelativeTimeValue, but all emitted values (`getCurrentTimestamp`, `handler.wake()` callbacks, Promise resolution values, Notifier updates) will be branded records. Client code must be prepared to accept these, in particular it must use TimeMath.compareAbs() to compare two timestamps, since they are records (objects), and using `>` will give erroneous results. Client authors should begin the transition process of submitting branded TimestampRecord and RelativeTimeRecord to the TimerService. A future upgrade will stop accepting non-branded values. Also the `TimeMath.toAbs`/`toRel` functions were replaced with `coerceTimestampRecord`/`coerceRelativeTimeRecord`, and accept any of Number, Bigint, or a correctly-branded record. They throw if given a branded record that does not match the target brand in the second argument. This should be used when converting a bare number (supplied by some external code which thinks it understands time) to a record suitable for submitting to the future (strict) TimerService. refs #6003 Co-authored-by: Richard Gibson <[email protected]>
The service still accepts both branded and unbranded (i.e. bigint) TimestampValue and RelativeTimeValue, but all emitted values (`getCurrentTimestamp`, `handler.wake()` callbacks, Promise resolution values, Notifier updates) will be branded records. The manual-timer.js mock accepts bigints on the control surface, for convenience, but returns branded TimestampRecord to API callers, just like the real vat-timer. Some additional conveniences were added. refs #6003 Co-authored-by: Richard Gibson <[email protected]>
Also update some testing tools like manualTimer.js and the fake price authority Co-authored-by: Richard Gibson <[email protected]>
Co-authored-by: Richard Gibson <[email protected]>
Co-authored-by: Richard Gibson <[email protected]>
ead3251
to
8369dd6
Compare
Change SwingSet vat-timer (aka
TimerService
) to only emit branded TimestampRecord / RelativeTimeRecord. The service continues to accept non-branded values (BigInts), but the payloads of handler callbacks andgetCurrentTimestamp()
will be a record with a.timerBrand
property.Change zoe/inter-protocol/etc to accomodate this. Most contracts still use plain BigInts internally.
We will finish the transition later, by changing the TimerService to only accept branded records, and reject plain BigInts.
refs #6003