-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Conversation
@emhane for context: I started by changing (Will fix any formatting issues as I see them!) |
There was a problem hiding this 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)>, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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>
?
There was a problem hiding this comment.
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>
.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
peer_id
is unique!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice progress!
close to finish line @AbhinavMir ! |
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 |
Hey @AbhinavMir! Anything we can help with to get this over the line? 😊 Let me know! |
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! |
There was a problem hiding this 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 !
pub(super) fn is_idle(&self, metadata: &TxSizeMetadata) -> bool { | ||
let Some(inflight_count) = self.active_peers.peek(&metadata.peer_id) else { return true }; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
fn get_size(&self) -> Option<usize> { | ||
if self.tx_encoded_len == 0 { | ||
None | ||
} else { | ||
Some(self.tx_encoded_len) | ||
} | ||
} |
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
entry.fallback_peers_mut().remove(&TxSizeMetadata { | ||
peer_id: *peer_failed_to_serve, | ||
tx_encoded_len: 0, | ||
}); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) {
...
}
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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'
fn get_size(&self) -> Option<usize> { | ||
if self.tx_encoded_len == 0 { | ||
None | ||
} else { | ||
Some(self.tx_encoded_len) | ||
} | ||
} |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[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>,
}
btw @AbhinavMir, try the command |
what to do with this @emhane ? please take over or close |
ok, I can take over :) |
potential fix #6528