-
Notifications
You must be signed in to change notification settings - Fork 66
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
Implement Topics #126
Implement Topics #126
Conversation
93cca33
to
7676752
Compare
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 might be getting close to the finish line, some comments for today
/// KBuckets per topic hash. | ||
topics_kbuckets: HashMap<TopicHash, KBucketsTable<NodeId, Enr>>, | ||
|
||
/// The peers returned in a NODES response to a TOPICQUERY or REGTOPIC request are inserted in |
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.
/// The peers returned in a NODES response to a TOPICQUERY or REGTOPIC request are inserted in | |
/// The peers received in a NODES response to a TOPICQUERY or REGTOPIC request are inserted in |
@@ -21,6 +21,7 @@ zeroize = { version = "1.4.3", features = ["zeroize_derive"] } | |||
futures = "0.3.19" | |||
uint = { version = "0.9.1", default-features = false } | |||
rlp = "0.5.1" | |||
sha2 = "0.9.5" |
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 dep can be accessed directly from the enr crate, as is re-exported and having it here causes problems trying to upgrade
@@ -43,15 +45,36 @@ lazy_static! { | |||
RwLock::new(crate::PermitBanList::default()); | |||
} | |||
|
|||
/// Helper function that returns the hash of the given topic string according to the | |||
/// implemented hashing algorithm. | |||
pub static HASH: for<'a> fn(topic: &'a str) -> TopicHash = |topic| { |
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 part is not necessary
pub static HASH: for<'a> fn(topic: &'a str) -> TopicHash = |topic| { | |
pub static HASH: fn(topic: &str) -> TopicHash = |topic| { |
config.incoming_bucket_limit, | ||
table_filter, | ||
bucket_filter, | ||
))); | ||
|
||
println!("{:?}", local_enr.read().get(ENR_KEY_FEATURES).unwrap()); |
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.
tracing::info
is probably better here with a nice message
// the service will verify if this node is contactable, we just send it and | ||
// await a response. |
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.
copy paste error?
let mut topic_item = topics_to_reg_iter.next(); | ||
while let Some((topic, _topic_hash)) = topic_item { | ||
trace!("Publishing topic {} with hash {}", topic, topic.hash()); | ||
topic_item = topics_to_reg_iter.next(); |
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 couldn't find a particular reason to do this using an extra variable. This might be a more idiomatic way of doing the same
let mut topic_item = topics_to_reg_iter.next(); | |
while let Some((topic, _topic_hash)) = topic_item { | |
trace!("Publishing topic {} with hash {}", topic, topic.hash()); | |
topic_item = topics_to_reg_iter.next(); | |
while let Some((topic, _topic_hash)) = topics_to_reg_iter.next() { | |
trace!("Publishing topic {} with hash {}", topic, topic.hash()); |
if sent_regtopics >= MAX_REGTOPICS_REGISTER_PER_INTERVAL { | ||
break | ||
} |
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 part might a bit problematic since what an user would expect is any topic they want to register should be kept alive, I think this could this promise. What do you think?
if topics_to_reg_iter.next().is_none() { | ||
topics_to_reg_iter = self.registration_attempts.keys().map(|topic| (topic.clone(), topic.hash())).collect::<Vec<(Topic, TopicHash)>>().into_iter(); | ||
} |
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.
So checking this I assume the only reason to do this, having a mutable iterator that needs to be stopped in a poll iteration is the MAX_REGTOPICS_REGISTER_PER_INTERVAL
. Do you remember why we have this?
} | ||
} | ||
|
||
fn get_active_topics(&mut self) -> HashMap<Topic, Vec<NodeId>> { |
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.
do you think this kind of maintenance could be done on an interval for example? in order to remove the mutability of a GET service function. We could still do this maintenance step when the call is done but at least it wouldn't be the only moment in which is done
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 should also move the maintenance code to it's own function (it's most of the code, yes) but it's repeated at least once more in the send_register_topics
logic
let encoded_topics_field = topics_field(topic.clone()).encode(); | ||
|
||
let enr_size = self.local_enr.read().size() + encoded_topics_field.len(); | ||
if enr_size >= 300 { |
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 be nicer as a constant
Protocol outdated, closing. |
this will take a bit longer after all |
How new connections are injected into topics kbuckets and the local routing table, will probably have to be revised and optimised to avoid having to update the same connection in different kbuckets and to avoid cloning enrs.
A lot of code has been reused purposely to show which parts of the discv5 pre-topics logic tie into the discv5 topics logic. A topic is a 32 byte hash that can be converted into the key of a kbucket entry, just as a node id can. An ADNODES (topics discv5) response body is identical to a NODES (old discv5) response body.