endo icon indicating copy to clipboard operation
endo copied to clipboard

enable stamps / trademarks using shared pure modules?

Open dckc opened this issue 4 years ago • 5 comments

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

dckc avatar Sep 28 '21 13:09 dckc

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.Proxy before import 'ses'
  • an inescapableGlobalProperty setup by the liveSlots layer.

Edit: issue for the approach above: https://github.com/Agoric/agoric-sdk/issues/3905

mhofman avatar Sep 28 '21 19:09 mhofman

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?

mhofman avatar Sep 28 '21 23:09 mhofman

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.

erights avatar Sep 29 '21 04:09 erights

@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.

erights avatar Sep 29 '21 04:09 erights

See https://github.com/endojs/endo/issues/414

erights avatar Aug 02 '22 06:08 erights

Closing as a dup of #414

erights avatar Jun 08 '23 00:06 erights