-
Notifications
You must be signed in to change notification settings - Fork 72
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
refactor(cli,daemon): start replacing Far with makeExo #2118
Conversation
6981d64
to
ac879ac
Compare
Attn @rekmarks @kumavis @danfinlay since this impacts the daemon and CLI, which we’re maintaining together going forward. I’m not sure what role |
And, I would like one of us to pick this up and run with it, consulting @erights so we can discover socialize the migration experience. |
Thanks. Staying in Draft in any case until we have evidence that the performance impact is not too bad. But see "Security Considerations" for why it is important. Though still not urgent. UpdateAbove I say
Since this PR makes this change only to |
ac879ac
to
c63a335
Compare
c63a335
to
840ebc6
Compare
This is now R4R @dtribble @ivanlei , I removed you as reviewers. @kriskowal @kumavis @rekmarks @gibson042 I added you as the reviewers. I'm still getting the static CI error mentioned under "Testing Considerations" in the PR comment. It is something about TypeScript generated files that I cannot figure out. Need help. Attn @turadg @michaelfig ? |
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.
The TypeScript errors in CI are opaque to me. |
Something with the templated type imports. 96a15b5 |
96a15b5
to
627ebed
Compare
Hi @turadg, thanks! But still getting the symptom at https://github.com/endojs/endo/actions/runs/8411192334/job/23030512852?pr=2118#step:9:76 |
Looks like you force pushed over the commit with the fix and it's gone. I'll try to retrive it when I'm back at my work computer. |
The 'import by redefine' was causing an error resolving the template parameters. e.g. M was M_1 in the slot, but with no binding. I don't know if it was due to bug in TS, but bumping to the latest (5.4.3) didn't solve it.
When I did Anyway, 5be642f adds the fix now. |
to wit: |
closes: #XXXX
refs: #XXXX
Description
To teach people how to write upgradable code, we should stop teaching
Far
and start teaching use of exo-making operations. This first step makes the easiest such transition, with the following mostly automated steps (that should also apply to agoric-sdk):Far\('(.*)', \{
with:
makeExo('$1', M.interface('$1', {}, { defaultGuards: 'passable' }), {
yarn format
Far
import when no longer used,"@endo/exo"
and"@endo/patterns"
makeExo
is implicitly heap-only, whereas we should really transition to the appropriate zones, including the heap zone. But the zone package has not yet been moved from agoric-sdk to endo, so this is not yet possible here. In any case, it can follow as a later step.The use of
defaultGuards:
is how we skip needing to write the method guards in this first step. This enables incremental progress from there of writing accurate method guards.Security Considerations
If this PR rewrote these to
defaultGuards: 'raw'
, then this rewrite would be security equivalent to the original.defaultGuards: 'passable'
does enforce the minimal requirement we need for separation at exo boundaries, which is that only passable values get directly passed in or out. However, this doesn't actually make the exo boundary a defensive boundary until we complete three tasksFar
. Hence this PR.M.await(pattern)
(withM.callWhen
) for promises that should or could be awaited before the raw method is called. This checks the fulfillment against the argument pattern.M.await
ed there.toPassableError
. Ensure anything else thrown is rethrown as something that it at least Passable, and likely also required to be pure data.So, again, this PR is just a step towards those goals.
As the interface guards are incrementally refined with proper method guards, we get a huge increase in defensive input validation. The underlying raw method will never see arguments that did not pass those method guards. The raw method code must still do any input validation of such guard-passing arguments, but this is a much smaller burden.
This is why our rewrite puts a per-makeExo interface inline, rather than just referring to a shared one or even saying
undefined
: To encourage the incremental expansion of these with accurate method guards.Once all methods have explicit method guards, the
defaultGuards:
option should be removed.Scaling Considerations
All this extra checking that arguments and return results are Passable is extra overhead that may be significant. Likely bottlenecking on
passStyleOf
that we already know is a painful hotspot. We'll only know how bad this is by measuring.Documentation Considerations
This is largely the point of this PR, and related upcoming agoric-sdk PRs. People learn to program for our platform by looking at example code. We want to shift from teaching
Far
to teaching exo making patterns to smooth their transition to writing upgradable code.Testing Considerations
All dynamic CI checks pass with this change, which is a bit of a surprise. Whether it is a pleasant or unpleasant surprise depends on whether this indicates the transition has no problems, or just that the CI tests aren't catching those problems. The likely problems are do to using
defaultGuards: 'passable'
rather thandefaultGuards: 'raw'
. It was perfectly correct to call Far objects with non-passable arguments. If such uses were covered by CI, we should have gotten a visible failure.Currently, CI is giving a static error
I don't understand this error and will need help figuring out what to do about it.
Compatibility Considerations
By using
defaultGuards: 'passable'
rather thandefaultGuards: 'raw'
, we do have a chance of breaking caller that were correct.Upgrade Considerations
Since neither
Far
normakeExo
make durable things, this first step has no effect on upgrade. Further, the abstractions changed by this PR are unlikely to become durable in the future. However, a next step should still change some of these to use a zone defaulting to theheapZone
. To the extent that the abstraction-making code can be parameterized by zone, then it can become up to the caller whether to use the heap zone or not.*BREAKING*:
in the commit message with migration instructions for any breaking change.NEWS.md
for user-facing changes.