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

Store fallback peers in TransactionFetcher as a PeerId, usize tuple #6559

Closed
wants to merge 8 commits into from
Closed

Store fallback peers in TransactionFetcher as a PeerId, usize tuple #6559

wants to merge 8 commits into from

Conversation

AbhinavMir
Copy link
Contributor

potential fix #6528

@AbhinavMir AbhinavMir marked this pull request as ready for review February 12, 2024 19:22
@mattsse mattsse added the A-networking Related to networking in general label Feb 12, 2024
@AbhinavMir
Copy link
Contributor Author

AbhinavMir commented Feb 12, 2024

@emhane for context: I started by changing fallback_peers: LruCache<PeerId> to fallback_peers: LruCache<(PeerId, usize)> - and used the errors from there to guide me to wherever this was used. I'm sure I missed a few things, so happy to address any feedback!

(Will fix any formatting issues as I see them!)

Copy link
Member

@emhane emhane left a comment

Choose a reason for hiding this comment

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

coming along well

@@ -870,7 +882,7 @@ pub(super) struct TxFetchMetadata {
/// The number of times a request attempt has been made for the hash.
retries: u8,
/// Peers that have announced the hash, but to which a request attempt has not yet been made.
fallback_peers: LruCache<PeerId>,
fallback_peers: LruCache<(PeerId, usize)>,
Copy link
Member

Choose a reason for hiding this comment

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

could you please make a new type

struct TxSizeMetadata {
    peer_id: PeerId
    tx_encoded_len: usize,
}

and then implement Hash and Eq for this, so that only the PeerId is considered. that way if a peer announces the same hash twice with two different sizes, it's only inserted once into the cache and the second time, the first entry is replaced.

Copy link
Contributor Author

@AbhinavMir AbhinavMir Feb 12, 2024

Choose a reason for hiding this comment

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

Makes sense! Would fallback_peer be essentially an array of TxSizeMetadata eg. Vec<TxSizeMetadata>?

Copy link
Member

@emhane emhane Feb 13, 2024

Choose a reason for hiding this comment

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

we want to keep the cache with its nice lru properties that suit our use case here, so a LruCache<TxSizeMetada>.

Copy link
Member

Choose a reason for hiding this comment

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

although we could use an LruMap, and add the PeerId as key and PackedOption<usize> as the value. otherwise, we would need a method TxSizeMetadata::get_size(&self) -> Option<usize> which returns None if the size is zero. as mentioned in the issue, zero is a reserved value here.

Copy link
Contributor Author

@AbhinavMir AbhinavMir Feb 15, 2024

Choose a reason for hiding this comment

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

Hi @emhane , I saw this issue was closed. Should I reopen this? I wasn't working yesterday so didn't have a chance to get back. I think the PR closed automatically b/c of deletion of branch. Just making sure!

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's actually some non-trivial changes I had to work with, so I will implement the changes on main directly!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@emhane Is PackedOption from the Cranelift crate?

Copy link
Member

Choose a reason for hiding this comment

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

yepp that's right! since you implemented get_size now manually, we don't need to use that type. we can just use the TxSizeMetadata type directly in the fallback peers cache, so we revert to a LruCache from LruMap, since we don't need a kv map anymore, just a set. We would have used PackedOption<usize> for the tx_encoded_len otherwise. PackedOption essentially does the same thing: has a reserved value (in our case 0), and stores that in place of the Option variant None. this saves memory, check out https://stackoverflow.com/a/16515488. try running that program in Rust Playground with usize (tx_encoded_len type).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes perfect sense, did some playing around with it. I've made a decent amount of progress with using LruCache. Just wanted to ask: Is peer_id strictly unique? For the fallback_peers.removal() type functions, the remove() method expects value (as defined here), so I can "get" the txSizeMetadata object, and pass it to the remove method, but for that I just wanted to be sure that peer_id is unique, and then find a way to implement get_txSizeMetadata_from_peer_id(). Thx!

Copy link
Member

Choose a reason for hiding this comment

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

peer_id is unique!

@emhane emhane deleted the branch paradigmxyz:main February 13, 2024 19:08
@emhane emhane closed this Feb 13, 2024
@emhane emhane reopened this Feb 15, 2024
@emhane emhane changed the base branch from emhane/speed-up-request-buffered-hashes to main February 15, 2024 11:37
@AbhinavMir AbhinavMir closed this Feb 18, 2024
@AbhinavMir AbhinavMir reopened this Feb 18, 2024
Copy link
Member

@emhane emhane left a comment

Choose a reason for hiding this comment

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

nice progress!

@emhane
Copy link
Member

emhane commented Apr 2, 2024

close to finish line @AbhinavMir !

@AbhinavMir
Copy link
Contributor Author

I'm sorry I had stopped working on this, had a bunch of things happen at the same time! I'll try to finish this up EoD. I'll make those changes! @emhane

@onbjerg
Copy link
Collaborator

onbjerg commented Apr 18, 2024

Hey @AbhinavMir! Anything we can help with to get this over the line? 😊 Let me know!

@AbhinavMir
Copy link
Contributor Author

Hi @onbjerg - I had lost context due to being busy, but wondering if I am back in the right direction? I removed packedOption and updated methods all around. There should be a warning, but if everything else looks good pls lmk!

Copy link
Member

@emhane emhane left a comment

Choose a reason for hiding this comment

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

maybe @onbjerg can better help you out from here, thanks for the effort @AbhinavMir !

Comment on lines 103 to 104
pub(super) fn is_idle(&self, metadata: &TxSizeMetadata) -> bool {
let Some(inflight_count) = self.active_peers.peek(&metadata.peer_id) else { return true };
Copy link
Member

Choose a reason for hiding this comment

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

would prefer if you revert this and extract the peer id reference before call to this function

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! Would this also change how the getter function for this (get_idle_peer_for) would work? I'll correspond with Oliver on this!

Comment on lines 902 to 908
fn get_size(&self) -> Option<usize> {
if self.tx_encoded_len == 0 {
None
} else {
Some(self.tx_encoded_len)
}
}
Copy link
Member

Choose a reason for hiding this comment

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

this is the code that is equivalent to PackedOption. so removing this OR PackedOption, that was the goal. not both. sorry if this was too advanced, hope you learned smthg new :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad! I missed this! I've reverted it. I am a little new to Rust was wasn't the easiest, but lots of fun learning.

Copy link
Member

Choose a reason for hiding this comment

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

ok looks really good now!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you, let me know if I need anything else to have it merged. Unsure what should I do about the warnings generated during build, though.

Copy link
Member

Choose a reason for hiding this comment

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

before a PR is merged, CI should be all green, have you tried fixing merge conflicts?

Copy link
Contributor Author

@AbhinavMir AbhinavMir Apr 21, 2024

Choose a reason for hiding this comment

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

Just fixed the merge conflicts, but it seems like some methods and variables, since newly introduced, are unused. What is best steps for dealing with this?

Comment on lines +360 to +363
entry.fallback_peers_mut().remove(&TxSizeMetadata {
peer_id: *peer_failed_to_serve,
tx_encoded_len: 0,
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

this doesn't seem correct (i see this over the rest of the pr too), will this not only remove it if the entry matches the peer id and tx_encoded_len is 0?

Copy link
Member

Choose a reason for hiding this comment

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

nope, because of PartialEq impl, it only considers the PeerId. at best this would be abstracted away by adding a method to TxFetchMetadata

pub fn remove_fallback_peer(&mut self, peer_id: PeerId) {
    ...
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

i'd prefer we add remove_fallback_peer since we always remove using tx_encoded_len: 0, it reduces confusion


impl Hash for TxSizeMetadata {
fn hash<H: Hasher>(&self, state: &mut H) {
self.peer_id.hash(state);
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think this is unexpected behavior, so not sure i am a fan. it should at least be documented

Copy link
Member

Choose a reason for hiding this comment

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

yes docs on the TxSizeMetadata type would be good, something like 'TxSizeMetadata is unique for PeerId'

Comment on lines +1105 to +1111
fn get_size(&self) -> Option<usize> {
if self.tx_encoded_len == 0 {
None
} else {
Some(self.tx_encoded_len)
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

any reason this doesn't just return usize?

Copy link
Member

Choose a reason for hiding this comment

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

have you read the docs for PackedOption type mentioned in the issue? it's similar to that type

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes, i understand that it is the same as PackedOption, but i do not see why we need an option in the first place. is it because you want 0 to represent that the peer has not told us how big the tx is?

@@ -1072,13 +1081,45 @@ impl Default for TransactionFetcher {
}
}

#[derive(Debug, Clone)]
pub(super) struct TxSizeMetadata {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
pub(super) struct TxSizeMetadata {
pub struct TxSizeMetadata {

this fixes one warning, please address the other warnings about missing documentation. as for the warning about unused function name, please add an underscore at the start of the method name. I will use the methods when this pr is merged.

@@ -1072,13 +1081,45 @@ impl Default for TransactionFetcher {
}
}

#[derive(Debug, Clone)]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Constructor)]

one last thing to address, asides that which @onbjerg says, is to import derive_more::Constructor, then replace all the places in the code where you make an instance of the type. so this

TxSizeMetadat::new(peer_id, 0)

instead of making it like this

TxSizeMetadata {
    peer_id: <value>,
    len: <value>,
}

@emhane
Copy link
Member

emhane commented Apr 22, 2024

btw @AbhinavMir, try the command make lint from the Makefile

@mattsse
Copy link
Collaborator

mattsse commented May 21, 2024

what to do with this @emhane ?

please take over or close

@emhane
Copy link
Member

emhane commented May 21, 2024

what to do with this @emhane ?

please take over or close

ok, I can take over :)

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

Successfully merging this pull request may close these issues.

Store fallback peers in TransactionFetcher as a (PeerId, usize) tuple
4 participants