Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inbound eviction logic / policy. #431

Open
wants to merge 39 commits into
base: master
Choose a base branch
from

Conversation

D-Stacks
Copy link
Collaborator

@D-Stacks D-Stacks commented Mar 12, 2024

This adds eviction logic and a policy to rusty-kaspa.

The idea is borrowed from btc and straight forward:

  1. rank peers, by last_ping_duration, time_connected, last_tx_transfer (duration), last_block_transfer (duration), prefix_bucket (dispersal).

  2. keep 40% of the best performing peers on any individual metric:

  • This means an eclipse attacker most outperform the best individual performer with all of its rankings.
  1. from the remaining peers, evicted peers are selected via a weighted choose function accounting for time-connected and prefix_bucket:
  • Here weights are not influenced by latency (as to not starve low-latency peers), This will also cause the node to prefer selection of newer peers, and peers from localized clusters (via prefix bucket), for eviction.

On the side, it also logs last tx transfer and last block transfer for each peer, as well as does a small overhaul on the PrefixBucket struct, (mostly inlining and refactoring).

protocol/flows/src/v5/txrelay/flow.rs Show resolved Hide resolved
components/connectionmanager/src/lib.rs Outdated Show resolved Hide resolved
components/connectionmanager/src/lib.rs Outdated Show resolved Hide resolved
utils/src/networking.rs Show resolved Hide resolved
@D-Stacks D-Stacks changed the base branch from master to dev August 28, 2024 19:42
@michaelsutton michaelsutton deleted the branch kaspanet:master September 11, 2024 18:34
@michaelsutton michaelsutton reopened this Sep 11, 2024
@michaelsutton michaelsutton changed the base branch from dev to master September 11, 2024 18:44
@someone235
Copy link
Contributor

Can you give the reference spec/code that you were inspired from?

assert_eq!(by_lowest_rank(&ranks1, &ranks2), Ordering::Equal);
}

//TODO: Add tests for the compare strategy functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add them?

Comment on lines +141 to +147
pub struct EvictionRanks {
ip_prefix_bucket: f64,
time_connected: f64,
last_ping_duration: f64,
last_block_transfer: f64,
last_tx_transfer: f64,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment for each field?

///
/// **Includes:** [`Self::last_ping_duration`], [`Self::time_connected`], [`Self::last_block_transfer`], [`Self::last_tx_transfer`], and [`Self::ip_prefix_bucket`].
#[inline]
fn all_ranks(&self) -> [f64; 5] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using something like this to avoid forgetting to update this function when adding new fields to the struct

where
Iter: Iterator<Item = (&'a Peer, EvictionRanks)> + 'a,
{
fn filter_peers<F>(self, amount: usize, compare_fn: F) -> impl Iterator<Item = (&'a Peer, EvictionRanks)> + 'a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not always use by_lowest_rank? This will simplify the function and the caller behaviour. The function can than be renamed to skip_peers_with_low_rank or something like this

.skip(amount)
}

fn select_peers_weighted<F>(self, amount: usize, weight_fn: F) -> impl Iterator<Item = (&'a Peer, EvictionRanks)> + 'a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: by_highest_none_latency_rank can be hard coded

@@ -188,6 +189,7 @@ impl HandleRelayInvsFlow {
Err(rule_error) => return Err(rule_error.into()),
};

self.router.set_last_block_transfer(last_block_transfer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also add it to blocks that were received during IBD (but not in the proof stage)

@@ -13,14 +13,16 @@ pub struct PeerProperties {
pub time_offset: i64,
}

#[derive(Debug)]
#[derive(Debug, Eq, PartialEq, Hash)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be the default behaviour for checking equality, but maybe filtered_eviction_set should use PeerId instead of Peer? And then we can remove the Eq, PartialEq, Hash from here

pub struct Peer {
identity: PeerId,
net_address: SocketAddr,
is_outbound: bool,
connection_started: Instant,
properties: Arc<PeerProperties>,
last_ping_duration: u64,
last_block_transfer: Option<Instant>, // TODO: add this to rpc, currently sidelined due to ongoing RPC development
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "currently" part is redundant since it can change. Please only leave // TODO: add this to rpc

@@ -102,6 +102,14 @@ struct RouterMutableState {

/// Duration of the last ping to this peer
last_ping_duration: u64,

/// Time of the last block transfer
/// This corresponds to the last full block transfer, not the last Block Invoice message.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inv stands for inventory and not invoice. Nevertheless, I think it's better to just say "Block Inv"

last_block_transfer: Option<Instant>,

/// Time of the last transaction transfer
/// This corresponds to the last full transaction(s) transfer(ed), not the last Transaction Invoice message.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants