enable stamps / trademarks using shared pure modules?
In a discussion about input validation to avoid reentrancy risks in cases such as amount.brand, I asked whether stamps (a la ejectorsGuardsTrademarks.js would work?
@erights writes:
... the path to stamps runs into a roadblock that the endo bundler + compartments may enable us to finally fix. The roadblock is that all of our modules are written to be multiply instantiated, because we didn't have enough control of the bundling and loading process to ensure there was only one instance of, for example, marshal.js. marshal.js used to stamp the far objects it made using a weakmap or weakset. However, with multiple instantiations, the far object made by one was not recognized as far by another. As a result, we've been avoiding this basic tool of ocap design all over our system. Marshal, for example, when to a structure validation scheme. If it passes, it is stamped by a weakMap local to that marshal. But only for efficiency. If another marshal is asked about the same structure it will re-validate and then apply its own stamp for its own efficiency. ... with the endo bundler + compartments, can we solve this now? With it together with the Proxy+passStyleOf trick I outline below (a kind of Records & Tuples shim), the passStyleOf pattern that is already most pleasant for so much of our input validation would also protect against proxy-handler-reentrancy without additional programmer effort. Currently, this reentrancy problem is really rather horrible. Like fatally horrible for normal ocap programming.
cc @mhofman
The current thinking to avoid the purity conundrum is to have trusted code replace the Proxy constructor with a version that stamps proxy instances it creates (adds them to a WeakSet), and return a power to check the stamp. The power can then be endowed to the passStyleOf helper (threading TBD).
This can currently be accomplished either as:
- a "trusted shim" which patches
globalThis.Proxybeforeimport 'ses' - an
inescapableGlobalPropertysetup by theliveSlotslayer.
Edit: issue for the approach above: https://github.com/Agoric/agoric-sdk/issues/3905
After thinking about this more, I do not believe pure modules would actually be able to help with stamps since by definition checking for a stamp would be an impure action. Did I miss something?
What you missed is something I have not explained yet. It will be a stretch but I think a necessary one. We can build a branding abstraction that is not observably impure out of an impure weakmap. Once we satisfy ourselves that the abstraction is pure, we deem it pure even though it is not checkably pure by the normal checks. I need to write something up about it.
Earlier, when I talked about pure modules containing classes that could recognize their instances, I mentioned "except for one counterfactual which I need to explain". To recognize their instances, the instances must have private fields. But a class with private fields can only be stateless if attribute the private fields to the instances. If the class is a base class with private fields, this works. If it is a subclass of a super that might do a return override, it is not. That can only be explained by attributing the mutability to the class, rendering it impure. That's why I was excited when Shu explained his structs as a restricted form of classes, where among the restrictions was that it could only inherit from another struct class. The struct class is a perfect example of something that can be pure but still recognize its instances via a shared unforgeable identity.
@michaelfig and I carefully designed the handled promise abstraction so that it could recognize its own presences without creating observable impurity. That's why the resolveWithPresence must return a fresh object. If it could be told to stamp an already existing object with a checkable stamp (as return override + private properties do), then it would be observably impure. That's what my abstraction-to-be-explained does, and what Shu's structs do.
See https://github.com/endojs/endo/issues/414
Closing as a dup of #414