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

Add Networking and Republishing logic to MsgPool #732

Merged
merged 37 commits into from
Nov 12, 2020
Merged

Add Networking and Republishing logic to MsgPool #732

merged 37 commits into from
Nov 12, 2020

Conversation

ec2
Copy link
Member

@ec2 ec2 commented Oct 7, 2020

Summary of changes
Changes introduced in this pull request:

  • Adds networking to the message pool to broadcast messages over GossipSub
  • Adds logic for republishing of messages over GossipSub

The MsgChainNode and MsgChain structs indeed look kinda of funny. I feel like it can definitely be improved on, but the idea is to mimic a doubly linked list in a way that is close enough for our purposes. There are definitely a few things that seem kinda sketchy. Please reach out to me if the logic is super hard to follow.
Those unwraps on .curr() will definitely raise some eyebrows, but they are safe insofar that you create MsgChain through the constructor. I figured this might not matter, since this is an internal datastructure. If you have a better way of doing around this, please let me know 😄

Reference issue to close (if applicable)

Closes
#708

Other information and links

Copy link
Contributor

@austinabell austinabell left a comment

Choose a reason for hiding this comment

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

Have you considered using some actual linked list implementation such as the rust one? Seems very inefficient to use the vector and with all the unwraps and unsafe indexing scares me.

I'll go through more in depth later too because it's hard for me to wrap my head around all the mutex usage here

blockchain/message_pool/src/msgpool.rs Outdated Show resolved Hide resolved
blockchain/message_pool/src/msgpool.rs Outdated Show resolved Hide resolved
Comment on lines 1130 to 1147
if tail[0].curr().unwrap().gas_perf >= head.last().unwrap().curr().unwrap().gas_perf {
let mut chain_a_msgs = tail[0].curr().unwrap().msgs.clone();
head.last_mut()
.unwrap()
.curr_mut()
.unwrap()
.msgs
.append(&mut chain_a_msgs);
head.last_mut().unwrap().curr_mut().unwrap().gas_reward +=
&tail[0].curr().unwrap().gas_reward;
head.last_mut().unwrap().curr_mut().unwrap().gas_limit +=
head.last().unwrap().curr().unwrap().gas_limit;
head.last_mut().unwrap().curr_mut().unwrap().gas_perf = get_gas_perf(
&head.last().unwrap().curr().unwrap().gas_reward,
head.last().unwrap().curr().unwrap().gas_limit,
);
tail[0].curr_mut().unwrap().valid = false;
merged += 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

ouuf

blockchain/message_pool/src/msgpool.rs Show resolved Hide resolved
}
pub fn get_gas_perf(gas_reward: &BigInt, gas_limit: i64) -> f64 {
let a = gas_reward * types::BLOCK_GAS_LIMIT;
a.to_f64().unwrap() / gas_limit as f64
Copy link
Contributor

Choose a reason for hiding this comment

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

this isn't safe? Why is it assumed that f64 can accommodate the value?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah but the unwrap is based on how many significant figures as well, It's not clear all of the use cases of this function so it seems like it opens a vulnerability that can be triggered? Or is there something I'm missing here?

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, so i did some research. Im using the num-rational crate now here. It has the ability to convert a ratio of integers to a f64. I unwrap because it seems the only case where it returns None is when the denominator is 0. This should never be the case because the gas_limit is guaranteed to have a non-zero value.

blockchain/message_pool/src/msgpool.rs Show resolved Hide resolved
blockchain/state_manager/Cargo.toml Outdated Show resolved Hide resolved
&tail[0].curr().unwrap().gas_reward;
head.last_mut().unwrap().curr_mut().unwrap().gas_limit +=
head.last().unwrap().curr().unwrap().gas_limit;
head.last_mut().unwrap().curr_mut().unwrap().gas_perf = get_gas_perf(
Copy link
Contributor

Choose a reason for hiding this comment

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

Since you are unwrapping the same stuff for each iteration, you can just unwrap once and make all the changes to that variable, and it doesn't look as scary lol. Something like this might work :

let mut head_last_curr = head.last_mut().unwrap().curr_mut().unwrap();
head_last_curr.msgs.append(&mut chain_a_msgs);

Copy link
Contributor

@RajarupanSampanthan RajarupanSampanthan left a comment

Choose a reason for hiding this comment

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

Looks good except for those small changes

}
}
*cur_tipset.write().await = Arc::new(ts);
}
if repub {
repub_trigger.send(()).await;
Copy link
Contributor

Choose a reason for hiding this comment

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

should this not check if the channel is full before sending? The only issue I have with this is that it's a channel of undefined length and if you send multiple republish signals, would it not do duplicate unnecessary work? Wouldn't you just want it to behave like an atomic bool and some waking mechanism, where the other thread is just notified when there was an event, perform the work, then go back to sleep?

Copy link
Member Author

Choose a reason for hiding this comment

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

Only place that a repub_trigger.send() happens is in head_change, so there shouldnt be duplicate work. This is because the republish function will return early if theres nothing pending. In head_change the pending messages map will be updated to delete messages that dont need to be propitigated.

@ec2 ec2 merged commit ee25ba9 into main Nov 12, 2020
@ec2 ec2 deleted the ec2/republish branch November 12, 2020 05:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants