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

fix(SwingSet): Restore LRU cache flushing when stopping a vat #6627

Merged
merged 3 commits into from
Dec 16, 2022

Conversation

gibson042
Copy link
Member

Fixes #6604

Description

Restores the bringOutYourDead call mistakenly commented out by #5636. Also resolves a TODO in favor of providing the new root object for an upgraded vat in order to capture it as a future target for messages in testing.

Security Considerations

If anyone sees hazards from returning the new root object of an upgraded vat, please let me know. But it seems to me that the ability to upgrade a vat is already an inherently greater capability.

Documentation Considerations

I didn't see anything documenting the old incarnationNumber argument that is being upgraded to { incarnationNumber, rootObject }, so I don't think there's anything to change.

Testing Considerations

This PR introduces a general bootstrap-relay testing bootstrap vat with { createVat, upgradeVat, messageVat, messageVatObject, awaitVatObject } functions operating on a map of named vats that can help keep testing code together rather than forcing test scripts into vat code as is currently the prevailing pattern. See testNullUpgrade in packages/SwingSet/test/upgrade/test-upgrade.js for example use. I'm not sure where to document it, though, so it will be something of an oral tradition for now.

@gibson042 gibson042 requested review from warner and FUDCo December 5, 2022 21:34
@FUDCo
Copy link
Contributor

FUDCo commented Dec 5, 2022

Providing the root object again seems reasonable to me. As currently implemented, the identity of the root object does not change under upgrade, so providing it again is just a convenience that I don't believe introduces any new authority. However, if in the future we allow upgrade to change the root object identity we might need to reconsider this, as such a change would have the side effect of invalidating prior references to the root object and making this a genuine authority issue. I can't think of any reason why we'd want to do that, but I can't really think of any reason why we wouldn't either, aside from the inconvenience of actually implementing it. On the other hand, I think so much other stuff would break if we did that that I suspect the question would only arise in the context of addressing some serious problem, which necessarily implies rethinking a lot of stuff anyway.

TL;DR: go for it.

Copy link
Contributor

@FUDCo FUDCo left a comment

Choose a reason for hiding this comment

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

Looks good to me, but you should probably still wait for Brian to weigh in too before merging.

Copy link
Member

@warner warner left a comment

Choose a reason for hiding this comment

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

Looks good, please make the change to the test (assert that the re-supplied root object has the same identity as the original), and let's see if @erights has thoughts about the re-supply.

upgradeID,
true,
undefined,
{ incarnationNumber, rootObject: kslot(kernelRootObjSlot) },
Copy link
Member

Choose a reason for hiding this comment

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

Hm.

You're right that there's nothing fundamentally wrong about re-supplying the root object in the result value of the upgrade request: anybody who had access to the control facet would have been given the root object the first time around, and it's unlikely that someone would go and split those authorities ("I'm going to let you upgrade this vat but not access the root object"??).

My hesitation is that re-supplying it lends the impression that each version has its own root, whereas really each version has its own implementation of a shared root-object identity. Re-supplying it raises the possibility that the root returned by upgradeVat might be different than the one you got from createVat. Not re-supplying it removes that concept entirely.

OTOH, I can imagine an upgrade scenario in which the original caller failed to retain the root object (maybe they used it to build a secondary object and then dropped it), and now they wish they'd kept it around (perhaps to make another secondary object). Doing a null upgrade with this re-supply feature would let them recover from that mistake.

So.. ok, let's leave it in. But let's add a note to the upgradeVat documentation to make it clear that this is a second copy of the same original object, and that it's not like upgradeVat is creating a new identity.

Copy link
Member

Choose a reason for hiding this comment

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

Actually @erights do you have any opinion on this? Should having the control facet for a vat (which allows terminateVat and upgradeVat) also give you access to the root object for that vat? Can you imagine a scenario in which it would be surprising for upgradeVat() (which previously only returned the new incarnation number, powerless) to lead to that root object?

}
console.log(`note: expect a '${complaint}' error below`);
Copy link
Member

Choose a reason for hiding this comment

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

let's retain the // TODO: who should see the details of what v2 did wrong? calling vat? only the console? comment from the original, I think we still need to find an answer for that question

t.deepEqual(v2result.upgradeResult, { incarnationNumber: 2 });
t.deepEqual(v2result.upgradeResult, {
incarnationNumber: 2,
rootObject: v2result.upgradeResult?.rootObject,
Copy link
Member

Choose a reason for hiding this comment

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

If we're going to re-supply the root object, we should assert that it's the same identity as the original, else this test is also contributing to the confusion.

kunser retains a module-level Map of the ersatz Presences it creates, so we just need the original buildV1 to return us ulrikRoot along with everything else, then in testUpgrade we can stash it. Then this comparison changes rootObject: v2result.upgradeResult?.rootObject into rootObject: ulrikRoot.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hrm, when I check the analogous situation in the new null-upgrade test I see that root object identity is not preserved:

  Difference (- actual, + expected):

    Object @Alleged: undefined {
  -   getKref: Function getKref {},
  +   getKref: Function getKref {},
  -   iface: Function iface {},
  +   iface: Function iface {},
    }

But all the other assertions still pass and the result from getKref() does match, so I'm going to revert the processUpgradeVat changes.

@warner warner requested a review from erights December 14, 2022 19:35
@gibson042 gibson042 force-pushed the gibson-6604-stopvat-flush-cache branch from b5e845e to 2015a0a Compare December 16, 2022 05:30
@gibson042 gibson042 added the automerge:rebase Automatically rebase updates, then merge label Dec 16, 2022
@mergify mergify bot merged commit ea49c84 into master Dec 16, 2022
@mergify mergify bot deleted the gibson-6604-stopvat-flush-cache branch December 16, 2022 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

stopVat is not flushing the LRU cache
3 participants