checkpoint

This commit is contained in:
John Smith
2023-02-17 17:47:21 -05:00
parent ca3ce91365
commit 05be3099c8
17 changed files with 205 additions and 152 deletions

View File

@@ -476,6 +476,10 @@ impl BucketEntryInner {
self.envelope_support.clone()
}
pub fn best_envelope_version(&self) -> Option<u8> {
self.envelope_support.iter().rev().find(|x| VALID_ENVELOPE_VERSIONS.contains(x)).copied()
}
pub fn state(&self, cur_ts: Timestamp) -> BucketEntryState {
if self.check_reliable(cur_ts) {
BucketEntryState::Reliable

View File

@@ -132,6 +132,9 @@ pub trait NodeRefBase: Sized {
fn set_envelope_support(&self, envelope_support: Vec<u8>) {
self.operate_mut(|_rti, e| e.set_envelope_support(envelope_support))
}
fn best_envelope_version(&self) -> Option<u8> {
self.operate(|_rti, e| e.best_envelope_version())
}
fn state(&self, cur_ts: Timestamp) -> BucketEntryState {
self.operate(|_rti, e| e.state(cur_ts))
}

View File

@@ -16,7 +16,7 @@ pub struct RouteHopData {
#[derive(Clone, Debug)]
pub enum RouteNode {
/// Route node is optimized, no contact method information as this node id has been seen before
NodeId(TypedKey),
NodeId(PublicKey),
/// Route node with full contact method information to ensure the peer is reachable
PeerInfo(PeerInfo),
}
@@ -79,6 +79,11 @@ impl PrivateRoute {
false
}
/// Get the crypto kind in use for this route
pub fn crypto_kind(&self) -> CryptoKind {
self.public_key.kind
}
/// Remove the first unencrypted hop if possible
pub fn pop_first_hop(&mut self) -> Option<RouteNode> {
match &mut self.hops {
@@ -112,8 +117,8 @@ impl PrivateRoute {
// Get the safety route to use from the spec
Some(match &pr_first_hop.node {
RouteNode::NodeId(n) => n,
RouteNode::PeerInfo(p) => p.node_id.key,
RouteNode::NodeId(n) => TypedKey::new(self.public_key.kind, *n),
RouteNode::PeerInfo(p) => p.node_ids.get(self.public_key.kind).unwrap(),
})
}
}
@@ -126,8 +131,13 @@ impl fmt::Display for PrivateRoute {
self.public_key,
self.hop_count,
match &self.hops {
PrivateRouteHops::FirstHop(fh) => {
format!("->{}", fh.node)
PrivateRouteHops::FirstHop(_) => {
format!(
"->{}",
self.first_hop_node_id()
.map(|n| n.to_string())
.unwrap_or_else(|| "None".to_owned())
)
}
PrivateRouteHops::Data(_) => {
"->?".to_owned()
@@ -156,6 +166,7 @@ pub struct SafetyRoute {
}
impl SafetyRoute {
/// Stub route is the form used when no privacy is required, but you need to directly contact a private route
pub fn new_stub(public_key: TypedKey, private_route: PrivateRoute) -> Self {
// First hop should have already been popped off for stubbed safety routes since
// we are sending directly to the first hop
@@ -166,9 +177,16 @@ impl SafetyRoute {
hops: SafetyRouteHops::Private(private_route),
}
}
/// Check if this is a stub route
pub fn is_stub(&self) -> bool {
matches!(self.hops, SafetyRouteHops::Private(_))
}
/// Get the crypto kind in use for this route
pub fn crypto_kind(&self) -> CryptoKind {
self.public_key.kind
}
}
impl fmt::Display for SafetyRoute {

View File

@@ -163,6 +163,8 @@ impl RouteStats {
#[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct RouteSpecDetail {
/// Crypto kind
crypto_kind: CryptoKind,
/// Secret key
#[with(Skip)]
secret_key: SecretKey,
@@ -187,6 +189,9 @@ pub struct RouteSpecDetail {
}
impl RouteSpecDetail {
pub fn get_crypto_kind(&self) -> CryptoKind {
self.crypto_kind
}
pub fn get_stats(&self) -> &RouteStats {
&self.stats
}
@@ -221,13 +226,13 @@ impl RouteSpecDetail {
#[archive_attr(repr(C, align(8)), derive(CheckBytes))]
pub struct RouteSpecStoreContent {
/// All of the routes we have allocated so far
details: HashMap<TypedKey, RouteSpecDetail>,
details: HashMap<PublicKey, RouteSpecDetail>,
}
/// What remote private routes have seen
#[derive(Debug, Clone, Default)]
pub struct RemotePrivateRouteInfo {
// The private route itself
/// The private route itself
private_route: Option<PrivateRoute>,
/// Did this remote private route see our node info due to no safety route in use
last_seen_our_node_info_ts: Timestamp,
@@ -256,13 +261,13 @@ pub struct RouteSpecStoreCache {
/// Route spec hop cache, used to quickly disqualify routes
hop_cache: HashSet<Vec<u8>>,
/// Has a remote private route responded to a question and when
remote_private_route_cache: LruCache<TypedKey, RemotePrivateRouteInfo>,
remote_private_route_cache: LruCache<PublicKey, RemotePrivateRouteInfo>,
/// Compiled route cache
compiled_route_cache: LruCache<CompiledRouteCacheKey, SafetyRoute>,
/// List of dead allocated routes
dead_routes: Vec<TypedKey>,
dead_routes: Vec<PublicKey>,
/// List of dead remote routes
dead_remote_routes: Vec<TypedKey>,
dead_remote_routes: Vec<PublicKey>,
}
impl Default for RouteSpecStoreCache {
@@ -602,6 +607,7 @@ impl RouteSpecStore {
/// Prefers nodes that are not currently in use by another route
/// The route is not yet tested for its reachability
/// Returns None if no route could be allocated at this time
/// Returns Some list of public keys for the requested set of crypto kinds
#[instrument(level = "trace", skip(self), ret, err)]
pub fn allocate_route(
&self,
@@ -1590,8 +1596,8 @@ impl RouteSpecStore {
rti: &RoutingTableInner,
safety_spec: &SafetySpec,
direction: DirectionSet,
avoid_nodes: &[TypedKey],
) -> EyreResult<Option<TypedKeySet>> {
avoid_nodes: &[PublicKey],
) -> EyreResult<Option<PublicKey>> {
// Ensure the total hop count isn't too long for our config
let max_route_hop_count = self.unlocked_inner.max_route_hop_count;
if safety_spec.hop_count == 0 {
@@ -1645,13 +1651,14 @@ impl RouteSpecStore {
Ok(Some(sr_pubkey))
}
/// Get a private sroute to use for the answer to question
/// Get a private route to use for the answer to question
#[instrument(level = "trace", skip(self), ret, err)]
pub fn get_private_route_for_safety_spec(
&self,
crypto_kind: CryptoKind,
safety_spec: &SafetySpec,
avoid_nodes: &[TypedKey],
) -> EyreResult<Option<TypedKey>> {
avoid_nodes: &[PublicKey],
) -> EyreResult<Option<PublicKey>> {
let inner = &mut *self.inner.lock();
let routing_table = self.unlocked_inner.routing_table.clone();
let rti = &*routing_table.inner.read();
@@ -1669,7 +1676,7 @@ impl RouteSpecStore {
#[instrument(level = "trace", skip(self), err)]
pub fn assemble_private_route(
&self,
key: &TypedKey,
key: &PublicKey,
optimized: Option<bool>,
) -> EyreResult<PrivateRoute> {
let inner = &*self.inner.lock();
@@ -1758,7 +1765,7 @@ impl RouteSpecStore {
/// Import a remote private route for compilation
#[instrument(level = "trace", skip(self, blob), ret, err)]
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> EyreResult<TypedKey> {
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> EyreResult<PublicKey> {
// decode the pr blob
let private_route = RouteSpecStore::blob_to_private_route(blob)?;
@@ -1783,7 +1790,7 @@ impl RouteSpecStore {
/// Release a remote private route that is no longer in use
#[instrument(level = "trace", skip(self), ret)]
fn release_remote_private_route(&self, key: &TypedKey) -> bool {
fn release_remote_private_route(&self, key: &PublicKey) -> bool {
let inner = &mut *self.inner.lock();
if inner.cache.remote_private_route_cache.remove(key).is_some() {
// Mark it as dead for the update
@@ -1795,7 +1802,7 @@ impl RouteSpecStore {
}
/// Retrieve an imported remote private route by its public key
pub fn get_remote_private_route(&self, key: &TypedKey) -> Option<PrivateRoute> {
pub fn get_remote_private_route(&self, key: &PublicKey) -> Option<PrivateRoute> {
let inner = &mut *self.inner.lock();
let cur_ts = get_aligned_timestamp();
Self::with_get_remote_private_route(inner, cur_ts, key, |r| {
@@ -1804,7 +1811,7 @@ impl RouteSpecStore {
}
/// Retrieve an imported remote private route by its public key but don't 'touch' it
pub fn peek_remote_private_route(&self, key: &TypedKey) -> Option<PrivateRoute> {
pub fn peek_remote_private_route(&self, key: &PublicKey) -> Option<PrivateRoute> {
let inner = &mut *self.inner.lock();
let cur_ts = get_aligned_timestamp();
Self::with_peek_remote_private_route(inner, cur_ts, key, |r| {
@@ -1865,7 +1872,7 @@ impl RouteSpecStore {
fn with_get_remote_private_route<F, R>(
inner: &mut RouteSpecStoreInner,
cur_ts: Timestamp,
remote_private_route: &TypedKey,
key: &PublicKey,
f: F,
) -> Option<R>
where
@@ -1885,7 +1892,7 @@ impl RouteSpecStore {
fn with_peek_remote_private_route<F, R>(
inner: &mut RouteSpecStoreInner,
cur_ts: Timestamp,
remote_private_route: &TypedKey,
key: &PublicKey,
f: F,
) -> Option<R>
where
@@ -1907,7 +1914,7 @@ impl RouteSpecStore {
/// Check to see if this remote (not ours) private route has seen our current node info yet
/// This happens when you communicate with a private route without a safety route
pub fn has_remote_private_route_seen_our_node_info(&self, remote_private_route: &TypedKey) -> bool {
pub fn has_remote_private_route_seen_our_node_info(&self, key: &PublicKey) -> bool {
let our_node_info_ts = {
let rti = &*self.unlocked_inner.routing_table.inner.read();
let Some(ts) = rti.get_own_node_info_ts(RoutingDomain::PublicInternet) else {
@@ -1919,7 +1926,7 @@ impl RouteSpecStore {
let opt_rpr_node_info_ts = {
let inner = &mut *self.inner.lock();
let cur_ts = get_aligned_timestamp();
Self::with_peek_remote_private_route(inner, cur_ts, remote_private_route, |rpr| {
Self::with_peek_remote_private_route(inner, cur_ts, key, |rpr| {
rpr.last_seen_our_node_info_ts
})
};