Commit 860af726 authored by Kenton Varda's avatar Kenton Varda

In RPC protocol, rename request -> params, answer -> results. Also fix up Join…

In RPC protocol, rename request -> params, answer -> results.  Also fix up Join stuff in rpc-twoparty.capnp, because it was sort of wrong.
parent 3dda3cee
......@@ -58,7 +58,7 @@ private:
typedef VatNetwork<
test::TestSturdyRefHostId, test::TestProvisionId, test::TestRecipientId,
test::TestThirdPartyCapId, test::TestJoinAnswer> TestNetworkAdapterBase;
test::TestThirdPartyCapId, test::TestJoinResult> TestNetworkAdapterBase;
class TestNetworkAdapter final: public TestNetworkAdapterBase {
public:
......
......@@ -110,10 +110,40 @@ struct ThirdPartyCapId {}
# Never used, because there is no third party.
struct JoinKeyPart {
# Joins in the two-party case are simplified by a few observations.
#
# First, on a two-party network, a Join only ever makes sense if the receiving end is also
# connected to other networks. A vat which is not connected to any other network can safely
# reject all joins.
#
# Second, since a two-party connection bisects the network -- there can be no other connections
# between the networks at either end of the connection -- if one part of a join crosses the
# connection, then _all_ parts must cross it. Therefore, a vat which is receiving a Join request
# off some other network which needs to be forwarded across the two-party connection can
# collect all the parts on its end and only forward them across the two-party connection when all
# have been received.
#
# For example, imagine that Alice and Bob are vats connected over a two-party connection, and
# each is also connected to other networks. At some point, Alice receives one part of a Join
# request off her network. The request is addressed to a capability that Alice received from
# Bob and is proxying to her other network. Alice goes ahead and responds to the Join part as
# if she hosted the capability locally (this is important so that if not all the Join parts end
# up at Alice, the original sender can detect the failed Join without hanging). As other parts
# trickle in, Alice verifies that each part is addressed to a capability from Bob and continues
# to respond to each one. Once the complete set of join parts is received, Alice checks if they
# were all for the exact same capability. If so, she doesn't need to send anything to Bob at
# all. Otherwise, she collects the set of capabilities (from Bob) to which the join parts were
# addressed and essentially initiates a _new_ Join request on those capabilities to Bob. Alice
# does not forward the Join parts she received herself, but essentially forwards the Join as a
# whole.
#
# On Bob's end, since he knows that Alice will always send all parts of a Join together, he
# simply waits until he's received them all, then performs a join on the respective capabilities
# as if it had been requested locally.
joinId @0 :UInt32;
# A number identifying this join, chosen by the contained app. Since the container will never
# issue a join _to_ the contained app, all ongoing joins across the whole (two-vat) network are
# uniquely identified by this ID.
# A number identifying this join, chosen by the sender. May be reused once `Finish` messages are
# sent corresponding to all of the `Join` messages.
partCount @1 :UInt16;
# The number of capabilities to be joined.
......@@ -122,12 +152,17 @@ struct JoinKeyPart {
# Which part this request targets -- a number in the range [0, partCount).
}
struct JoinAnswer {
struct JoinResult {
joinId @0 :UInt32;
# Matches `JoinKeyPart`.
succeeded @1 :Bool;
# All JoinAnswers in the set will have the same value for `succeeded`. The container actually
# All JoinResults in the set will have the same value for `succeeded`. The receiver actually
# implements the join by waiting for all the `JoinKeyParts` and then performing its own join on
# them, then going back and answering all the join requests afterwards.
cap @2 :Object;
# One of the JoinResults will have a non-null `cap` which is the joined capability.
#
# TODO(cleanup): Change `Object` to `Capability` when that is supported.
}
......@@ -237,39 +237,46 @@ const ::capnp::_::RawSchema s_95b29059097fca83 = {
0x95b29059097fca83, b_95b29059097fca83.words, 61, nullptr, m_95b29059097fca83,
0, 3, i_95b29059097fca83, nullptr, nullptr
};
static const ::capnp::_::AlignedData<47> b_e34f40bff3af6b96 = {
static const ::capnp::_::AlignedData<61> b_9d263a3630b7ebee = {
{ 0, 0, 0, 0, 5, 0, 5, 0,
150, 107, 175, 243, 191, 64, 79, 227,
238, 235, 183, 48, 54, 58, 38, 157,
0, 0, 0, 0, 1, 0, 1, 0,
161, 242, 218, 92, 136, 199, 132, 161,
0, 0, 5, 0, 0, 0, 0, 0,
1, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
17, 0, 0, 0, 34, 1, 0, 0,
33, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 119, 0, 0, 0,
29, 0, 0, 0, 175, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 112, 110, 112, 47, 114, 112,
99, 45, 116, 119, 111, 112, 97, 114,
116, 121, 46, 99, 97, 112, 110, 112,
58, 74, 111, 105, 110, 65, 110, 115,
119, 101, 114, 0, 0, 0, 0, 0,
58, 74, 111, 105, 110, 82, 101, 115,
117, 108, 116, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
8, 0, 0, 0, 3, 0, 4, 0,
12, 0, 0, 0, 3, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 0, 0, 58, 0, 0, 0,
69, 0, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
36, 0, 0, 0, 2, 0, 1, 0,
44, 0, 0, 0, 2, 0, 1, 0,
64, 0, 0, 0, 2, 0, 1, 0,
72, 0, 0, 0, 2, 0, 1, 0,
1, 0, 0, 0, 32, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
41, 0, 0, 0, 82, 0, 0, 0,
69, 0, 0, 0, 82, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
68, 0, 0, 0, 2, 0, 1, 0,
76, 0, 0, 0, 2, 0, 1, 0,
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
73, 0, 0, 0, 34, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
40, 0, 0, 0, 2, 0, 1, 0,
48, 0, 0, 0, 2, 0, 1, 0,
68, 0, 0, 0, 2, 0, 1, 0,
76, 0, 0, 0, 2, 0, 1, 0,
106, 111, 105, 110, 73, 100, 0, 0,
8, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
......@@ -283,14 +290,21 @@ static const ::capnp::_::AlignedData<47> b_e34f40bff3af6b96 = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
99, 97, 112, 0, 0, 0, 0, 0,
18, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
18, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
static const uint16_t m_e34f40bff3af6b96[] = {0, 1};
static const uint16_t i_e34f40bff3af6b96[] = {0, 1};
const ::capnp::_::RawSchema s_e34f40bff3af6b96 = {
0xe34f40bff3af6b96, b_e34f40bff3af6b96.words, 47, nullptr, m_e34f40bff3af6b96,
0, 2, i_e34f40bff3af6b96, nullptr, nullptr
static const uint16_t m_9d263a3630b7ebee[] = {2, 0, 1};
static const uint16_t i_9d263a3630b7ebee[] = {0, 1, 2};
const ::capnp::_::RawSchema s_9d263a3630b7ebee = {
0x9d263a3630b7ebee, b_9d263a3630b7ebee.words, 61, nullptr, m_9d263a3630b7ebee,
0, 3, i_9d263a3630b7ebee, nullptr, nullptr
};
} // namespace schemas
namespace _ { // private
......@@ -307,6 +321,6 @@ CAPNP_DEFINE_STRUCT(
CAPNP_DEFINE_STRUCT(
::capnp::rpc::twoparty::JoinKeyPart);
CAPNP_DEFINE_STRUCT(
::capnp::rpc::twoparty::JoinAnswer);
::capnp::rpc::twoparty::JoinResult);
} // namespace _ (private)
} // namespace capnp
......@@ -60,8 +60,8 @@ struct JoinKeyPart {
class Pipeline;
};
struct JoinAnswer {
JoinAnswer() = delete;
struct JoinResult {
JoinResult() = delete;
class Reader;
class Builder;
......@@ -83,7 +83,7 @@ extern const ::capnp::_::RawSchema s_b88d09a9c5f39817;
extern const ::capnp::_::RawSchema s_89f389b6fd4082c1;
extern const ::capnp::_::RawSchema s_b47f4979672cb59d;
extern const ::capnp::_::RawSchema s_95b29059097fca83;
extern const ::capnp::_::RawSchema s_e34f40bff3af6b96;
extern const ::capnp::_::RawSchema s_9d263a3630b7ebee;
} // namespace schemas
namespace _ { // private
......@@ -106,8 +106,8 @@ CAPNP_DECLARE_STRUCT(
::capnp::rpc::twoparty::JoinKeyPart, 95b29059097fca83,
1, 0, EIGHT_BYTES);
CAPNP_DECLARE_STRUCT(
::capnp::rpc::twoparty::JoinAnswer, e34f40bff3af6b96,
1, 0, EIGHT_BYTES);
::capnp::rpc::twoparty::JoinResult, 9d263a3630b7ebee,
1, 1, INLINE_COMPOSITE);
} // namespace _ (private)
} // namespace capnp
......@@ -478,9 +478,9 @@ private:
friend struct ::capnp::ToDynamic_;
};
class JoinAnswer::Reader {
class JoinResult::Reader {
public:
typedef JoinAnswer Reads;
typedef JoinResult Reads;
Reader() = default;
inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}
......@@ -493,6 +493,9 @@ public:
inline bool getSucceeded() const;
inline bool hasCap() const;
inline ::capnp::ObjectPointer::Reader getCap() const;
private:
::capnp::_::StructReader _reader;
template <typename T, ::capnp::Kind k>
......@@ -503,16 +506,16 @@ private:
friend struct ::capnp::List;
friend class ::capnp::MessageBuilder;
friend class ::capnp::Orphanage;
friend ::kj::StringTree KJ_STRINGIFY(JoinAnswer::Reader reader);
friend ::kj::StringTree KJ_STRINGIFY(JoinResult::Reader reader);
};
inline ::kj::StringTree KJ_STRINGIFY(JoinAnswer::Reader reader) {
return ::capnp::_::structString<JoinAnswer>(reader._reader);
inline ::kj::StringTree KJ_STRINGIFY(JoinResult::Reader reader) {
return ::capnp::_::structString<JoinResult>(reader._reader);
}
class JoinAnswer::Builder {
class JoinResult::Builder {
public:
typedef JoinAnswer Builds;
typedef JoinResult Builds;
Builder() = delete; // Deleted to discourage incorrect usage.
// You can explicitly initialize to nullptr instead.
......@@ -529,21 +532,25 @@ public:
inline bool getSucceeded();
inline void setSucceeded(bool value);
inline bool hasCap();
inline ::capnp::ObjectPointer::Builder getCap();
inline ::capnp::ObjectPointer::Builder initCap();
private:
::capnp::_::StructBuilder _builder;
template <typename T, ::capnp::Kind k>
friend struct ::capnp::ToDynamic_;
friend class ::capnp::Orphanage;
friend ::kj::StringTree KJ_STRINGIFY(JoinAnswer::Builder builder);
friend ::kj::StringTree KJ_STRINGIFY(JoinResult::Builder builder);
};
inline ::kj::StringTree KJ_STRINGIFY(JoinAnswer::Builder builder) {
return ::capnp::_::structString<JoinAnswer>(builder._builder.asReader());
inline ::kj::StringTree KJ_STRINGIFY(JoinResult::Builder builder) {
return ::capnp::_::structString<JoinResult>(builder._builder.asReader());
}
class JoinAnswer::Pipeline {
class JoinResult::Pipeline {
public:
typedef JoinAnswer Pipelines;
typedef JoinResult Pipelines;
inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
inline explicit Pipeline(::capnp::ObjectPointer::Pipeline&& typeless)
......@@ -627,34 +634,55 @@ inline void JoinKeyPart::Builder::setPartNum( ::uint16_t value) {
3 * ::capnp::ELEMENTS, value);
}
inline ::uint32_t JoinAnswer::Reader::getJoinId() const {
inline ::uint32_t JoinResult::Reader::getJoinId() const {
return _reader.getDataField< ::uint32_t>(
0 * ::capnp::ELEMENTS);
}
inline ::uint32_t JoinAnswer::Builder::getJoinId() {
inline ::uint32_t JoinResult::Builder::getJoinId() {
return _builder.getDataField< ::uint32_t>(
0 * ::capnp::ELEMENTS);
}
inline void JoinAnswer::Builder::setJoinId( ::uint32_t value) {
inline void JoinResult::Builder::setJoinId( ::uint32_t value) {
_builder.setDataField< ::uint32_t>(
0 * ::capnp::ELEMENTS, value);
}
inline bool JoinAnswer::Reader::getSucceeded() const {
inline bool JoinResult::Reader::getSucceeded() const {
return _reader.getDataField<bool>(
32 * ::capnp::ELEMENTS);
}
inline bool JoinAnswer::Builder::getSucceeded() {
inline bool JoinResult::Builder::getSucceeded() {
return _builder.getDataField<bool>(
32 * ::capnp::ELEMENTS);
}
inline void JoinAnswer::Builder::setSucceeded(bool value) {
inline void JoinResult::Builder::setSucceeded(bool value) {
_builder.setDataField<bool>(
32 * ::capnp::ELEMENTS, value);
}
inline bool JoinResult::Reader::hasCap() const {
return !_reader.getPointerField(0 * ::capnp::POINTERS).isNull();
}
inline bool JoinResult::Builder::hasCap() {
return !_builder.getPointerField(0 * ::capnp::POINTERS).isNull();
}
inline ::capnp::ObjectPointer::Reader JoinResult::Reader::getCap() const {
return ::capnp::ObjectPointer::Reader(
_reader.getPointerField(0 * ::capnp::POINTERS));
}
inline ::capnp::ObjectPointer::Builder JoinResult::Builder::getCap() {
return ::capnp::ObjectPointer::Builder(
_builder.getPointerField(0 * ::capnp::POINTERS));
}
inline ::capnp::ObjectPointer::Builder JoinResult::Builder::initCap() {
auto result = ::capnp::ObjectPointer::Builder(
_builder.getPointerField(0 * ::capnp::POINTERS));
result.clear();
return result;
}
} // namespace
} // namespace
} // namespace
......
......@@ -32,7 +32,7 @@
namespace capnp {
typedef VatNetwork<rpc::twoparty::SturdyRefHostId, rpc::twoparty::ProvisionId,
rpc::twoparty::RecipientId, rpc::twoparty::ThirdPartyCapId, rpc::twoparty::JoinAnswer>
rpc::twoparty::RecipientId, rpc::twoparty::ThirdPartyCapId, rpc::twoparty::JoinResult>
TwoPartyVatNetworkBase;
class TwoPartyVatNetwork: public TwoPartyVatNetworkBase,
......
......@@ -1043,7 +1043,7 @@ private:
injector(kj::heap<CapInjectorImpl>(connectionState)),
context(*injector),
callBuilder(message->getBody().getAs<rpc::Message>().initCall()),
paramsBuilder(context.imbue(callBuilder.getRequest())) {}
paramsBuilder(context.imbue(callBuilder.getParams())) {}
inline ObjectPointer::Builder getRoot() {
return paramsBuilder;
......@@ -1407,7 +1407,7 @@ private:
requestCapExtractor.retainedListSizeHint(request == nullptr));
returnMessage = message->getBody().initAs<rpc::Message>().initReturn();
auto response = kj::heap<RpcServerResponse>(
connectionState, kj::mv(message), returnMessage.getAnswer());
connectionState, kj::mv(message), returnMessage.getResults());
auto results = response->getResults();
this->response = kj::mv(response);
return results;
......@@ -1690,7 +1690,7 @@ private:
QuestionId questionId = call.getQuestionId();
auto context = kj::refcounted<RpcCallContext>(
*this, questionId, kj::mv(message), call.getRequest());
*this, questionId, kj::mv(message), call.getParams());
auto promiseAndPipeline = capability->call(
call.getInterfaceId(), call.getMethodId(), context->addRef());
......@@ -1754,9 +1754,9 @@ private:
}
switch (ret.which()) {
case rpc::Return::ANSWER:
case rpc::Return::RESULTS:
question->fulfiller->fulfill(
kj::refcounted<RpcResponse>(*this, kj::mv(message), ret.getAnswer()));
kj::refcounted<RpcResponse>(*this, kj::mv(message), ret.getResults()));
break;
case rpc::Return::EXCEPTION:
......@@ -1853,9 +1853,12 @@ private:
KJ_IF_MAYBE(exception, kj::runCatchingExceptions([&]() {
KJ_IF_MAYBE(r, restorer) {
Capability::Client cap = r->baseRestore(restore.getObjectId());
auto answer = context.imbue(ret.initAnswer());
answer.setAs<Capability>(cap);
capHook = answer.asReader().getPipelinedCap(nullptr);
auto results = context.imbue(ret.initResults());
results.setAs<Capability>(cap);
// Hack to extract the ClientHook, because Capability::Client doesn't provide direct
// access. Maybe it should?
capHook = results.asReader().getPipelinedCap(nullptr);
} else {
KJ_FAIL_REQUIRE("This vat cannot restore this SturdyRef.") { break; }
}
......
......@@ -277,10 +277,10 @@ struct Call {
methodId @4 :UInt16;
# The ordinal number of the method to call within the requested interface.
request @5 :Object;
# The request struct. The fields of this struct correspond to the parameters of the method.
params @5 :Object;
# The params struct. The fields of this struct correspond to the parameters of the method.
#
# The request may contain capabilities. These capabilities are automatically released when the
# The params may contain capabilities. These capabilities are automatically released when the
# call returns *unless* the Return message explicitly indicates that they are being retained.
}
......@@ -295,17 +295,17 @@ struct Return {
retainedCaps @1 :List(ExportId);
# **(level 1)**
#
# List of capabilities from the request to which the callee continues to hold references. Any
# other capabilities from the request are implicitly released.
# List of capabilities from the params to which the callee continues to hold references. Any
# other capabilities from the params are implicitly released.
union {
answer @2 :Object;
results @2 :Object;
# Result object. If the method returns a struct, this is it. Otherwise, this points to
# a struct which contains exactly one field, corresponding to the method's return type.
# (This implies that an method's return type can be upgraded from a non-struct to a struct
# without breaking wire compatibility.)
#
# For a `Return` in response to an `Accept`, `answer` is a capability pointer (and therefore
# For a `Return` in response to an `Accept`, `results` is a capability pointer (and therefore
# points to a `CapDescriptor`, but is tagged as a capability rather than a struct). A
# `Finish` is still required in this case, and the capability must still be listed in
# `retainedCaps` if it is to be retained.
......@@ -331,9 +331,9 @@ struct Finish {
# Message type sent from the caller to the callee to indicate:
# 1) The questionId will no longer be used in any messages sent by the callee (no further
# pipelined requests).
# 2) Any capabilities in the answer other than the ones listed below should be implicitly
# 2) Any capabilities in the results other than the ones listed below should be implicitly
# released.
# 3) If the answer has not returned yet, the caller no longer cares about the answer, so the
# 3) If the call has not returned yet, the caller no longer cares about the result, so the
# callee may wish to immediately cancel the operation and send back a Return message with
# "canceled" set.
#
......@@ -342,14 +342,14 @@ struct Finish {
# though the caller hasn't yet finished processing the response.
questionId @0 :QuestionId;
# ID of the question whose answer is to be released.
# ID of the call whose result is to be released.
retainedCaps @1 :List(ExportId);
# **(level 1)**
#
# List of capabilities from the answer to which the callee continues to hold references. Any
# other capabilities from the answer that need to be released are implicitly released along
# with the answer itself.
# List of capabilities from the results to which the callee continues to hold references. Any
# other capabilities from the results that need to be released are implicitly released along
# with the result itself.
}
# Level 1 message types ----------------------------------------------
......@@ -434,7 +434,7 @@ struct Save {
questionId @0 :QuestionId;
# A new question ID identifying this request, which will eventually receive a Return
# message whose `answer` is a SturdyRef.
# message whose `results` is a SturdyRef.
target :union {
# What is to be saved.
......@@ -491,7 +491,7 @@ struct Delete {
questionId @0 :QuestionId;
# A new question ID identifying this request, which will eventually receive a Return message
# with an empty answer.
# with an empty (null) result.
objectId @1 :SturdyRefObjectId;
# Designates the capability to delete.
......@@ -510,7 +510,7 @@ struct Provide {
# every vat. In Cap'n Proto, we bake this into the core protocol.)
questionId @0 :QuestionId;
# Question ID to be held open until the recipient has received the capability. An answer will
# Question ID to be held open until the recipient has received the capability. A result will
# be returned once the third party has successfully received the capability. The sender must
# at some point send a `Finish` message as with any other call, and such a message can be
# used to cancel the whole operation.
......@@ -522,7 +522,7 @@ struct Provide {
# An exported capability.
promisedAnswer @2 :PromisedAnswer;
# A capability expected to be returned in the answer to an outstanding question.
# A capability expected to be returned in the results of an outstanding question.
}
recipient @3 :RecipientId;
......@@ -565,14 +565,14 @@ struct Join {
# - Alice is proxying a capability hosted by Dana, so forwards the request to Dana's cap.
# - Dana receives the first request and sees that the JoinKeyPart is one of two. She notes that
# she doesn't have the other part yet, so she records the request and responds with a
# JoinAnswer.
# JoinResult.
# - Alice relays the JoinAswer back to Bob.
# - Carol is also proxying a capability from Dana, and so forwards her Join request to Dana as
# well.
# - Dana receives Carol's request and notes that she now has both parts of a JoinKey. She
# combines them in order to form information needed to form a secure connection to Bob. She
# also responds with another JoinAnswer.
# - Bob receives the responses from Alice and Carol. He uses the returned JoinAnswers to
# also responds with another JoinResult.
# - Bob receives the responses from Alice and Carol. He uses the returned JoinResults to
# determine how to connect to Dana and attempts to form the connection. Since Bob and Dana now
# agree on a secret key which neither Alice nor Carol ever saw, this connection can be made
# securely even if Alice or Carol is conspiring against the other. (If Alice and Carol are
......@@ -589,16 +589,16 @@ struct Join {
# request for one hop; each part has a different ID and relayed copies of the request have
# (probably) different IDs still.)
#
# The receiver will reply with a `Return` whose `answer` is a JoinAnswer. This `JoinAnswer`
# The receiver will reply with a `Return` whose `results` is a JoinResult. This `JoinResult`
# is relayed from the joined object's host, possibly with transformation applied as needed
# by the network.
#
# Like any answer, the answer must be released using a `Finish`. However, this release
# Like any return, the result must be released using a `Finish`. However, this release
# should not occur until the joiner has either successfully connected to the joined object.
# Vats relaying a `Join` message similarly must not release the answer they receive until the
# answer they relayed back towards the joiner has itself been released. This allows the
# Vats relaying a `Join` message similarly must not release the result they receive until the
# return they relayed back towards the joiner has itself been released. This allows the
# joined object's host to detect when the Join operation is canceled before completing -- if
# it receives a `Finish` for one of the join answers before the joiner successfully
# it receives a `Finish` for one of the join results before the joiner successfully
# connects. It can then free any resources it had allocated as part of the join.
capId @1 :ExportId;
......@@ -646,7 +646,7 @@ struct CapDescriptor {
# A capability (or promise) previously exported by the receiver.
receiverAnswer @3 :PromisedAnswer;
# A capability expected to be returned in the answer for a currently-outstanding question posed
# A capability expected to be returned in the results of a currently-outstanding call posed
# by the sender.
thirdPartyHosted @4 :ThirdPartyCapDescriptor;
......@@ -661,7 +661,7 @@ struct PromisedAnswer {
# **(mostly level 1)**
#
# Specifies how to derive a promise from an unanswered question, by specifying the path of fields
# to follow from the root of the eventual answer struct to get to the desired capability. Used
# to follow from the root of the eventual result struct to get to the desired capability. Used
# to address method calls to a not-yet-returned capability or to pass such a capability as an
# input to some other method call.
#
......@@ -674,8 +674,8 @@ struct PromisedAnswer {
# expected to contain the capability.
transform @1 :List(Op);
# Operations / transformations to apply to the answer in order to get the capability actually
# being addressed. E.g. if the answer is a struct and you want to call a method on a capability
# Operations / transformations to apply to the result in order to get the capability actually
# being addressed. E.g. if the result is a struct and you want to call a method on a capability
# pointed to by a field of the struct, you need a `getPointerField` op.
struct Op {
......@@ -705,7 +705,7 @@ struct PromisedAnswer {
# TODO(someday): We could add:
# - For lists, the ability to address every member of the list, or a slice of the list, the
# answer to which would be another list. This is useful for implementing the equivalent of
# result of which would be another list. This is useful for implementing the equivalent of
# a SQL table join (not to be confused with the `Join` message type).
# - Maybe some ability to test a union.
# - Probably not a good idea: the ability to specify an arbitrary script to run on the
......@@ -721,7 +721,7 @@ struct SturdyRef {
# **(level 2)**
#
# A combination of a SturdyRefObjectId and SturdyRefHostId. This is what a client of the ref
# would typically save in its own storage. This type is also the answer to a `Save` message.
# would typically save in its own storage. This type is also the result of a `Save` message.
hostId @0 :SturdyRefHostId;
# Describes how to connect to and authenticate a vat that hosts this SturdyRef (and can therefore
......@@ -891,7 +891,8 @@ using RecipientId = Object;
# capability.
#
# In a network where each vat has a public/private key pair, this could simply be the public key
# fingerprint of the recipient.
# fingerprint of the recipient. (CapTP also calls for a nonce to identify the object. In our
# case, the `Provide` message's `questionId` can serve as the nonce.)
using ThirdPartyCapId = Object;
# **(level 3)**
......@@ -927,18 +928,18 @@ using JoinKeyPart = Object;
# the joiner and the joined object's host. Each JoinKeyPart should also include an indication of
# how many parts to expect and a hash of the shared secret (used to match up parts).
using JoinAnswer = Object;
using JoinResult = Object;
# **(level 4)**
#
# Information returned in the answer to a `Join` message, needed by the joiner in order to form a
# Information returned as the result to a `Join` message, needed by the joiner in order to form a
# direct connection to a joined object. This might simply be the address of the joined object's
# host vat, since the `JoinKey` has already been communicated so the two vats already have a shared
# secret to use to authenticate each other.
#
# The `JoinAnswer` should also contain information that can be used to detect when the Join
# The `JoinResult` should also contain information that can be used to detect when the Join
# requests ended up reaching different objects, so that this situation can be detected easily.
# This could be a simple matter of including a sequence number -- if the joiner receives two
# `JoinAnswer`s with sequence number 0, then they must have come from different objects and the
# `JoinResult`s with sequence number 0, then they must have come from different objects and the
# whole join is a failure.
# ========================================================================================
......@@ -989,8 +990,8 @@ using JoinAnswer = Object;
# }
#
# interface Joiner {
# addJoinAnswer(answer :JoinAnswer) :Void;
# # Add a JoinAnswer received in response to one of the `Join` messages. All `JoinAnswer`s
# addJoinResult(result :JoinResult) :Void;
# # Add a JoinResult received in response to one of the `Join` messages. All `JoinResult`s
# # returned from all paths must be added before trying to connect.
#
# connect() :ConnectionAndProvisionId;
......
......@@ -275,7 +275,7 @@ static const ::capnp::_::AlignedData<83> b_836a53ce789d4cd4 = {
4, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
113, 0, 0, 0, 66, 0, 0, 0,
113, 0, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
108, 0, 0, 0, 2, 0, 1, 0,
116, 0, 0, 0, 2, 0, 1, 0,
......@@ -304,7 +304,7 @@ static const ::capnp::_::AlignedData<83> b_836a53ce789d4cd4 = {
7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
114, 101, 113, 117, 101, 115, 116, 0,
112, 97, 114, 97, 109, 115, 0, 0,
18, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
......@@ -315,7 +315,7 @@ static const ::capnp::_::AlignedData<83> b_836a53ce789d4cd4 = {
static const ::capnp::_::RawSchema* const d_836a53ce789d4cd4[] = {
&s_cb72865a863459a7,
};
static const uint16_t m_836a53ce789d4cd4[] = {2, 3, 0, 4, 1};
static const uint16_t m_836a53ce789d4cd4[] = {2, 3, 4, 0, 1};
static const uint16_t i_836a53ce789d4cd4[] = {0, 1, 2, 3, 4};
const ::capnp::_::RawSchema s_836a53ce789d4cd4 = {
0x836a53ce789d4cd4, b_836a53ce789d4cd4.words, 83, d_836a53ce789d4cd4, m_836a53ce789d4cd4,
......@@ -413,7 +413,7 @@ static const ::capnp::_::AlignedData<109> b_9e19b28d3db3573a = {
2, 0, 255, 255, 1, 0, 0, 0,
0, 0, 1, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
173, 0, 0, 0, 58, 0, 0, 0,
173, 0, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
168, 0, 0, 0, 2, 0, 1, 0,
176, 0, 0, 0, 2, 0, 1, 0,
......@@ -457,7 +457,7 @@ static const ::capnp::_::AlignedData<109> b_9e19b28d3db3573a = {
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
97, 110, 115, 119, 101, 114, 0, 0,
114, 101, 115, 117, 108, 116, 115, 0,
18, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
......@@ -493,7 +493,7 @@ static const ::capnp::_::AlignedData<109> b_9e19b28d3db3573a = {
static const ::capnp::_::RawSchema* const d_9e19b28d3db3573a[] = {
&s_d625b7063acf691a,
};
static const uint16_t m_9e19b28d3db3573a[] = {2, 4, 3, 0, 1, 5};
static const uint16_t m_9e19b28d3db3573a[] = {4, 3, 0, 2, 1, 5};
static const uint16_t i_9e19b28d3db3573a[] = {2, 3, 4, 5, 0, 1};
const ::capnp::_::RawSchema s_9e19b28d3db3573a = {
0x9e19b28d3db3573a, b_9e19b28d3db3573a.words, 109, d_9e19b28d3db3573a, m_9e19b28d3db3573a,
......
......@@ -65,7 +65,7 @@ struct Return {
class Builder;
class Pipeline;
enum Which: uint16_t {
ANSWER,
RESULTS,
EXCEPTION,
CANCELED,
UNSUPPORTED_PIPELINE_OP,
......@@ -593,8 +593,8 @@ public:
inline ::uint16_t getMethodId() const;
inline bool hasRequest() const;
inline ::capnp::ObjectPointer::Reader getRequest() const;
inline bool hasParams() const;
inline ::capnp::ObjectPointer::Reader getParams() const;
private:
::capnp::_::StructReader _reader;
......@@ -638,9 +638,9 @@ public:
inline ::uint16_t getMethodId();
inline void setMethodId( ::uint16_t value);
inline bool hasRequest();
inline ::capnp::ObjectPointer::Builder getRequest();
inline ::capnp::ObjectPointer::Builder initRequest();
inline bool hasParams();
inline ::capnp::ObjectPointer::Builder getParams();
inline ::capnp::ObjectPointer::Builder initParams();
private:
::capnp::_::StructBuilder _builder;
......@@ -774,9 +774,9 @@ public:
inline bool hasRetainedCaps() const;
inline ::capnp::List< ::uint32_t>::Reader getRetainedCaps() const;
inline bool isAnswer() const;
inline bool hasAnswer() const;
inline ::capnp::ObjectPointer::Reader getAnswer() const;
inline bool isResults() const;
inline bool hasResults() const;
inline ::capnp::ObjectPointer::Reader getResults() const;
inline bool isException() const;
inline bool hasException() const;
......@@ -830,10 +830,10 @@ public:
inline void adoptRetainedCaps(::capnp::Orphan< ::capnp::List< ::uint32_t>>&& value);
inline ::capnp::Orphan< ::capnp::List< ::uint32_t>> disownRetainedCaps();
inline bool isAnswer();
inline bool hasAnswer();
inline ::capnp::ObjectPointer::Builder getAnswer();
inline ::capnp::ObjectPointer::Builder initAnswer();
inline bool isResults();
inline bool hasResults();
inline ::capnp::ObjectPointer::Builder getResults();
inline ::capnp::ObjectPointer::Builder initResults();
inline bool isException();
inline bool hasException();
......@@ -3070,21 +3070,21 @@ inline void Call::Builder::setMethodId( ::uint16_t value) {
5 * ::capnp::ELEMENTS, value);
}
inline bool Call::Reader::hasRequest() const {
inline bool Call::Reader::hasParams() const {
return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull();
}
inline bool Call::Builder::hasRequest() {
inline bool Call::Builder::hasParams() {
return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull();
}
inline ::capnp::ObjectPointer::Reader Call::Reader::getRequest() const {
inline ::capnp::ObjectPointer::Reader Call::Reader::getParams() const {
return ::capnp::ObjectPointer::Reader(
_reader.getPointerField(1 * ::capnp::POINTERS));
}
inline ::capnp::ObjectPointer::Builder Call::Builder::getRequest() {
inline ::capnp::ObjectPointer::Builder Call::Builder::getParams() {
return ::capnp::ObjectPointer::Builder(
_builder.getPointerField(1 * ::capnp::POINTERS));
}
inline ::capnp::ObjectPointer::Builder Call::Builder::initRequest() {
inline ::capnp::ObjectPointer::Builder Call::Builder::initParams() {
auto result = ::capnp::ObjectPointer::Builder(
_builder.getPointerField(1 * ::capnp::POINTERS));
result.clear();
......@@ -3233,35 +3233,35 @@ inline ::capnp::Orphan< ::capnp::List< ::uint32_t>> Return::Builder::disownRetai
_builder.getPointerField(0 * ::capnp::POINTERS));
}
inline bool Return::Reader::isAnswer() const {
return which() == Return::ANSWER;
inline bool Return::Reader::isResults() const {
return which() == Return::RESULTS;
}
inline bool Return::Builder::isAnswer() {
return which() == Return::ANSWER;
inline bool Return::Builder::isResults() {
return which() == Return::RESULTS;
}
inline bool Return::Reader::hasAnswer() const {
if (which() != Return::ANSWER) return false;
inline bool Return::Reader::hasResults() const {
if (which() != Return::RESULTS) return false;
return !_reader.getPointerField(1 * ::capnp::POINTERS).isNull();
}
inline bool Return::Builder::hasAnswer() {
if (which() != Return::ANSWER) return false;
inline bool Return::Builder::hasResults() {
if (which() != Return::RESULTS) return false;
return !_builder.getPointerField(1 * ::capnp::POINTERS).isNull();
}
inline ::capnp::ObjectPointer::Reader Return::Reader::getAnswer() const {
KJ_IREQUIRE(which() == Return::ANSWER,
inline ::capnp::ObjectPointer::Reader Return::Reader::getResults() const {
KJ_IREQUIRE(which() == Return::RESULTS,
"Must check which() before get()ing a union member.");
return ::capnp::ObjectPointer::Reader(
_reader.getPointerField(1 * ::capnp::POINTERS));
}
inline ::capnp::ObjectPointer::Builder Return::Builder::getAnswer() {
KJ_IREQUIRE(which() == Return::ANSWER,
inline ::capnp::ObjectPointer::Builder Return::Builder::getResults() {
KJ_IREQUIRE(which() == Return::RESULTS,
"Must check which() before get()ing a union member.");
return ::capnp::ObjectPointer::Builder(
_builder.getPointerField(1 * ::capnp::POINTERS));
}
inline ::capnp::ObjectPointer::Builder Return::Builder::initAnswer() {
inline ::capnp::ObjectPointer::Builder Return::Builder::initResults() {
_builder.setDataField<Return::Which>(
2 * ::capnp::ELEMENTS, Return::ANSWER);
2 * ::capnp::ELEMENTS, Return::RESULTS);
auto result = ::capnp::ObjectPointer::Builder(
_builder.getPointerField(1 * ::capnp::POINTERS));
result.clear();
......
......@@ -124,7 +124,7 @@ public:
};
template <typename SturdyRefHostId, typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer>
typename ThirdPartyCapId, typename JoinResult>
class VatNetwork: public _::VatNetworkBase {
public:
class Connection;
......@@ -251,10 +251,10 @@ template <typename SturdyRefHostId>
class RpcSystem: public _::RpcSystemBase {
public:
template <typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer,
typename ThirdPartyCapId, typename JoinResult,
typename LocalSturdyRefObjectId>
RpcSystem(
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>& network,
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
kj::Maybe<SturdyRefRestorer<LocalSturdyRefObjectId>&> restorer,
const kj::EventLoop& eventLoop);
RpcSystem(RpcSystem&& other) = default;
......@@ -265,9 +265,9 @@ public:
};
template <typename SturdyRefHostId, typename LocalSturdyRefObjectId,
typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinAnswer>
typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
RpcSystem<SturdyRefHostId> makeRpcServer(
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>& network,
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
SturdyRefRestorer<LocalSturdyRefObjectId>& restorer,
const kj::EventLoop& eventLoop = kj::EventLoop::current());
// Make an RPC server. Typical usage (e.g. in a main() function):
......@@ -279,9 +279,9 @@ RpcSystem<SturdyRefHostId> makeRpcServer(
// eventLoop.wait(...); // (e.g. wait on a promise that never returns)
template <typename SturdyRefHostId, typename ProvisionId,
typename RecipientId, typename ThirdPartyCapId, typename JoinAnswer>
typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
RpcSystem<SturdyRefHostId> makeRpcClient(
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>& network,
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
const kj::EventLoop& eventLoop = kj::EventLoop::current());
// Make an RPC client. Typical usage (e.g. in a main() function):
//
......@@ -300,8 +300,8 @@ RpcSystem<SturdyRefHostId> makeRpcClient(
// =======================================================================================
template <typename SturdyRef, typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer>
void VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>::
typename ThirdPartyCapId, typename JoinResult>
void VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
Connection::baseIntroduceTo(VatNetworkBase::Connection& recipient,
ObjectPointer::Builder sendToRecipient,
ObjectPointer::Builder sendToTarget) {
......@@ -310,26 +310,26 @@ void VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer
}
template <typename SturdyRef, typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer>
typename ThirdPartyCapId, typename JoinResult>
_::VatNetworkBase::ConnectionAndProvisionId
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>::
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
Connection::baseConnectToIntroduced(ObjectPointer::Reader capId) {
auto result = connectToIntroduced(capId.getAs<ThirdPartyCapId>());
return { kj::mv(result.connection), kj::mv(result.firstMessage), kj::mv(result.provisionId) };
}
template <typename SturdyRef, typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer>
typename ThirdPartyCapId, typename JoinResult>
kj::Own<_::VatNetworkBase::Connection>
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>::
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
Connection::baseAcceptIntroducedConnection(ObjectPointer::Reader recipientId) {
return acceptIntroducedConnection(recipientId.getAs<RecipientId>());
}
template <typename SturdyRef, typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer>
typename ThirdPartyCapId, typename JoinResult>
kj::Maybe<kj::Own<_::VatNetworkBase::Connection>>
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>::
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
baseConnectToRefHost(_::StructReader ref) {
auto maybe = connectToRefHost(typename SturdyRef::Reader(ref));
return maybe.map([](kj::Own<Connection>& conn) -> kj::Own<_::VatNetworkBase::Connection> {
......@@ -338,9 +338,9 @@ kj::Maybe<kj::Own<_::VatNetworkBase::Connection>>
}
template <typename SturdyRef, typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer>
typename ThirdPartyCapId, typename JoinResult>
kj::Promise<kj::Own<_::VatNetworkBase::Connection>>
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>::
VatNetwork<SturdyRef, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>::
baseAcceptConnectionAsRefHost() {
return acceptConnectionAsRefHost().thenInAnyThread(
[](kj::Own<Connection>&& connection) -> kj::Own<_::VatNetworkBase::Connection> {
......@@ -355,10 +355,10 @@ Capability::Client SturdyRefRestorer<SturdyRef>::baseRestore(ObjectPointer::Read
template <typename SturdyRefHostId>
template <typename ProvisionId, typename RecipientId,
typename ThirdPartyCapId, typename JoinAnswer,
typename ThirdPartyCapId, typename JoinResult,
typename LocalSturdyRefObjectId>
RpcSystem<SturdyRefHostId>::RpcSystem(
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>& network,
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
kj::Maybe<SturdyRefRestorer<LocalSturdyRefObjectId>&> restorer,
const kj::EventLoop& eventLoop)
: _::RpcSystemBase(network, restorer, eventLoop) {}
......@@ -370,18 +370,18 @@ Capability::Client RpcSystem<SturdyRefHostId>::restore(
}
template <typename SturdyRefHostId, typename LocalSturdyRefObjectId,
typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinAnswer>
typename ProvisionId, typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
RpcSystem<SturdyRefHostId> makeRpcServer(
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>& network,
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
SturdyRefRestorer<LocalSturdyRefObjectId>& restorer, const kj::EventLoop& eventLoop) {
return RpcSystem<SturdyRefHostId>(network,
kj::Maybe<SturdyRefRestorer<LocalSturdyRefObjectId>&>(restorer), eventLoop);
}
template <typename SturdyRefHostId, typename ProvisionId,
typename RecipientId, typename ThirdPartyCapId, typename JoinAnswer>
typename RecipientId, typename ThirdPartyCapId, typename JoinResult>
RpcSystem<SturdyRefHostId> makeRpcClient(
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinAnswer>& network,
VatNetwork<SturdyRefHostId, ProvisionId, RecipientId, ThirdPartyCapId, JoinResult>& network,
const kj::EventLoop& eventLoop) {
return RpcSystem<SturdyRefHostId>(network,
kj::Maybe<SturdyRefRestorer<ObjectPointer>&>(nullptr), eventLoop);
......
......@@ -626,4 +626,4 @@ struct TestSturdyRefObjectId {
struct TestProvisionId {}
struct TestRecipientId {}
struct TestThirdPartyCapId {}
struct TestJoinAnswer {}
struct TestJoinResult {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment