-
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
contract upgrade proposals fragile due to promiseSpace reset strange behavior #7709
Comments
The basic problem is that This is triggered by a pattern in @dckc 's init-proposal test, which wasn't in the unit tests:
If the To fix this best, I think we should remove the closed-over variables |
Is the abstraction buggy in a way revealed by the test? Or is the test buggy in that it assumes a stronger property of the abstraction than the abstraction is supposed to provide? |
I think it's the former. It should be legal to capture both |
Previously, the reset() feature misbehaved in a common use pattern, where both the `reset` and `resolve` facets were extracted at the same time. The state was nominally held in `nameToState.get(name)`, but was sometimes used by closed-over `state` and `pk` variables. Which one you got depended upon when the Proxy `get` trap was called. If `resolve` was fetched early and retained across a `reset()` call, then `resolve()` would resolve the *old* promise. Later, when `consume` was used, the space would create a new Promise to satisfy the request, which would never be resolved. This changes the implementation to strictly keep/use the state in `nameToState`, and allow all resolve/reject/reset methods to work the same way no matter when they were retrieved (they close over `name` but not any state). closes #7709
Previously, the reset() feature misbehaved in a common use pattern, where both the `reset` and `resolve` facets were extracted at the same time. The state was nominally held in `nameToState.get(name)`, but was sometimes used by closed-over `state` and `pk` variables. Which one you got depended upon when the Proxy `get` trap was called. If `resolve` was fetched early and retained across a `reset()` call, then `resolve()` would resolve the *old* promise. Later, when `consume` was used, the space would create a new Promise to satisfy the request, which would never be resolved. This changes the implementation to strictly keep/use the state in `nameToState`, and allow all resolve/reject/reset methods to work the same way no matter when they were retrieved (they close over `name` but not any state). closes #7709
Previously, the reset() feature misbehaved in a common use pattern, where both the `reset` and `resolve` facets were extracted at the same time. The state was nominally held in `nameToState.get(name)`, but was sometimes used by closed-over `state` and `pk` variables. Which one you got depended upon when the Proxy `get` trap was called. If `resolve` was fetched early and retained across a `reset()` call, then `resolve()` would resolve the *old* promise. Later, when `consume` was used, the space would create a new Promise to satisfy the request, which would never be resolved. This changes the implementation to strictly keep/use the state in `nameToState`, and allow all resolve/reject/reset methods to work the same way no matter when they were retrieved (they close over `name` but not any state). closes #7709
Previously, the reset() feature misbehaved in a common use pattern, where both the `reset` and `resolve` facets were extracted at the same time. The state was nominally held in `nameToState.get(name)`, but was sometimes used by closed-over `state` and `pk` variables. Which one you got depended upon when the Proxy `get` trap was called. If `resolve` was fetched early and retained across a `reset()` call, then `resolve()` would resolve the *old* promise. Later, when `consume` was used, the space would create a new Promise to satisfy the request, which would never be resolved. This changes the implementation to strictly keep/use the state in `nameToState`, and allow all resolve/reject/reset methods to work the same way no matter when they were retrieved (they close over `name` but not any state). closes #7709
Previously, the reset() feature misbehaved in a common use pattern, where both the `reset` and `resolve` facets were extracted at the same time. The state was nominally held in `nameToState.get(name)`, but was sometimes used by closed-over `state` and `pk` variables. Which one you got depended upon when the Proxy `get` trap was called. If `resolve` was fetched early and retained across a `reset()` call, then `resolve()` would resolve the *old* promise. Later, when `consume` was used, the space would create a new Promise to satisfy the request, which would never be resolved. This changes the implementation to strictly keep/use the state in `nameToState`, and allow all resolve/reject/reset methods to work the same way no matter when they were retrieved (they close over `name` but not any state). closes #7709
Describe the bug
while working on upgrade testing (#6099) we ran into strange behavior that causes subtle failures in core eval proposals.
it seems to come down to a bug around the
reset()
method frommakePromiseSpace
.To Reproduce
Steps to reproduce the behavior:
Expected behavior
test above ^ passes. Perhaps some other design constraints need some thought.
Platform Environment
git describe --tags --always
)Additional context
Add any other context about the problem here.
Screenshots
If applicable, add screenshots to help explain your problem, especially for UI interactions.
cc @michaelfig @turadg @warner
The text was updated successfully, but these errors were encountered: