Skip to content

Report malice on sibling blocks from the same validator#165

Closed
vkomenda wants to merge 7 commits into
aura-posfrom
vk-sibling-blocks
Closed

Report malice on sibling blocks from the same validator#165
vkomenda wants to merge 7 commits into
aura-posfrom
vk-sibling-blocks

Conversation

@vkomenda
Copy link
Copy Markdown

@vkomenda vkomenda commented Jul 4, 2019

Fixes #164

/// modifications.
posdao_transition: Option<BlockNumber>,
/// History of block hashes recently received from peers.
received_block_hashes: RwLock<BTreeMap<(u64, Address), H256>>,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Trying to understand the code base better so I can contribute. Why this added to the ~AuthorityRound only and not AuthorityRoundParams?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Because this is a run time map that is built from blocks received from the peers.

if &new_hash != old_hash {
trace!(target: "engine", "Validator {} produced sibling blocks", header.author());
self.validators.report_malicious(header.author(), set_number, header.number(), Default::default());
Err(EngineError::SiblingBlocks(*header.author()))?;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I actually think we shouldn't return an error.
Because if the sender produced two sibling blocks, it could happen that the second one ends up getting finalized, so we need to make sure we import it. And the block itself isn't invalid, after all.
So I'd just log and report, and then continue.

@vkomenda
Copy link
Copy Markdown
Author

vkomenda commented Jul 4, 2019

cargo test in ethcore shows a deadlock in f93eaa4.

.read()
.iter()
.map(|(k, _)| k)
.filter(|(n, _)| *n < oldest_block_number)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since a BTreeMap's keys are already ordered (and tuples are ordered lexicographically), it shouldn't be necessary to iterate through all of them. You could replace filter with take_while, or use range or split_off. (Not sure what's best.)

.received_block_hashes
.read()
.iter()
.map(|(k, _)| k)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

iter().map(|(k, _)| k) is equivalent to keys().

@vkomenda
Copy link
Copy Markdown
Author

vkomenda commented Jul 5, 2019

There is a problem with upgrading the Weak pointer in 90dfaaf. I'm not removing the WIP status yet.

let received_block_hashes = self.received_block_hashes.read();
received_block_hashes.get(&received_block_key).map(|h| h.clone())
};
if let Some(old_hash) = old_hash {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we don't use old_hash elsewhere, we could just do this in one line:

if self.received_block_hashes.read().get(&received_block_key).any(|h| *h != new_hash) {

@vkomenda vkomenda marked this pull request as ready for review July 9, 2019 13:44
@varasev
Copy link
Copy Markdown
Member

varasev commented Jul 11, 2019

Can we simulate somehow the producing of sibling blocks on the same step? (for testing purposes like we did for testing reportMalicious feature in the afck-sim-malice branch).

Copy link
Copy Markdown
Collaborator

@afck afck 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! 👍
(Just a non-blocking nit-pick.)

.ok_or(EngineError::FailedSystemCall("Failed to upgrade to BlockchainClient.".to_string()))?;

// Remove older block hash records.
let oldest_block_number = full_client.best_block_header().number().saturating_sub(100);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Let's turn 100 into a constant. (SIBLING_DETECTION_PERIOD? MALICE_REPORTING_HORIZON? DUPLICATE_BLOCK_SEARCH_LIMIT? A_BETTER_NAME_I_CANT_THINK_OF_RIGHT_NOW!)

@afck
Copy link
Copy Markdown
Collaborator

afck commented Jul 22, 2019

But let's hold off merging until we've tested it, of course.
Yes, maybe we should update afck-sim-malice to produce sibling blocks.

Copy link
Copy Markdown
Collaborator

@afck afck left a comment

Choose a reason for hiding this comment

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

(Just two more nit-picks, but nothing blocking.)

Err(EngineError::DoubleVote(*header.author()))?;
}
// Report malice if the validator produced other sibling blocks in the same step.
let received_block_key = (header.number(), header.author().clone());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think Address is Copy:

Suggested change
let received_block_key = (header.number(), header.author().clone());
let received_block_key = (header.number(), *header.author());

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks! I rely on clippy too much in such cases, and it's not usable here at all.

.collect();
for k in keys_to_remove {
self.received_block_hashes.write().remove(&k);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could this be simplified using BTreeMap::split_off?

let rbh = self.received_block_hashes.write();
let new_rbh = rbh.split_off((oldest_block_number, Address::zero()));
*rbh = new_rbh;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Sure, thanks!

@varasev
Copy link
Copy Markdown
Member

varasev commented Aug 13, 2019 via email

@vkomenda
Copy link
Copy Markdown
Author

Let's test this before merging

I'm working on this.

Comment thread ethcore/src/engines/authority_round/mod.rs Outdated
@varasev
Copy link
Copy Markdown
Member

varasev commented Sep 12, 2019

Please don't merge this yet. It should be tested manually with posdao-test-setup first

@afck afck force-pushed the vk-sibling-blocks branch from d00d1ac to 89c5848 Compare October 7, 2019 10:18
@afck
Copy link
Copy Markdown
Collaborator

afck commented Oct 7, 2019

I had to rebase this, since aura-pos was rebased on v2.5.9.

@varasev
Copy link
Copy Markdown
Member

varasev commented Oct 18, 2019

@afck I wanted to test this PR with posdao-test-setup but seems it's a bit different from the upstream's merged version https://github.com/paritytech/parity-ethereum/pull/11160/files. Could you please check the changes in #165 and update them according to upstream's? After that, I will test this PR with posdao-test-setup.

@afck
Copy link
Copy Markdown
Collaborator

afck commented Oct 18, 2019

Closing in favor of #196.

@afck afck closed this Oct 18, 2019
@afck afck deleted the vk-sibling-blocks branch October 18, 2019 09:16
@varasev
Copy link
Copy Markdown
Member

varasev commented Oct 18, 2019

Thanks, I will test #196

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Aura doesn't report multiple blocks in one step.

4 participants