-
Notifications
You must be signed in to change notification settings - Fork 228
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
5346 replace uses of makeNotifierKit with makeNotifierFromSubscriber #5704
Conversation
662351c
to
6594619
Compare
packages/notifier/src/storesub.js
Outdated
if (!storageNode) { | ||
return {}; | ||
} | ||
return E(storageNode).getStoreKey(); |
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'm surprised by this divergence between storageNode
being falsy vs. fulfilling with a falsy value, but it probably won't come up in practice.
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.
do you mean you'd expect this to return falsy when storageNode is falsy? agreed. I tried returning null but ran into a type error.
I'll leave this conversation open to come back to it. Let me know if you're talking about somethign else
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, and also that a falsy storageNode is accepted while a storageNode that resolves to a falsy value (e.g., Promise.resolve(undefined)
) results in an exception. I think this also intersects my concern about allowing invocation without a valid storage node, which seems to unnecessarily complicate things (e.g., note how the output from getStoreKey
is meaningless in such a configuration).
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 agree with the perspective. In production, the storageNode and marshaller should always be there so it would be fine to require it. In tests, they aren't always. I think it would be better to solve that, but pragmatically I'm not sure it's worth it.
If I can't remove the kludge in the tests, I'll at least remove it from @agoric/notifier
and make the contracts deal with it.
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.
In production, the storageNode and marshaller should always be there
We have the sim chain, which while perhaps not production, is supported for smart contract development work. In the sim chain, there's no chainStorage.
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.
Thanks, that's the thing I was trying to remember. Since it's a "sim" chain, would it be reasonable to simulate chainStorage? E.g. in-memory stoageNode, identity marshaller.
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.
oh. yeah. in-memory chainStorage would be great.
identity doesn't work as a marshaller, cuz the output has to be a string and the input is not constrained that way. But I think you can always use a vanilla output from makeMarshal()
.
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.
Made it required and updated bootstrap to always provide it cbaa70b, falling back to a no-op "NullStorageNode" when ChainStorage isn't available.
publisher.publish(initialValue); | ||
const storesub = makeStoredSubscriber(subscriber, storage); | ||
|
||
t.deepEqual(await E(storesub).getStoreKey(), await E(storage).getStoreKey()); |
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 may be highlighting a gap in makeFakeStorage
; I would expect the key to be defined as part of its initialization rather than dynamic like this.
6594619
to
9591dfe
Compare
use case: list of vaults by risk cc @btulloh |
Where is the code that makes a |
3c29431
to
fb4b156
Compare
YTBD. Right now just trying to refactor existing behavior to use |
fb4b156
to
9e13972
Compare
9e13972
to
3f195cc
Compare
d7c5b6c
to
6e2ebd5
Compare
b33b192
to
cbaa70b
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.
Looks pretty good... at least: I don't see any serious problems.
I'm a little fuzzy on the details; I'm relying somewhat on test coverage, static typing, and discussion with @gibson042 and co.
getNotifier: ({ state }) => state.assetNotifier, | ||
getNotifier: ({ state }) => makeNotifierFromSubscriber(state.assetSubscriber), |
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.
Perhaps add a "we make a new notifier on each call that has no memory of previous states" comment?
The difference between these is subtle. I was a about to ask why we make a new one on each call when I remembered the whole prefix-lossy concept.
getNotifier: ({ state }) => state.assetNotifier, | ||
getNotifier: ({ state }) => state.assetSubscriber, |
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.
is this an internal API? rename it to getSubscriber
?
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.
looks like it got renamed later
@@ -662,7 +666,8 @@ test('update liquidator', async t => { | |||
}), | |||
); | |||
await eventLoopIteration(); | |||
govNotify = await d.managerNotified(); | |||
// ??? why is AT_NEXT necessary now |
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 don't know; I wonder if I'm sufficiently up-to-speed to review this...
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.
looks like that went away in a later commit
*/ | ||
export const makeVaultKit = (vault, assetSubscriber) => { | ||
const { holder, helper } = makeVaultHolder(vault); | ||
const vaultKit = harden({ | ||
publicNotifiers: { | ||
vault: holder.getNotifier(), | ||
asset: assetSubscriber, | ||
asset: makeNotifierFromSubscriber(assetSubscriber), |
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.
we make this notifier just once? not a new prefix-lossy one on demand?
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.
right, this is interim. the contract shouldn't be making Notifiers at all because that costs state tracking. Change in next PR.
@@ -50,7 +50,7 @@ export async function start(zcf, privateArgs) { | |||
|
|||
const { zcfSeat: stage } = zcf.makeEmptySeatKit(); | |||
|
|||
const { notifier: managerNotifier } = makeNotifierKit(); | |||
const { subscriber: assetSubscriber } = makePublishKit(); |
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.
we throw away the publisher? how does it every get updated?
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.
It doesn't, this is the fake contract
locked: aeth.makeEmpty(), | ||
updateCount: undefined, | ||
}, | ||
// ??? why is AT_NEXT necessary now |
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.
again, good question
* @property {ERef<Notifier<Timestamp>>} notifier | ||
* @property {ERef<Notifier<unknown>>} notifier |
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 is a relaxation of a type constraint? Any particular reason?
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.
It was wrong
chainStorageP.resolve(undefined); | ||
chainStorageP.resolve(null); |
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.
why change undefined
to null
?
You were considering an in-memory chainStorage; that didn't work out?
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.
Because when there's no chain storage available, it's defined to be missing. I think that's better expressed as null.
cbaa70b
to
ec40f84
Compare
refs: #5346
Description
This with #5739 will enable #5386
This one removes
makeNotifierKit
from VaultFactory without changing its API. Next will update the external API to provide Subscriber, for off-chain reads.Review recommendation: by commit
Security Considerations
--
Documentation Considerations
--
Testing Considerations
Tests needed updates for refactors, but there should be no change in behavior.
Also test locally
agoric start --reset
to ensure sim-chain hasn't broken on making storageNode and marshaller no longer optional.