refactor checkpoint

This commit is contained in:
John Smith
2022-09-04 14:17:28 -04:00
parent e0a5b1bd69
commit 79cda4a712
25 changed files with 531 additions and 398 deletions

View File

@@ -200,22 +200,8 @@ impl RPCProcessor {
/// Determine if a NodeInfo can be placed into the specified routing domain
fn filter_node_info(&self, routing_domain: RoutingDomain, node_info: &NodeInfo) -> bool {
// reject attempts to include non-public addresses in results
for did in &node_info.dial_info_detail_list {
if !did.dial_info.is_global() {
// non-public address causes rejection
return false;
}
}
if let Some(rpi) = &node_info.relay_peer_info {
for did in &rpi.signed_node_info.node_info.dial_info_detail_list {
if !did.dial_info.is_global() {
// non-public address causes rejection
return false;
}
}
}
true
let routing_table = self.routing_table();
routing_table.node_info_is_valid_in_routing_domain(routing_domain, &node_info)
}
//////////////////////////////////////////////////////////////////////
@@ -360,9 +346,6 @@ impl RPCProcessor {
waitable_reply.node_ref.stats_question_lost();
}
Ok(TimeoutOr::Value((rpcreader, _))) => {
// Note that the remote node definitely received this node info since we got a reply
waitable_reply.node_ref.set_seen_our_node_info();
// Reply received
let recv_ts = intf::get_timestamp();
waitable_reply.node_ref.stats_answer_rcvd(
@@ -403,13 +386,11 @@ impl RPCProcessor {
match dest {
Destination::Direct {
target: node_ref,
routing_domain,
safety_route_spec,
}
| Destination::Relay {
relay: node_ref,
target: _,
routing_domain,
safety_route_spec,
} => {
// Send to a node without a private route
@@ -419,7 +400,6 @@ impl RPCProcessor {
let (node_ref, node_id) = if let Destination::Relay {
relay: _,
target: dht_key,
routing_domain: _,
safety_route_spec: _,
} = dest
{
@@ -508,6 +488,53 @@ impl RPCProcessor {
})
}
// Get signed node info to package with RPC messages to improve
// routing table caching when it is okay to do so
// This is only done in the PublicInternet routing domain because
// as far as we can tell this is the only domain that will really benefit
fn get_sender_signed_node_info(&self, dest: &Destination) -> Option<SignedNodeInfo> {
// Don't do this if the sender is to remain private
if dest.safety_route_spec().is_some() {
return None;
}
// Don't do this if our own signed node info isn't valid yet
let routing_table = self.routing_table();
if !routing_table.has_valid_own_node_info(RoutingDomain::PublicInternet) {
return None;
}
match dest {
Destination::Direct {
target,
safety_route_spec: _,
} => {
// If the target has seen our node info already don't do this
if target.has_seen_our_node_info(RoutingDomain::PublicInternet) {
return None;
}
Some(routing_table.get_own_signed_node_info(RoutingDomain::PublicInternet))
}
Destination::Relay {
relay: _,
target,
safety_route_spec: _,
} => {
if let Some(target) = routing_table.lookup_node_ref(*target) {
if target.has_seen_our_node_info(RoutingDomain::PublicInternet) {
return None;
}
Some(routing_table.get_own_signed_node_info(RoutingDomain::PublicInternet))
} else {
None
}
}
Destination::PrivateRoute {
private_route: _,
safety_route_spec: _,
} => None,
}
}
// Issue a question over the network, possibly using an anonymized route
#[instrument(level = "debug", skip(self, question), err)]
async fn question(
@@ -515,18 +542,11 @@ impl RPCProcessor {
dest: Destination,
question: RPCQuestion,
) -> Result<NetworkResult<WaitableReply>, RPCError> {
// Get sender info if we should send that
let opt_sender_info = if dest.safety_route_spec().is_none() && matches!(question.respond_to(), RespondTo::Sender) {
// Sender is not private, send sender info if needed
// Get the noderef of the eventual destination or first route hop
if let Some(target_nr) = self.routing_table().lookup_node_ref(dest.get_target_id()) {
if target_nr.has_seen_our_node_info(R)
}
}
let opt_sender_info = self.get_sender_signed_node_info(&dest);
// Wrap question in operation
let operation = RPCOperation::new_question(question);
let operation = RPCOperation::new_question(question, opt_sender_info);
let op_id = operation.op_id();
// Log rpc send
@@ -538,7 +558,7 @@ impl RPCProcessor {
node_id,
node_ref,
hop_count,
} = self.render_operation(dest, &operation, safety_route_spec)?;
} = self.render_operation(dest, &operation)?;
// If we need to resolve the first hop, do it
let node_ref = match node_ref {
@@ -594,14 +614,17 @@ impl RPCProcessor {
}
// Issue a statement over the network, possibly using an anonymized route
#[instrument(level = "debug", skip(self, statement, safety_route_spec), err)]
#[instrument(level = "debug", skip(self, statement), err)]
async fn statement(
&self,
dest: Destination,
statement: RPCStatement,
) -> Result<NetworkResult<()>, RPCError> {
// Get sender info if we should send that
let opt_sender_info = self.get_sender_signed_node_info(&dest);
// Wrap statement in operation
let operation = RPCOperation::new_statement(statement);
let operation = RPCOperation::new_statement(statement, opt_sender_info);
// Log rpc send
debug!(target: "rpc_message", dir = "send", kind = "statement", op_id = operation.op_id(), desc = operation.kind().desc(), ?dest);
@@ -612,7 +635,7 @@ impl RPCProcessor {
node_id,
node_ref,
hop_count: _,
} = self.render_operation(dest, &operation, safety_route_spec)?;
} = self.render_operation(dest, &operation)?;
// If we need to resolve the first hop, do it
let node_ref = match node_ref {
@@ -662,7 +685,7 @@ impl RPCProcessor {
// To where should we respond?
match respond_to {
RespondTo::Sender(_) => {
RespondTo::Sender => {
// Reply directly to the request's source
let sender_id = request.header.envelope.get_sender_id();
@@ -672,29 +695,32 @@ impl RPCProcessor {
// If the sender_id is that of the peer, then this is a direct reply
// else it is a relayed reply through the peer
if peer_noderef.node_id() == sender_id {
Destination::Direct(peer_noderef)
Destination::direct(peer_noderef)
} else {
Destination::Relay(peer_noderef, sender_id)
Destination::relay(peer_noderef, sender_id)
}
}
RespondTo::PrivateRoute(pr) => Destination::PrivateRoute(pr.clone()),
RespondTo::PrivateRoute(pr) => Destination::private_route(pr.clone()),
}
}
// Issue a reply over the network, possibly using an anonymized route
// The request must want a response, or this routine fails
#[instrument(level = "debug", skip(self, request, answer, safety_route_spec), err)]
#[instrument(level = "debug", skip(self, request, answer), err)]
async fn answer(
&self,
request: RPCMessage,
answer: RPCAnswer,
) -> Result<NetworkResult<()>, RPCError> {
// Wrap answer in operation
let operation = RPCOperation::new_answer(&request.operation, answer);
// Extract destination from respond_to
let dest = self.get_respond_to_destination(&request);
// Get sender info if we should send that
let opt_sender_info = self.get_sender_signed_node_info(&dest);
// Wrap answer in operation
let operation = RPCOperation::new_answer(&request.operation, answer, opt_sender_info);
// Log rpc send
debug!(target: "rpc_message", dir = "send", kind = "answer", op_id = operation.op_id(), desc = operation.kind().desc(), ?dest);
@@ -704,7 +730,7 @@ impl RPCProcessor {
node_id,
node_ref,
hop_count: _,
} = self.render_operation(dest, &operation, safety_route_spec)?;
} = self.render_operation(dest, &operation)?;
// If we need to resolve the first hop, do it
let node_ref = match node_ref {
@@ -747,8 +773,7 @@ impl RPCProcessor {
&self,
encoded_msg: RPCMessageEncoded,
) -> Result<(), RPCError> {
// Get the routing domain
// Get the routing domain this message came over
let routing_domain = encoded_msg.header.routing_domain;
// Decode the operation
@@ -764,35 +789,34 @@ impl RPCProcessor {
RPCOperation::decode(&op_reader, &sender_node_id)?
};
// Get the sender noderef, incorporating and 'sender node info' we have from a question
// Get the sender noderef, incorporating and 'sender node info'
let mut opt_sender_nr: Option<NodeRef> = None;
match operation.kind() {
RPCOperationKind::Question(q) => {
match q.respond_to() {
RespondTo::Sender(Some(sender_ni)) => {
// Sender NodeInfo was specified, update our routing table with it
if !self.filter_node_info(&sender_ni.node_info) {
return Err(RPCError::invalid_format(
"respond_to_sender_signed_node_info has invalid peer scope",
));
}
opt_sender_nr = self.routing_table().register_node_with_signed_node_info(
routing_domain,
sender_node_id,
sender_ni.clone(),
false,
);
}
_ => {}
}
if let Some(sender_node_info) = operation.sender_node_info() {
// Sender NodeInfo was specified, update our routing table with it
if !self.filter_node_info(RoutingDomain::PublicInternet, &sender_node_info.node_info) {
return Err(RPCError::invalid_format(
"sender signednodeinfo has invalid peer scope",
));
}
_ => {}
};
opt_sender_nr = self.routing_table().register_node_with_signed_node_info(
routing_domain,
sender_node_id,
sender_node_info.clone(),
false,
);
}
// look up sender node, in case it's different than our peer due to relaying
if opt_sender_nr.is_none() {
// look up sender node, in case it's different than our peer due to relaying
opt_sender_nr = self.routing_table().lookup_node_ref(sender_node_id)
}
// Mark this sender as having seen our node info over this routing domain
// because it managed to reach us over that routing domain
if let Some(sender_nr) = &opt_sender_nr {
sender_nr.set_seen_our_node_info(routing_domain);
}
// Make the RPC message
let msg = RPCMessage {
header: encoded_msg.header,