Browse Source

Merge branch 'ocapn-ids-rename' into 'master'

Rename machine to node in CapTP

See merge request spritely/goblins!35
merge-requests/24/merge
Christine Lemmer-Webber 3 years ago
parent
commit
cd542d3e2a
  1. 290
      goblins/core.rkt
  2. 50
      goblins/ocapn/captp-test.rkt
  3. 83
      goblins/ocapn/captp.rkt
  4. 20
      goblins/ocapn/netlayer/fake-intarwebs.rkt
  5. 14
      goblins/ocapn/netlayer/onion.rkt
  6. 212
      goblins/ocapn/structs-urls.rkt
  7. 2
      goblins/scribblings/captp.scrbl
  8. 2
      goblins/vat.rkt

290
goblins/core.rkt

@ -155,8 +155,8 @@
;;; Here's an image to get started:
;;;
;;; .----------------------------------. .-------------------.
;;; | Machine 1 | | Machine 2 |
;;; | ========= | | ========= |
;;; | Node 1 | | Node 2 |
;;; | ====== | | ====== |
;;; | | | |
;;; | .--------------. .---------. .-. .-. |
;;; | | Vat A | | Vat B | | \______| \_ .----------. |
@ -185,21 +185,21 @@
;;; Alfred are both objects in Vat A, Bob is an object in Vat B, and
;;; Carol and Carlos are objects in Vat C.
;;;
;;; - Zooming out the farthest is the "machine/network level".
;;; There are two machines (Machine 1 and Machine 2) connected over a
;;; Goblins CapTP network. The stubby shapes on the borders between the
;;; machines represent the directions of references Machine 1 has to
;;; objects in Machine 2 (at the top) and references Machine 2 has to
;;; Machine 1. Both machines in this diagram are cooperating to preserve
;;; - Zooming out the farthest is the "node/network level".
;;; There are two nodes (Node 1 and Node 2) connected over CapTP network.
;;; The stubby shapes on the borders between the
;;; nodes represent the directions of references Node 1 has to
;;; objects in Node 2 (at the top) and references Node 2 has to
;;; Node 1. Both nodes in this diagram are cooperating to preserve
;;; that Bob has access to Carol but that Carol does not have access to
;;; Bob, and that Carlos has access to Bob but Bob does not have access
;;; to Carlos. (However there is no strict guarantee from either
;;; machine's perspective that this is the case... generally it's in
;;; node's perspective that this is the case... generally it's in
;;; everyone's best interests to take a "principle of least authority"
;;; approach though so usually it is.)
;;;
;;; This illustration is what's sometimes called a "grannovetter diagram"
;;; in the ocap community, inspired by the kinds of diagrams in Mark
;;; in the OCap community, inspired by the kinds of diagrams in Mark
;;; S. Grannovetter's "The Strength of Weak Ties" paper. The connection is
;;; that while the "Weak Ties" paper was describing the kinds of social
;;; connections between people (Alice knows Bob, Bob knows Carol), similar
@ -215,143 +215,143 @@
;;;
;;; Generally, things look like so:
;;;
;;; (machine (vat (actormap {refr: (mactor object-handler)})))
;;; (node (vat (actormap {refr: (mactor object-handler)})))
;;;
;;; However, we could really benefit from looking at those in more detail,
;;; so from the outermost layer in...
;;;
;;; .--- A machine in Goblins is basically an OS process.
;;; .--- A node in Goblins is basically an OS process.
;;; | However, the broader Goblins CapTP/MachineTP network is
;;; | made up of many machines. A connection to another machine
;;; | is the closest amount of "assurance" a Goblins machine has
;;; | made up of many nodes. A connection to another node
;;; | is the closest amount of "assurance" a Goblins node has
;;; | that it is delivering to a specific destination.
;;; | Nonetheless, Goblins users generally operate at the object
;;; | reference level of abstraction, even across machines.
;;; | reference level of abstraction, even across nodes.
;;; |
;;; | An object reference on the same machine is considered
;;; | "local" and an object reference on another machine is
;;; | An object reference on the same node is considered
;;; | "local" and an object reference on another node is
;;; | considered "remote".
;;; |
;;; | .--- Chris: "How about I call this 'hive'?"
;;; | | Ocap community: "We hate that, use 'vat'"
;;; | | Everyone else: "What's a 'vat' what a weird name"
;;; | |
;;; | | A vat is a traditional ocap term, both a container for
;;; | | objects but most importantly an event loop that
;;; | | communicates with other event loops. Vats operate
;;; | | "one turn at a time"... a toplevel message is handled
;;; | | for some object which is transactional; either it happens
;;; | | or, if something bad happens in-between, no effects occur
;;; | | at all (except that a promise waiting for the result of
;;; | | this turn is broken).
;;; | |
;;; | | Objects in the same vat are "near", whereas objects in
;;; | | remote vats are "far". (As you may notice, "near" objects
;;; | | can be "near" or "far", but "remote" objects are always
;;; | | "far".)
;;; | |
;;; | | This distinction is important, because Goblins supports
;;; | | both asynchronous messages + promises via `<-` and
;;; | | classic synchronous call-and-return invocations via `$`.
;;; | | However, while any actor can call any other actor via
;;; | | <-, only near actors may use $ for synchronous call-retun
;;; | | invocations. In the general case, a turn starts by
;;; | | delivering to an actor in some vat a message passed with <-,
;;; | | but during that turn many other near actors may be called
;;; | | with $. For example, this allows for implementing transactional
;;; | | actions as transferring money from one account/purse to another
;;; | | with $ in the same vat very easily, while knowing that if
;;; | | something bad happens in this transaction, no actor state
;;; | | changes will be committed (though listeners waiting for
;;; | | the result of its transaction will be informed of its failure);
;;; | | ie, the financial system will not end up in a corrupt state.
;;; | | In this example, it is possible for users all over the network
;;; | | to hold and use purses in this vat, even though this vat is
;;; | | responsible for money transfer between those purses.
;;; | | For an example of such a financial system in E, see
;;; | | "An Ode to the Grannovetter Diagram":
;;; | | http://erights.org/elib/capability/ode/index.html
;;; | |
;;; | | .--- Earlier we said that vats are both an event loop and
;;; | | | a container for storing actor state. Surprise! The
;;; | | | vat is actually wrapping the container, which is called
;;; | | | an "actormap". While vats do not expose their actormaps,
;;; | | | Goblins has made a novel change by allowing actormaps to
;;; | | | be used as independent first-class objects. Most users
;;; | | | will rarely do this, but first-class usage of actormaps
;;; | | | is still useful if integrating Goblins with an existing
;;; | | | event loop (such as one for a video game or a GUI) or for
;;; | | | writing unit tests.
;;; | | |
;;; | | | The keys to actormaps are references (called "refrs")
;;; | | | and the values are current behavior. This is described
;;; | | | below.
;;; | | |
;;; | | | Actormaps also technically operate on "turns", which are
;;; | | | a transactional operation. Once a turn begins, a dynamic
;;; | | | "syscaller" (or "actor context") is initialized so that
;;; | | | actors can make changes within this transaction. At the
;;; | | | end of the turn, the user of actormap-turn is presented
;;; | | | with the transactional actormap (called "transactormap")
;;; | | | which can either be committed or not to the current mutable
;;; | | | actormap state ("whactormap", which stands for
;;; | | | "weak hash actormap"), alongside a queue of messages that
;;; | | | were scheduled to be run from actors in this turn using <-,
;;; | | | and the result of the computation run.
;;; | | |
;;; | | | However, few users will operate using actormap-turn directly,
;;; | | | and will instead either use actormap-poke! (which automatically
;;; | | | commits the transaction if it succeeds or propagates the error)
;;; | | | or actormap-peek (which returns the result but throws away the
;;; | | | transaction; useful for getting a sense of what's going on
;;; | | | without committing any changes to actor state).
;;; | | | Or, even more commonly, they'll just use a vat and never think
;;; | | | about actormaps at all.
;;; | | |
;;; | | | .--- A reference to an object or actor.
;;; | | | | Traditionally called a "ref" by the ocap community, but
;;; | | | | scheme already uses "-ref" everywhere so we call it
;;; | | | | "refr" instead. Whatever.
;;; | | | |
;;; | | | | Anyway, these are the real "capabilities" of Goblins'
;;; | | | | "object capability system". Holding onto one gives you
;;; | | | | authority to make invocations with <- or $, and can be
;;; | | | | passed around to procedure or actor invocations.
;;; | | | | Effectively the "moral equivalent" of a procedure
;;; | | | | reference. If you have it, you can use (and share) it;
;;; | | | | if not, you can't.
;;; | | | |
;;; | | | | Actually, technically these are local-live-refrs...
;;; | | | | see "The World of Refrs" below for the rest of them.
;;; | | | |
;;; | | | | .--- We're now at the "object behavior" side of
;;; | | | | | things. I wish I could avoid talking about
;;; | | | | | "mactors" but we're talking about the actual
;;; | | | | | implementation here so... "mactor" stands for
;;; | | | | | "meta-actor", and really there are a few
;;; | | | | | "core kinds of behavior" (mainly for promises
;;; | | | | | vs object behavior). But in the general case,
;;; | | | | | most objects from a user's perspective are the
;;; | | | | | mactor:object kind, which is just a wrapper
;;; | | | | | around the current object handler (as well as
;;; | | | | | some information to track when this object is
;;; | | | | | "becoming" another kind of object.
;;; | | | | |
;;; | | | | | .--- Finally, "object"... a term that is
;;; | | | | | | unambiguous and well-understood! Well,
;;; | | | | | | "object" in our system means "references
;;; | | | | | | mapping to an encapsulation of state".
;;; | | | | | | Refrs are the reference part, so
;;; | | | | | | object-handlers are the "current state"
;;; | | | | | | part. The time when an object transitions
;;; | | | | | | from "one" behavior to another is when it
;;; | | | | | | returns a new handler wrapped in a "become"
;;; | | | | | | wrapper specific to this object (and
;;; | | | | | | provided to the object at construction
;;; | | | | | | time)
;;; | | | | | |
;;; V V V V V V
;;; (machine (vat (actormap {refr: (mactor object-handler)})))
;;; | .----- Christine: "How about I call this 'hive'?"
;;; | | Ocap community: "We hate that, use 'vat'"
;;; | | Everyone else: "What's a 'vat' what a weird name"
;;; | |
;;; | | A vat is a traditional ocap term, both a container for
;;; | | objects but most importantly an event loop that
;;; | | communicates with other event loops. Vats operate
;;; | | "one turn at a time"... a toplevel message is handled
;;; | | for some object which is transactional; either it happens
;;; | | or, if something bad happens in-between, no effects occur
;;; | | at all (except that a promise waiting for the result of
;;; | | this turn is broken).
;;; | |
;;; | | Objects in the same vat are "near", whereas objects in
;;; | | remote vats are "far". (As you may notice, "near" objects
;;; | | can be "near" or "far", but "remote" objects are always
;;; | | "far".)
;;; | |
;;; | | This distinction is important, because Goblins supports
;;; | | both asynchronous messages + promises via `<-` and
;;; | | classic synchronous call-and-return invocations via `$`.
;;; | | However, while any actor can call any other actor via
;;; | | <-, only near actors may use $ for synchronous call-retun
;;; | | invocations. In the general case, a turn starts by
;;; | | delivering to an actor in some vat a message passed with <-,
;;; | | but during that turn many other near actors may be called
;;; | | with $. For example, this allows for implementing transactional
;;; | | actions as transferring money from one account/purse to another
;;; | | with $ in the same vat very easily, while knowing that if
;;; | | something bad happens in this transaction, no actor state
;;; | | changes will be committed (though listeners waiting for
;;; | | the result of its transaction will be informed of its failure);
;;; | | ie, the financial system will not end up in a corrupt state.
;;; | | In this example, it is possible for users all over the network
;;; | | to hold and use purses in this vat, even though this vat is
;;; | | responsible for money transfer between those purses.
;;; | | For an example of such a financial system in E, see
;;; | | "An Ode to the Grannovetter Diagram":
;;; | | http://erights.org/elib/capability/ode/index.html
;;; | |
;;; | | .--- Earlier we said that vats are both an event loop and
;;; | | | a container for storing actor state. Surprise! The
;;; | | | vat is actually wrapping the container, which is called
;;; | | | an "actormap". While vats do not expose their actormaps,
;;; | | | Goblins has made a novel change by allowing actormaps to
;;; | | | be used as independent first-class objects. Most users
;;; | | | will rarely do this, but first-class usage of actormaps
;;; | | | is still useful if integrating Goblins with an existing
;;; | | | event loop (such as one for a video game or a GUI) or for
;;; | | | writing unit tests.
;;; | | |
;;; | | | The keys to actormaps are references (called "refrs")
;;; | | | and the values are current behavior. This is described
;;; | | | below.
;;; | | |
;;; | | | Actormaps also technically operate on "turns", which are
;;; | | | a transactional operation. Once a turn begins, a dynamic
;;; | | | "syscaller" (or "actor context") is initialized so that
;;; | | | actors can make changes within this transaction. At the
;;; | | | end of the turn, the user of actormap-turn is presented
;;; | | | with the transactional actormap (called "transactormap")
;;; | | | which can either be committed or not to the current mutable
;;; | | | actormap state ("whactormap", which stands for
;;; | | | "weak hash actormap"), alongside a queue of messages that
;;; | | | were scheduled to be run from actors in this turn using <-,
;;; | | | and the result of the computation run.
;;; | | |
;;; | | | However, few users will operate using actormap-turn directly,
;;; | | | and will instead either use actormap-poke! (which automatically
;;; | | | commits the transaction if it succeeds or propagates the error)
;;; | | | or actormap-peek (which returns the result but throws away the
;;; | | | transaction; useful for getting a sense of what's going on
;;; | | | without committing any changes to actor state).
;;; | | | Or, even more commonly, they'll just use a vat and never think
;;; | | | about actormaps at all.
;;; | | |
;;; | | | .--- A reference to an object or actor.
;;; | | | | Traditionally called a "ref" by the ocap community, but
;;; | | | | scheme already uses "-ref" everywhere so we call it
;;; | | | | "refr" instead. Whatever.
;;; | | | |
;;; | | | | Anyway, these are the real "capabilities" of Goblins'
;;; | | | | "object capability system". Holding onto one gives you
;;; | | | | authority to make invocations with <- or $, and can be
;;; | | | | passed around to procedure or actor invocations.
;;; | | | | Effectively the "moral equivalent" of a procedure
;;; | | | | reference. If you have it, you can use (and share) it;
;;; | | | | if not, you can't.
;;; | | | |
;;; | | | | Actually, technically these are local-live-refrs...
;;; | | | | see "The World of Refrs" below for the rest of them.
;;; | | | |
;;; | | | | .--- We're now at the "object behavior" side of
;;; | | | | | things. I wish I could avoid talking about
;;; | | | | | "mactors" but we're talking about the actual
;;; | | | | | implementation here so... "mactor" stands for
;;; | | | | | "meta-actor", and really there are a few
;;; | | | | | "core kinds of behavior" (mainly for promises
;;; | | | | | vs object behavior). But in the general case,
;;; | | | | | most objects from a user's perspective are the
;;; | | | | | mactor:object kind, which is just a wrapper
;;; | | | | | around the current object handler (as well as
;;; | | | | | some information to track when this object is
;;; | | | | | "becoming" another kind of object.
;;; | | | | |
;;; | | | | | .--- Finally, "object"... a term that is
;;; | | | | | | unambiguous and well-understood! Well,
;;; | | | | | | "object" in our system means "references
;;; | | | | | | mapping to an encapsulation of state".
;;; | | | | | | Refrs are the reference part, so
;;; | | | | | | object-handlers are the "current state"
;;; | | | | | | part. The time when an object transitions
;;; | | | | | | from "one" behavior to another is when it
;;; | | | | | | returns a new handler wrapped in a "become"
;;; | | | | | | wrapper specific to this object (and
;;; | | | | | provided to the object at construction
;;; | | | | | | time)
;;; | | | | | |
;;; V V V V V V
;;; (node (vat (actormap {refr: (mactor object-handler)})))
;;;
;;;
;;; Whew! That's a lot of info, so go take a break and then we'll go onto
@ -376,7 +376,7 @@
;;; '----------------'----------------' :
;;;
;;; On the left hand side we see live references (only valid within this
;;; process runtime or between machines across captp sessions) and
;;; process runtime or between nodes across captp sessions) and
;;; offline-storeable references (sturdy refrs, a kind of bearer URI,
;;; and certificate chains, which are like "deeds" indicating that the
;;; possessor of some cryptographic material is permitted access).
@ -386,8 +386,8 @@
;;; capability, as well as authority to produce these offline-storeable
;;; objects).
;;;
;;; Live references subdivide into local (on the same machine) and
;;; remote (on a foreign machine). These are typed as either
;;; Live references subdivide into local (on the same node) and
;;; remote (on a foreign node). These are typed as either
;;; representing an object or a promise.
;;;
;;; (Local references also further subdivide into "near" and "far",
@ -427,8 +427,8 @@
(_make-local-promise-refr vat-connector))
;; Captp-connector should be a procedure which both sends a message
;; to the local machine representative actor, but also has something
;; serialized that knows which specific remote machine + session this
;; to the local node representative actor, but also has something
;; serialized that knows which specific remote node + session this
;; corresponds to (to look up the right captp session and forward)
(struct remote-refr live-refr (captp-connector sealed-pos))
@ -538,7 +538,7 @@
;;; it is sure to correspond to a mactor:object. A local-promise-refr can
;;; correspond to any object state *except* for mactor:object (if a promise
;;; resolves to a local object, it must point to it via mactor:local-link.)
;;; (remote-refrs of course never correspond to a mactor on this machine;
;;; (remote-refrs of course never correspond to a mactor on this node;
;;; those are managed by captp.)
;;;
;;; See also:
@ -610,7 +610,7 @@
(struct mactor:remote-link mactor:eventual
(point-to))
;; Link to an object on the same machine.
;; Link to an object on the same node.
(struct mactor:local-link mactor
(point-to))
@ -1325,7 +1325,7 @@
`#(success ,(void))])]
;; But if it's a remote promise then we queue it in the waiting
;; messages because we prefer to have messages "swim as close
;; as possible to the machine barrier where possible", with
;; as possible to the node barrier where possible", with
;; the exception of questions/answers which always cross over
;; (see mactor:question handling later in this procedure)
[(? remote-promise-refr?)

50
goblins/ocapn/captp-test.rkt

@ -37,7 +37,7 @@
;;;; we want, but maybe we should do that by building an actual ocapn
;;;; test harness.
;; ;; Testing against a machine representative with nothing real on the other side.
;; ;; Testing against a node representative with nothing real on the other side.
;; ;; We're calling our end the "repl" end even if inaccurate ;)
;; (define-values (repl->test1-ip repl->test1-op)
;; (make-pipe))
@ -76,7 +76,7 @@
;; (test1-vat 'run
;; (lambda ()
;; ($ test1-mycapn 'new-connection
;; (ocapn-machine 'imaginary "repl" #f)
;; (ocapn-node 'imaginary "repl" #f)
;; repl->test1-ip test1->repl-op))))
;; (define repl-handoff-privkey
@ -90,11 +90,11 @@
;; ;; First of all, we need to send our own end of the session
;; (let ()
;; (syrup-write (mtp:op:start-session repl-encoded-handoff-pubkey
;; (ocapn-machine 'imaginary "repl" #f)
;; (ocapn-node 'imaginary "repl" #f)
;; (pk-sign repl-handoff-privkey
;; (syrup-encode
;; (record* 'my-location
;; (ocapn-machine 'imaginary "repl" #f))
;; (ocapn-node 'imaginary "repl" #f))
;; #:marshallers marshallers)))
;; repl->test1-op
;; #:marshallers marshallers)
@ -102,13 +102,13 @@
;; ;; We should also hear its own side of the session
;; (test-true
;; "test machine should send their part of the session"
;; "test node should send their part of the session"
;; (mtp:op:start-session? (syrup-read test1->repl-ip
;; #:unmarshallers unmarshallers)))
;; ;; It should send us (the REPL) a bootstrap message with answer pos 0
;; (test-equal?
;; "test machine should send a bootstrap message"
;; "test node should send a bootstrap message"
;; (syrup-read test1->repl-ip
;; #:unmarshallers unmarshallers)
;; (op:bootstrap 0 (desc:import-object 0)))
@ -171,13 +171,13 @@
($ network 'register "m2" m2-incoming)
($ network 'register "m3" m3-incoming))
;; Set up the machines we plan to use.
;; Set up the nodes we plan to use.
(define m1-location
(string->ocapn-machine "ocapn://m1.fake"))
(string->ocapn-node "ocapn://m1.fake"))
(define m2-location
(string->ocapn-machine "ocapn://m2.fake"))
(string->ocapn-node "ocapn://m2.fake"))
(define m3-location
(string->ocapn-machine "ocapn://m3.fake"))
(string->ocapn-node "ocapn://m3.fake"))
(define m1-fakenet
(m1-run (spawn ^fake-netlayer "m1" network m1-incoming)))
@ -215,19 +215,19 @@
;;
;; M1 <-> M2
(define m1->m2-vow
(m1-run ($ m1-mycapn 'connect-to-machine m2-location)))
(m1-run ($ m1-mycapn 'connect-to-node m2-location)))
(sleep .2)
(define m2->m1-vow
(m2-run ($ m2-mycapn 'connect-to-machine m1-location)))
(m2-run ($ m2-mycapn 'connect-to-node m1-location)))
;; ;; M1 <-> M3
(define m1->m3-vow
(m1-run ($ m1-mycapn 'connect-to-machine m3-location)))
(m1-run ($ m1-mycapn 'connect-to-node m3-location)))
(sleep .2)
(define m3->m1-vow
(m3-run ($ m3-mycapn 'connect-to-machine m1-location)))
(m3-run ($ m3-mycapn 'connect-to-node m1-location)))
;; Vat A -> Vat B tests
;; (TODO: Replace this with machines in separate places)
;; (TODO: Replace this with nodes in separate places)
(define a-vat
(make-vat))
(define b-vat
@ -336,7 +336,7 @@
;; [something-else
;; #f]))
;; Now for testing three vats across two machines.
;; Now for testing three vats across two nodes.
;; This one, functionally, is actually running through a-vat's
;; machinetp system
(define c-vat
@ -378,7 +378,7 @@
chatty-carol))))
(test-equal?
"A and C on one machine, B on another, with introductions"
"A and C on one node, B on another, with introductions"
(sync/timeout 0.5 meeter-bob-response-ch)
'(heard-back (hello-back-from carol)))
@ -427,11 +427,11 @@
;; (define parrot (b-vat 'spawn ^parrot))
;; ;; TODO: This apparently will need to register itself with the base
;; ;; ^machine...
;; (define machine-representative->machine-thread-ch
;; (make-machinetp-thread m2->m1-ip m1->m2-op
;; b-vat
;; bob))
;; ;; ^node...
;; (define node-representative->node-thread-ch
;; (make-captptp-thread m2->m1-ip m1->m2-op
;; b-vat
;; bob))
;; (syrup-write (op:deliver-only 0 #f '("George") #hasheq())
;; m2->m1-op
@ -455,7 +455,7 @@
(<- m2->m1-vow 'fetch (ocapn-sturdyref-swiss-num shares-a-args-counter-sref))))
;; Now for the three-machine handoff.
;; Now for the three-node handoff.
;; ==================================
(define d-vat
(make-vat))
@ -476,7 +476,7 @@
;; Handoff success
(test-equal?
"A on one machine, B on another, introduced to D on another, via handoffs"
"A on one node, B on another, introduced to D on another, via handoffs"
(sync/timeout 0.5 meeter-bob-response-ch)
'(heard-back (hello-back-from daniel)))
@ -491,7 +491,7 @@
;; "Shortening when handoffs come back home mystery error".
;; That's where we might fill in further code... but is it ever
;; needed? The handoff from M3 gifting access to M2 already means
;; that we've reduced things to a two-machine scenario... no need
;; that we've reduced things to a two-node scenario... no need
;; for another handoff.
;; Nonetheless this test is really useful and should be preserved!
;; TODO UPDATE: And we did hit it! Wee comment sabove about the

83
goblins/ocapn/captp.rkt

@ -56,7 +56,7 @@
;; https://capnproto.org/rpc.html
;; https://github.com/sandstorm-io/capnproto/blob/master/c++/src/capnp/rpc.capnp
;;
;; For the gory details of "Chris figuring out how CapTP works"
;; For the gory details of "Christine figuring out how CapTP works"
;; see these monster threads:
;; https://groups.google.com/g/cap-talk/c/xWv2-J62g-I
;; https://groups.google.com/g/cap-talk/c/-JYtc-L9OvQ
@ -163,7 +163,7 @@
;; : handoff-key?
recipient-key
;; exporter-location(-hint(s)): how to connect to get this
;; : ocap-machine-uri?
;; : ocap-node-url?
;; Note that currently this requires a certain amount of VatTP
;; crossover, since we have to give a way to connect to VatTP...
exporter-location
@ -186,7 +186,7 @@
signed-give)
marshall::desc:handoff-receive unmarshall::desc:handoff-receive)
;; machinetp operations/descriptions
;; CapTP operations/descriptions
(define-recordable-struct op:start-session
(captp-version
handoff-pubkey
@ -212,7 +212,7 @@
marshall::desc:handoff-receive
marshall::op:start-session
marshall::ocapn-machine
marshall::ocapn-node
marshall::ocapn-sturdyref
marshall::ocapn-cert
marshall::ocapn-bearer-union))
@ -234,7 +234,7 @@
unmarshall::desc:handoff-receive
unmarshall::op:start-session
unmarshall::ocapn-machine
unmarshall::ocapn-node
unmarshall::ocapn-sturdyref
unmarshall::ocapn-cert
unmarshall::ocapn-bearer-union))
@ -293,7 +293,7 @@
;; handoffs, etc.
coordinator
bootstrap-obj
intra-machine-warden intra-machine-incanter)
intra-node-warden intra-node-incanter)
;; position sealers, so we know this really is from our imports/exports
;; @@: Not great protection, subject to a reuse attack, but really
;; this is just an extra step... in general we shouldn't be exposing
@ -307,7 +307,7 @@
;; look up what question corresponds to an entry in the table.
;; Used by mactor:question (a special kind of promise),
;; since messages sent to a question are pipelined through the answer
;; side of some "remote" machine.
;; side of some "remote" node.
(struct question-finder ())
(define (_handle-message msg)
@ -334,7 +334,7 @@
wants-partial?)))
(define (^connector-obj _bcom)
(define intra-machine-beh
(define intra-node-beh
(methods
[(get-handoff-privkey)
($ coordinator 'get-handoff-privkey)]
@ -359,7 +359,7 @@
(spawn ^cancel-sever-notification)]
[(cancel-sever-interest sever-resolver)
($ interested-in-sever 'remove sever-resolver)]))
(ward intra-machine-warden intra-machine-beh
(ward intra-node-warden intra-node-beh
#:extends main-beh))
(define connector-obj (spawn ^connector-obj))
(define (_get-connector-obj) connector-obj)
@ -610,7 +610,7 @@
(record* 'void)]
[(? keyword?)
(record* 'kw (string->symbol (keyword->string obj)))]
;; TODO: Supply more machine-crossing exception types here
;; TODO: Supply more CapTP boundary-crossing exception types here
[(? exn:fail?)
(record* 'exn:fail:mystery)]
;; And here's the general-purpose record that users can use
@ -649,7 +649,7 @@
unknown-record-tag)]
[(? signed-handoff-give? sig-envelope-and-handoff)
;; We need to send this message to the coordinator, which will
;; work with the machine to (hopefully) get it to the right
;; work with the node to (hopefully) get it to the right
;; destination
(define handoff-vow
($ coordinator 'start-retrieve-handoff sig-envelope-and-handoff))
@ -675,7 +675,7 @@
[(eq? refr-captp-connector captp-connector)
(desc:export (pos-unseal (remote-refr-sealed-pos obj)))]
[else
(error 'captp-to-wrong-machine)])]))
(error 'captp-to-wrong-node)])]))
(define (install-answer! answer-pos resolve-me-desc)
(define resolve-me
@ -927,11 +927,11 @@
;;; =================END CRYPTOGRAPHY ADMONISHMENT===============
(define (^coordinator bcom router our-location
intra-machine-warden intra-machine-incanter
intra-node-warden intra-node-incanter
#:privkey [handoff-privkey
(generate-private-key eddsa
'((curve ed25519)))]
;; #:local-machine-location [local-machine-location #f]
;; #:local-node-location [local-node-location #f]
)
;; counters used to increment how many handoff requests have been
;; made in this session to prevent replay attacks.
@ -980,7 +980,7 @@
(define (ready-beh remote-encoded-key
remote-key
remote-location
;; remote-machine-location ;; auughhhhhh
;; remote-node-location ;; auughhhhhh
)
(define remote-side-name
(sha256d (syrup-encode remote-encoded-key)))
@ -1017,13 +1017,13 @@
(define recipient-key remote-encoded-key)
(define exporter-location
($ intra-machine-incanter
($ intra-node-incanter
exported-connector-obj 'get-remote-location))
(define gifter-and-exporter-session
($ intra-machine-incanter exported-connector-obj
($ intra-node-incanter exported-connector-obj
'get-session-name))
(define gifter-side
($ intra-machine-incanter exported-connector-obj
($ intra-node-incanter exported-connector-obj
'get-our-side-name))
(define gift-id (crypto-random-bytes 32))
@ -1033,7 +1033,7 @@
gifter-side
gift-id))
(define handoff-give-sig-racket
(pk-sign ($ intra-machine-incanter
(pk-sign ($ intra-node-incanter
exported-connector-obj 'get-handoff-privkey)
(syrup-encode handoff-give
#:marshallers marshallers)))
@ -1041,7 +1041,7 @@
(racket->gcrypt/signature handoff-give-sig-racket))
(define exporter-session-bootstrap
($ intra-machine-incanter
($ intra-node-incanter
exported-connector-obj 'get-remote-bootstrap))
;; Now we send a message to the exporter saying we'd like to deposit
@ -1189,8 +1189,8 @@
(spawn-nonce-registry-locator-pair))
;; Warden and incanter for collaborating parties in this
;; particular machine
(define-values (intra-machine-warden intra-machine-incanter)
;; particular node
(define-values (intra-node-warden intra-node-incanter)
(spawn-warding-pair))
(define locations->open-session-names
(spawn ^hash))
@ -1260,7 +1260,7 @@
;; If we made it this far, it's ok... so time to get that referenced
;; object!
($ intra-machine-incanter cert-session-local-bootstrap-obj
($ intra-node-incanter cert-session-local-bootstrap-obj
'pull-out-gift
(desc:handoff-give-gift-id handoff-give))
)
@ -1294,7 +1294,7 @@
($ waiting-gifts 'set id (list gift-promise gift-resolver))
gift-promise))])]))
(ward intra-machine-warden cross-gift-beh #:extends main-beh))
(ward intra-node-warden cross-gift-beh #:extends main-beh))
#;(define (^bootstrap bcom coordinator #:extends [extends #f])
(define session-name ($ coordinator 'get-session-name))
@ -1307,23 +1307,22 @@
(pk 'retrieve-gift signed-handoff-receive)
'TODO]))
;; TODO: Rename this to connect-to-machine I guess?
(define (retrieve-or-setup-session-vow remote-machine-loc)
(if ($ locations->open-session-names 'has-key? remote-machine-loc)
(define (retrieve-or-setup-session-vow remote-node-loc)
(if ($ locations->open-session-names 'has-key? remote-node-loc)
;; found an open session for this location
(let ([session-name ($ locations->open-session-names
'ref remote-machine-loc)])
'ref remote-node-loc)])
(sessionmeta-remote-bootstrap-obj
($ open-session-names->sessionmeta 'ref session-name)))
;; Guess we'll make a new one
(let ([netlayer (get-netlayer-for-location remote-machine-loc)])
($ netlayer 'connect-to remote-machine-loc))))
(let ([netlayer (get-netlayer-for-location remote-node-loc)])
($ netlayer 'connect-to remote-node-loc))))
(define (get-netlayer-for-location loc)
(define transport-tag (ocapn-machine-transport loc))
(define transport-tag (ocapn-node-transport loc))
(unless ($ netlayer-map 'has-key? transport-tag)
(error 'unsupported-transport
"NETLAYER not supported for this machine: ~a" transport-tag))
"NETLAYER not supported for this node: ~a" transport-tag))
($ netlayer-map 'ref transport-tag))
(define (self-location? loc)
@ -1336,15 +1335,15 @@
(-> live-refr? symbol? ocapn-sturdyref?)
(unless ($ netlayer-map 'has-key? netlayer-name)
(error 'unsupported-transport
"NETLAYER not supported for this machine: ~a" netlayer-name))
"NETLAYER not supported for this node: ~a" netlayer-name))
(define netlayer ($ netlayer-map 'ref netlayer-name))
(define machine-loc ($ netlayer 'our-location))
(define node-loc ($ netlayer 'our-location))
(define nonce ($ registry 'register obj))
(ocapn-sturdyref machine-loc nonce))
(ocapn-sturdyref node-loc nonce))
(define/contract (enliven sturdyref)
(-> ocapn-sturdyref? live-refr?)
(define sref-loc (ocapn-sturdyref-machine sturdyref))
(define sref-loc (ocapn-sturdyref-node sturdyref))
(define sref-swiss-num (ocapn-sturdyref-swiss-num sturdyref))
;; Is it local?
(if (self-location? sref-loc)
@ -1382,7 +1381,7 @@
($ netlayer 'our-location))
(define coordinator
(spawn ^coordinator self our-location
intra-machine-warden intra-machine-incanter))
intra-node-warden intra-node-incanter))
(define handoff-pubkey
($ coordinator 'get-handoff-pubkey))
(define our-location-sig
@ -1393,7 +1392,7 @@
(define-values (meta-bootstrap-vow meta-bootstrap-resolver)
(spawn-promise-values))
;; Complete the initialization step against the remote machine.
;; Complete the initialization step against the remote node.
;; Basically this allows the coordinator to know of what remote
;; key will be used in this session.
(define (^setup-completer bcom)
@ -1403,7 +1402,7 @@
;; "confident" this is from the right location
[(op:start-session remote-captp-version
remote-encoded-pubkey
(? ocapn-machine? claimed-remote-location)
(? ocapn-node? claimed-remote-location)
remote-location-sig)
(unless (string=? remote-captp-version captp-version)
;; It's important this is an <-np-extern, otherwise we won't actually send as we error.
@ -1419,7 +1418,7 @@
;; for the start-session message...
;; So, remove this if we can. Or realistically, move this whole part
;; to the NETLAYER code.
#;(unless (same-machine-location? claimed-remote-location remote-location)
#;(unless (same-node-location? claimed-remote-location remote-location)
(error (format "Supplied location mismatch. Claimed: ~s Expected: ~s"
claimed-remote-location remote-location)))
(unless (pk-verify remote-handoff-pubkey
@ -1453,7 +1452,7 @@
(define-values (captp-incoming-handler remote-bootstrap-vow)
(setup-captp-conn send-to-remote coordinator
local-bootstrap-obj
intra-machine-warden intra-machine-incanter))
intra-node-warden intra-node-incanter))
;; Fulfill the meta-bootstrap-promise with the promise that
;; setup-captp-conn gave us
($ meta-bootstrap-resolver 'fulfill remote-bootstrap-vow)
@ -1516,7 +1515,7 @@
[self-location? self-location?]
;; ... is that it?
[connect-to-machine retrieve-or-setup-session-vow]
[connect-to-node retrieve-or-setup-session-vow]
[(install-netlayer netlayer)
(define netlayer-name ($ netlayer 'netlayer-name))

20
goblins/ocapn/netlayer/fake-intarwebs.rkt

@ -45,7 +45,7 @@
(vector m1->m2-ip m2->m1-op)]))
(define (^fake-netlayer _bcom our-name network new-conn-ch)
(define our-location (ocapn-machine 'fake our-name #f))
(define our-location (ocapn-node 'fake our-name #f))
;; This allows for incoming messages over a channel, preserving some illusion
;; of foreign-communication
(define (start-listening conn-establisher)
@ -69,7 +69,7 @@
(define pre-setup-beh
(methods
#:extends base-beh
;; The machine is now wiring us up with the appropriate behavior for
;; The node is now wiring us up with the appropriate behavior for
;; when a new connection comes in
[(setup conn-establisher)
(start-listening conn-establisher)
@ -80,10 +80,10 @@
(methods
#:extends base-beh
[(self-location? loc)
(same-machine-location? our-location loc)]
[(connect-to remote-machine)
(match remote-machine
[(ocapn-machine 'fake name #f)
(same-node-location? our-location loc)]
[(connect-to remote-node)
(match remote-node
[(ocapn-node 'fake name #f)
(on (<- network 'connect-to name)
(match-lambda
[(vector ip op)
@ -123,8 +123,8 @@
($ network 'register "a" a-incoming)
($ network 'register "b" b-incoming))
(define a-location (string->ocapn-machine "ocapn://a.fake"))
(define b-location (string->ocapn-machine "ocapn://b.fake"))
(define a-location (string->ocapn-node "ocapn://a.fake"))
(define b-location (string->ocapn-node "ocapn://b.fake"))
(define a-mycapn
(a-run
@ -134,9 +134,9 @@
(spawn-mycapn b-fake-netlayer)))
(define a->b-vow
(a-run ($ a-mycapn 'connect-to-machine b-location)))
(a-run ($ a-mycapn 'connect-to-node b-location)))
(define b->a-vow
(b-run ($ b-mycapn 'connect-to-machine a-location)))
(b-run ($ b-mycapn 'connect-to-node a-location)))
;; TODO: Next we need to spawn a couple of useful actors, make
;; sturdyrefs to them, and make sure we can message them from each

14
goblins/ocapn/netlayer/onion.rkt

@ -201,7 +201,7 @@
(define pre-setup-beh
(methods
#:extends base-beh
;; The machine is now wiring us up with the appropriate behavior for
;; The node is now wiring us up with the appropriate behavior for
;; when a new connection comes in
[(setup conn-establisher)
(start-listen-thread conn-establisher)
@ -211,10 +211,10 @@
(methods
#:extends base-beh
[(self-location? loc)
(same-machine-location? our-location loc)]
[(connect-to remote-machine)
(match remote-machine
[(ocapn-machine 'onion address #f)
(same-node-location? our-location loc)]
[(connect-to remote-node)
(match remote-node
[(ocapn-node 'onion designator #f)
;; hacky way to start the connection in another thread but with
;; working promise machinery
(define connect-vat (make-vat))
@ -222,7 +222,7 @@
(lambda ()
(define-values (ip op)
(unix-socket-connect tor-socks-path))
(onion-socks5-setup! ip op (string-append address ".onion"))
(onion-socks5-setup! ip op (string-append designator ".onion"))
(define-values (read-message write-message)
(read-write-procs ip op))
(<- conn-establisher read-message write-message #f)))
@ -239,7 +239,7 @@
(delete-directory ocapn-tmp-dir))
(define our-location
(ocapn-machine 'onion service-id #f))
(ocapn-node 'onion service-id #f))
(values (spawn ^onion-netlayer our-location ocapn-sock-listener
tor-socks-path do-cleanup)

212
goblins/ocapn/structs-urls.rkt

@ -24,16 +24,16 @@
syrup)
(provide (contract-out
(struct ocapn-machine ([transport symbol?]
[address string?]
[hints (or/c #f string?)])))
(struct ocapn-node ([transport symbol?]
[designator string?]
[hints (or/c #f string?)])))
(contract-out
(struct ocapn-sturdyref ([machine ocapn-machine?]
(struct ocapn-sturdyref ([node ocapn-node?]
[swiss-num bytes?])))
;; We only really "support" sturdyrefs so far. We'll export
;; these other ones as they become more broadly supported
#;(contract-out
(struct ocapn-cert ([machine ocapn-machine?]
(struct ocapn-cert ([node ocapn-node?]
;; I guess we should restrict this to syrup-only data?
[certdata any/c])))
#;(contract-out
@ -42,94 +42,92 @@
[private-key bytes?])))
ocapn-struct?
ocapn-struct->ocapn-machine
same-machine-location?
ocapn-struct->ocapn-node
same-node-location?
ocapn-machine->url
ocapn-node->url
ocapn-sturdyref->url
;; ocapn-cert->url
;; ocapn-bearer-union->url
url->ocapn-machine
url->ocapn-node
url->ocapn-sturdyref
;; url->ocapn-cert
;; url->ocapn-bearer-union
url->ocapn-struct
string->ocapn-machine
string->ocapn-node
string->ocapn-sturdyref
;; string->ocapn-cert
;; string->ocapn-bearer-union
string->ocapn-struct
ocapn-machine->string
ocapn-node->string
ocapn-sturdyref->string
;; ocapn-cert->string
;; ocapn-bearer-union->string
ocapn-url?
ocapn-machine-url?
ocapn-node-url?
ocapn-sturdyref-url?
;; ocapn-cert-url?
;; ocapn-bearer-union-url?
)
(module+ marshall
(provide marshall::ocapn-machine
(provide marshall::ocapn-node
marshall::ocapn-sturdyref
marshall::ocapn-cert
marshall::ocapn-bearer-union
unmarshall::ocapn-machine
unmarshall::ocapn-node
unmarshall::ocapn-sturdyref
unmarshall::ocapn-cert
unmarshall::ocapn-bearer-union))
;; Ocapn machine type URI:
;; Ocapn node type URI:
;;
;; ocapn://<transport-address>.<transport>
;; ocapn://<designator>.<transport>
;;
;; <ocapn-machine $transport $transport-address $transport-hints>
;; <ocapn-node $transport $designator $transport-hints>
;;
;; . o O (Are hints really a good idea or needed anymore?)
;; NB: Hints are not currently supported.
;; EG: "ocapn:m.onion.wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
;; TODO: Consider adding hints, possibly to the query part of the URI
(define-recordable-struct ocapn-machine
(transport address hints)
marshall::ocapn-machine unmarshall::ocapn-machine)
;; NB: Hints aren't supported.
;;
;; EG: "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion"
(define-recordable-struct ocapn-node
(transport designator hints)
marshall::ocapn-node unmarshall::ocapn-node)
;; Ocapn swissnum URI:
;;
;; ocapn://abpoiyaspodyoiapsdyiopbasyop.onion/3cbe8e02-ca27-4699-b2dd-3e284c71fa96
;;
;; ocapn://<transport-address>.<transport>/s/<swiss-num>
;; ocapn://<designator>.<transport>/s/<swiss-num>
;;
;; <ocapn-sturdyref <ocapn-machine $transport $transport-address $transport-hints>
;; <ocapn-sturdyref <ocapn-node $transport $designator $transport-hints>
;; $swiss-num>
(define-recordable-struct ocapn-sturdyref
(machine swiss-num)
(node swiss-num)
marshall::ocapn-sturdyref unmarshall::ocapn-sturdyref)
;; Ocapn certificate URI:
;;
;; ocapn://<transport-address>.<transport>./c/<cert>
;; ocapn://<designator>.<transport>./c/<cert>
;;
;; <ocapn-cert <ocapn-machine $transport $transport-address $transport-hints>
;; <ocapn-cert <ocapn-node $transport $transport-designator $transport-hints>
;; $cert>
(define-recordable-struct ocapn-cert
(machine certdata)
(node certdata)
marshall::ocapn-cert unmarshall::ocapn-cert)
;; Ocapn bearer certificate union URI:
;;
;; ocapn://<transport-address>.<transport>/b/<cert>/<key-type>.<private-key>
;; ocapn://<designator>.<transport>/b/<cert>/<key-type>.<private-key>
;;
;; <ocapn-bearer-union <ocapn-cert <ocapn-machine $transport
;; $transport-address
;; <ocapn-bearer-union <ocapn-cert <ocapn-node $transport
;; $transport-designator
;; $transport-hints>
;; $cert>
;; $key-type
@ -141,32 +139,32 @@
(define (ocapn-struct? obj)
(or (ocapn-machine? obj)
(or (ocapn-node? obj)
(ocapn-sturdyref? obj)))
;; (ocapn-cert? obj)
;; (ocapn-bearer-union? obj)))
(define (ocapn-struct->ocapn-machine ocapn-struct)
(define (ocapn-struct->ocapn-node ocapn-struct)
(match ocapn-struct
[(? ocapn-machine?) ocapn-struct]
[(ocapn-sturdyref ocapn-machine _sn) ocapn-machine]))
;;[(ocapn-cert ocapn-machine _cert) ocapn-machine]
;;[(ocapn-bearer-union (ocapn-cert ocapn-machine _cert) _key-type _private-key)
;; ocapn-machine]))
;; Checks for the equivalence between two ocapn-machine structs
;; (including ocapn-machines nested in other ocapn-structs),
[(? ocapn-node?) ocapn-struct]
[(ocapn-sturdyref ocapn-node _sn) ocapn-node]))
;;[(ocapn-cert ocapn-node _cert) ocapn-node]
;;[(ocapn-bearer-union (ocapn-cert ocapn-node _cert) _key-type _private-key)
;; ocapn-node]))
;; Checks for the equivalence between two ocapn-node structs
;; (including ocapn-nodes nested in other ocapn-structs),
;; ignoring hints
(define/contract (same-machine-location? ocapn-struct1 ocapn-struct2)
(define/contract (same-node-location? ocapn-struct1 ocapn-struct2)
(-> ocapn-struct? ocapn-struct? any/c)
(define machine1 (ocapn-struct->ocapn-machine ocapn-struct1))
(define machine2 (ocapn-struct->ocapn-machine ocapn-struct2))
(match-let ([(ocapn-machine m1-transport m1-address _m1-hints)
machine1]
[(ocapn-machine m2-transport m2-address _m2-hints)
machine2])
(and (equal? m1-transport m2-transport)
(equal? m1-address m2-address))))
(define node1 (ocapn-struct->ocapn-node ocapn-struct1))
(define node2 (ocapn-struct->ocapn-node ocapn-struct2))
(match-let ([(ocapn-node n1-transport n1-designator _n1-hints)
node1]
[(ocapn-node n2-transport n2-designator _n2-hints)
node2])
(and (equal? n1-transport n2-transport)
(equal? n1-designator n2-designator))))
(define (error-not-an-ocapn-url something-else)
@ -175,14 +173,14 @@
(define (url-host->transport-parts url-host)
(let* ((url-host-length (string-length url-host))
(transport-str (last (string-split url-host ".")))
(address (substring url-host 0 (- url-host-length (string-length transport-str) 1))))
(values (string->symbol transport-str) address)))
(designator (substring url-host 0 (- url-host-length (string-length transport-str) 1))))
(values (string->symbol transport-str) designator)))
(define/contract (url->ocapn-machine ocapn-url)
(-> url? ocapn-machine?)
(define/contract (url->ocapn-node ocapn-url)
(-> url? ocapn-node?)
(let*-values ([(host) (url-host ocapn-url)]
[(transport address) (url-host->transport-parts host)])
(ocapn-machine transport address #f)))
[(transport designator) (url-host->transport-parts host)])
(ocapn-node transport designator #f)))
(define (url->ocapn-struct ocapn-url)
(unless (and (string? (url-scheme ocapn-url))
@ -190,13 +188,13 @@
(error-not-an-ocapn-url ocapn-url))
(match (url-path ocapn-url)
;; This is a machine type, so we're done
;; This is a node type, so we're done
[(or (list)
(list (path/param "" '())))
(url->ocapn-machine ocapn-url)]
(url->ocapn-node ocapn-url)]
;; Sturdyref
[(list (path/param "s" '()) (path/param swiss-num '()))
(ocapn-sturdyref (url->ocapn-machine ocapn-url) (url-base64-decode swiss-num))]))
(ocapn-sturdyref (url->ocapn-node ocapn-url) (url-base64-decode swiss-num))]))
;; way too lazy but the contracts do the right thing on these
;; TODO: Except kind of not because it says "broke its own contract",
@ -209,8 +207,8 @@
;;(define-url->ocapn-something url->ocapn-cert ocapn-cert?)
;;(define-url->ocapn-something url->ocapn-bearer-union ocapn-bearer-union?)
(define (string->ocapn-machine str)
(url->ocapn-machine (string->url str)))
(define (string->ocapn-node str)
(url->ocapn-node (string->url str)))
(define (string->ocapn-sturdyref str)
(url->ocapn-sturdyref (string->url str)))
;; (define (string->ocapn-cert str)
@ -220,8 +218,8 @@
(define (string->ocapn-struct str)
(url->ocapn-struct (string->url str)))
(define (ocapn-machine->string machine)
(url->string (ocapn-machine->url machine)))
(define (ocapn-node->string node)
(url->string (ocapn-node->url node)))
(define (ocapn-sturdyref->string sturdyref)
(url->string (ocapn-sturdyref->url sturdyref)))
;; (define (ocapn-cert->string cert)
@ -230,20 +228,20 @@
;; (url->string (ocapn-bearer-union->url bearer-union)))
;; helper procedure for the next two
(define (ocapn-machine->address-str machine)
(match machine
[(ocapn-machine transport address hints)
(format "~a.~a" address transport)]))
(define (ocapn-node->designator-str node)
(match node
[(ocapn-node transport designator hints)
(format "~a.~a" designator transport)]))
(define (ocapn-machine->url machine)
(let ((address-str (ocapn-machine->address-str machine)))
(make-url "ocapn" #f address-str #f #t '() '() #f)))
(define (ocapn-node->url node)
(let ((designator-str (ocapn-node->designator-str node)))
(make-url "ocapn" #f designator-str #f #t '() '() #f)))
(define (ocapn-sturdyref->url sturdyref)
(match sturdyref
[(ocapn-sturdyref machine swiss-num)
(let ((address-str (ocapn-machine->address-str machine)))
(make-url "ocapn" #f address-str #f #t
[(ocapn-sturdyref node swiss-num)
(let ((designator-str (ocapn-node->designator-str node)))
(make-url "ocapn" #f designator-str #f #t
(list (path/param "s" '())
(path/param (url-base64-encode swiss-num) '()))
'() #f))]))
@ -261,14 +259,14 @@
(define (make-ocapn-url-type-checker type-denotation)
(lambda (ocapn-uri)
(match ocapn-uri
[(url "ocapn" #f host #f #t (list (path/param type-address '())
[(url "ocapn" #f host #f #t (list (path/param type-designator '())
_other-paths ...)
'() #f)
(string-prefix? type-address type-denotation)]
(string-prefix? type-designator type-denotation)]
[_ #f])))
(define (ocapn-machine-url? ocapn-url)
(define (ocapn-node-url? ocapn-url)
(match ocapn-url
[(or (url "ocapn" #f host #f #t '() '() #f)
(url "ocapn" #f host #f #t '(path/param "" '()) '() #f))
@ -283,18 +281,18 @@
(require rackunit)
(test-equal?
"url->ocapn-machine, no hints"
(url->ocapn-machine
"url->ocapn-node, no hints"
(url->ocapn-node
(string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion"))
(ocapn-machine 'onion
(ocapn-node 'onion
"wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
#f))
;; (test-equal?
;; "url->ocapn-machine, with hints"
;; (string->ocapn-machine
;; "url->ocapn-node, with hints"
;; (string->ocapn-node
;; "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.blablabla.foo")
;; (ocapn-machine 'foo
;; (ocapn-node 'foo
;; "wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
;; "blablabla"))
@ -304,23 +302,23 @@
(string->url
"ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion/s/eQjP4nR28ffX5eoNCK5DWH6DT_d7BIqD3-My459CUbU"))
(ocapn-sturdyref
(ocapn-machine 'onion
(ocapn-node 'onion
"wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
#f)
#"y\b\317\342tv\361\367\327\345\352\r\b\256CX~\203O\367{\4\212\203\337\3432\343\237BQ\265"))
(test-equal?
"ocapn-machine->url, no hints"
(ocapn-machine->url
(ocapn-machine 'onion
"ocapn-node->url, no hints"
(ocapn-node->url
(ocapn-node 'onion
"wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
#f))
(string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion"))
;; (test-equal?
;; "ocapn-machine->url, with hints"
;; (ocapn-machine->url
;; (ocapn-machine 'onion
;; "ocapn-node->url, with hints"
;; (ocapn-node->url
;; (ocapn-node 'onion
;; "wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
;; "hintyhint"))
;; (string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.hintyhint.onion"))
@ -329,14 +327,14 @@
"ocapn-sturdyref->url"
(ocapn-sturdyref->url
(ocapn-sturdyref
(ocapn-machine 'onion
(ocapn-node 'onion
"wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd"
#f)
#"y\b\317\342tv\361\367\327\345\352\r\b\256CX~\203O\367{\4\212\203\337\3432\343\237BQ\265"))
(string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion/s/eQjP4nR28ffX5eoNCK5DWH6DT_d7BIqD3-My459CUbU"))
(check-true
(ocapn-machine-url? (string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion")))
(ocapn-node-url? (string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion")))
(check-true
(ocapn-sturdyref-url? (string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion/s/eQjP4nR28ffX5eoNCK5DWH6DT_d7BIqD3-My459CUbU")))
;; (check-true
@ -347,22 +345,22 @@
(ocapn-sturdyref-url? (string->url "ocapn://wy46gxdweyqn5m7ntzwlxinhdia2jjanlsh37gxklwhfec7yxqr4k3qd.onion")))
(check-true
(same-machine-location?
(string->ocapn-machine "ocapn://foo.testnet")
(string->ocapn-machine "ocapn://foo.testnet")))
(same-node-location?
(string->ocapn-node "ocapn://foo.testnet")
(string->ocapn-node "ocapn://foo.testnet")))
(check-false
(same-machine-location?
(string->ocapn-machine "ocapn://foo.testnet")
(string->ocapn-machine "ocapn://bar.testnet")))
(same-node-location?
(string->ocapn-node "ocapn://foo.testnet")
(string->ocapn-node "ocapn://bar.testnet")))
(check-false
(same-machine-location?
(string->ocapn-machine "ocapn://foo.testnet")
(string->ocapn-machine "ocapn://foo.othernet")))
(same-node-location?
(string->ocapn-node "ocapn://foo.testnet")
(string->ocapn-node "ocapn://foo.othernet")))
(check-true
(same-machine-location?
(string->ocapn-machine "ocapn://foo.testnet")
(same-node-location?
(string->ocapn-node "ocapn://foo.testnet")
(string->ocapn-sturdyref "ocapn://foo.testnet/s/d1607782-3c39-463f-baae-408753681a91")))
(check-false
(same-machine-location?
(string->ocapn-machine "ocapn://foo.testnet")
(same-node-location?
(string->ocapn-node "ocapn://foo.testnet")
(string->ocapn-sturdyref "ocapn://bar.testnet/s/d1607782-3c39-463f-baae-408753681a91"))))

2
goblins/scribblings/captp.scrbl

@ -278,7 +278,7 @@ Horray!
see the Tor Onion Services example above for an example.
Returns an object representing the machine with various methods
that Chris really ought to document.}
that Christine really ought to document.}
Sorry, these docs are pretty sparse; we hope to make them better.
Hopefully the above example helps get you started.

2
goblins/vat.rkt

@ -72,7 +72,7 @@
;;; might result in building up more messages by calls sent to <-, which,
;;; if to refrs in the same vat, will be put on the queue (FIFO order), but
;;; if they are in another vat will be sent there using the reference's vat
;;; or machine connector (depending on if local/remote).
;;; or CapTP connector (depending on if local/remote).
;;;
;;; Anyway, you could implement a vat-like event loop yourself, but this
;;; module implements the general behavior. The most important thing if

Loading…
Cancel
Save