-
Notifications
You must be signed in to change notification settings - Fork 53
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
Functional tests for floresta-wire/chain_selector #180
base: master
Are you sure you want to change the base?
Conversation
bd3206e
to
d0055b1
Compare
8c4de42
to
6f8e3da
Compare
@Davidson-Souza I think I am done with chain-selector here. Please review this. |
) | ||
.await; | ||
} | ||
} |
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 add cases where a block is actually invalid?
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.
Please correct if I am going wrong here, When the chain selector node is run, it first achieves the best block headers from all its peers. Then if pow_fraud_proofs is enabled the check_tips
function is executed, and all the peers have to give their best utreexo states, and if they differ then someone is lying.
The only time the whole UtreexoBlock data is used in .update_acc
function where I think we calculate the immediate next utreexo acc on our own codebase.
I couldn't find any code in chain_selector.rs
where the block is actually validated according to the consensus rules.
Maybe the tests for validity of blocks could be done in the running_node
or the sync_node
. I am a little confused 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.
I was thinking, like 3 different testing environments could be made, just like for chain_selector
is done here, for running_node
and sync_node
and covering all their functionalities in their respective test codebases.
So I think each and every function in chain_selector.rs
is tested along, except .is_our_chain_invalid
here :
async fn check_tips(&mut self) -> Result<(), WireError> {
...
...
...
// if we have more than one tip, we need to check if our best chain has an invalid block
tips.remove(0); // no need to check our best one
for tip in tips {
self.is_our_chain_invalid(tip).await?;
}
return Ok(());
}
...
...
Ok(())
}
because I could not figure out how to create different tips in our chain, I need a little help there.
After this, maybe I could move forward with writing tests for the other two remaining nodes ?? @Davidson-Souza your thoughts ?
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 function will check if our current best chain has an invalid block.
I was thinking, like 3 different testing environments could be made, just like for chain_selector is done here, for running_node and sync_node and covering all their functionalities in their respective test codebases.
I agree
because I could not figure out how to create different tips in our chain, I need a little help there.
By having peers following different tips. They need to be forks, no only lag a few blocks. When poke_peers
is called, it'll download the other tips.
|
||
let mut peers = Vec::new(); | ||
|
||
for _ in 0..10 { |
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.
In some cases where the tip is different, could you please make them an actual fork? Like:
1 -> 2 -> 3
\-> 2a
on regtest you can easily create those with invalidateblock
. Just mine a couple of blocks, take the headers and roots. Then you invalidate some in the middle and mine some more
I have a doubt here @Davidson-Souza, in this function we are requesting the utreexo block from peer1 always, but what if peer1 is the liar and peer2 is honest. If the honesty of both the peers is in question how can we rely on only one of them to get the UtreexoBlock and judge who is honest. I am a little confused here -_- async fn find_who_is_lying(
&mut self,
peer1: PeerId,
peer2: PeerId,
) -> Result<Option<PeerId>, WireError> {
...
...
...
let block = self.chain.get_block_hash(fork + 1).unwrap();
self.send_to_peer(peer1, NodeRequest::GetBlock((vec![block], true)))
.await?;
let NodeNotification::FromPeer(_, PeerMessages::Block(block)) =
self.node_rx.recv().await.unwrap()
else {
return Ok(None);
};
let acc1 = self.update_acc(agreed, block, fork + 1)?;
let peer1_acc = Self::parse_acc(peer1_acc)?;
let peer2_acc = Self::parse_acc(peer2_acc)?;
if peer1_acc != acc1 && peer2_acc != acc1 {
return Ok(None);
}
if peer1_acc != acc1 {
return Ok(Some(peer1));
}
Ok(Some(peer2))
} |
@lla-dane the block we ask for is the last one they agree on. Also, if they send an invalid proof, this is make |
Oh, Okay, right, I thought we ask for the block they disagreed on, got a little confused. Thanks !! |
Changes made: floresta-wire/p2p_wire/tests
Simulated a peer to take in requests from the Chain Selector node instance, and then send in the appropriate responses to the node.