[E-Lang] vouching pattern alternatives

Marc Stiegler marcs@skyhunter.com
Sat, 24 Feb 2001 03:07:18 -0700


Here are 2 alternative vouching systems that I believe convey no authority.
The first uses a java WeakHashMap. In this version, you must register
("notarize") each vouchable object as it is created.

The second uses the vat-game-turn private shared variable that freaked markm
out so much a year ago when I invented it for sealer/unsealers :-) In this
version, each vouchable object must implement the privateVouch method. In
the current implementation, it will throw an exception if it receives an
object for vouching that does not respond to privateVouch; I suspect it
should just return null, let me know if you disagree. Or should it always
throw an exception if it gets a null (i.e., unvouched-for) value at the end?

These 2 systems also use different ways of returning the vouching objects.
The systems share the fact that part of the vouching system is closely held,
and the other part is publishable. In the one version, I return a single
closely held object from which you can get the publishable object. In the
other version, I return a private/public pair.

 I have used the terms "notary" and "inspector", which I'm sure someone will
object to because they probably don't quite fit well enough metaphorically,
so alternatives are welcome.

Personally, I prefer the vat-game-turn version because it doesn't depend on
the java weakHashMap, and I worry mildly that it could contain a bug that
would turn into a security breach in this usage. However, markm does have a
weak pointer system in the latest E, so we could probably use a weak key
table without depending on java if someone identifies an advantage in that
strategy.

On the other hand, I think I prefer returning a single private object that
offers a publishable object in preference to returning a pair. When you
return a pair, there are a number of easy programming errors (starting with
not remembering that this is one of those funny Makers that returns a pair,
and ending with the awful possibility of getting mixed up as to whether the
pair is public/private or private/public, with ridiculous and horrific
consequences).

If everyone agrees with both my opinions, then neither of the below
implementations is the correct one, and I'll write the new improved one
after seeing how my opinions get crucified.

--marcs

#vouching system based on java.util.WeakHashMap
#returns single closely held object that allows you to
#get a public object (the inspector)
def notaryMaker new :any {
 def notarizedObjects := <import:java.util.WeakHashMap> new
 def inspector vouch(obj) :any {
  if (notarizedObjects containsKey(obj)) {
   obj
  } else {null}
 }
 def notary {
  to notarize(object) {notarizedObjects put(object,null)}
  to getInspector :any {inspector}
 }
}

#build a maker that offers vouching services
def thingMakerMaker new :any {
 def thingNotary := notaryMaker new
 def thingMaker {
  to new :any {
   def thing run {println("I am vouchable")}
   thingNotary notarize(thing)
   thing
  }
  to getInspector :any {thingNotary getInspector}
 }
}

#test the vouching services
def myThingMaker := thingMakerMaker new
def myThing := myThingMaker new
myThingMaker getInspector vouch(myThing) run
def fake {}
if (myThingMaker getInspector vouch(fake) != null) {
 println("notary vouched falsely")
} else {println("notary spotted fake")}

#----version 2---------

#vouching system based on synchronous private comm
#returns a private/public (notary/inspector) pair
def notaryInspectorPairMaker new :any {
 def currentNotarizedObject := null
 def notary setForInspection(obj) { currentNotarizedObject := obj}
 def inspector vouch(obj) :any {
  currentNotarizedObject := null
  obj privateVouch
  currentNotarizedObject
 }
 [notary,inspector]
}

#a maker that offers vouching version2
def fooMakerMaker new :any {
 def [notary,inspector] := notaryInspectorPairMaker new
 def fooMaker {
  to new :any {
   def foo {
    to run {println("I am vouchable")}
    to privateVouch {notary setForInspection(foo)}
   }
  }
  to getInspector :any {inspector}
 }
}

#testing the second vouching system
def myFooMaker := fooMakerMaker new
def myFoo := myFooMaker new
myFooMaker getInspector vouch(myFoo) run
def fake2 privateVouch {}
if (myFooMaker getInspector vouch(fake2) != null) {
 println("notary2 vouched falsely")
} else {println("notary2 spotted fake2")}


interp blockAtTop