Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Init store for slots-headers #2492

Merged
merged 24 commits into from
May 15, 2019
Merged

Conversation

marcio-diaz
Copy link
Contributor

@marcio-diaz marcio-diaz commented May 6, 2019

Starting PR for issue paritytech/polkadot-sdk#70.

  • Introduces a map in the Aux Storage: slot -> vec![(header, signer)].
  • It contains the last MAX_SLOT_CAPACITY slots.
  • It's pruned when reaching PRUNING_BOUND % slot_now == 0, with PRUNING_BOUND > MAX_SLOT_CAPACITY. Note: I don't know if the pruning may be too slow.
  • The size of the vector is O(validators) in the worst scenario, since we save only one header by signer, i.e. duplicates are ignored and different headers generate equivocations.
  • When checking headers we use the map for checking for equivocations and throw an error if it's the case. Follow up PR will produce a report.

@marcio-diaz marcio-diaz marked this pull request as ready for review May 7, 2019 17:26
@marcio-diaz marcio-diaz requested review from rphmeier and andresilva May 7, 2019 17:27
@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 1ccf396 to 93b70bf Compare May 7, 2019 17:30
@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 93b70bf to c0dfff5 Compare May 7, 2019 17:38
@marcio-diaz marcio-diaz added the A0-please_review Pull request needs code review. label May 8, 2019
@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 997bb08 to 0a03d71 Compare May 8, 2019 08:48
@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 0a03d71 to 01a38e3 Compare May 8, 2019 08:55
}

/// Check if the header is an equivocation and returns the proof in that case.
/// Assumes all the headers in the same slot are signed by the same Signer.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we can make this assumption for BABE (remember that uncles are allowed). I'm also not sure it holds for Aura in the presence of forks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I'm checking the public key now, it's executed after verification.

slot_header_map = slot_header_map.split_off(&(slot - MAX_SLOT_CAPACITY));
}

backend.insert_aux(
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we can come up with a simple way to avoid dumping everything to disk. If we store the different elements under different keys (e.g. SLOT_HEADER_MAP_KEY + index), then we'd only need to delete one key and add a new one as we import new blocks. Not sure this is strictly needed for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed by adding SLOT_HEADER_MAP_KEY + index as keys.

Ok(CheckedHeader::Checked(header, digest_item))
match check_equivocation(client, slot_num, header.clone()) {
Ok(Some(equivocation_proof)) => {
// TODO: dispatch report here.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to add a reporting module as part of this PR?

Copy link
Contributor

@rphmeier rphmeier May 8, 2019

Choose a reason for hiding this comment

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

A runtime module? I think we'll hold that off for another PR. srml-aura should get a function for checking equivocation, given two headers.

@rphmeier rphmeier requested a review from Demi-Marie May 8, 2019 18:57
Copy link
Contributor

@Demi-Marie Demi-Marie left a comment

Choose a reason for hiding this comment

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

Commented-out code needs to be either removed or finished, and a potential denial of service attack from many equivocations needs to be addressed.

match check_equivocation::<_, _, <P as Pair>::Public>(client, slot_num, header.clone(), public.clone()) {
Ok(Some(equivocation_proof)) => {
// TODO: dispatch report here.
Err(format!("Slot author is equivocating with headers {:?} and {:?}",
Copy link
Contributor

Choose a reason for hiding this comment

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

We should log this with severity at least warn, as it should not happen normally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added it as info.

let mut v = load_decode::<_, Vec<(H, P)>>(backend.clone(), &key[..])?
.unwrap_or_else(Vec::new);

for (prev_header, prev_signer) in v.iter() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is O(n), and is called O(n) times, so it is O(n^2) (where n is the number of messages from any particular validator).

Copy link
Contributor Author

@marcio-diaz marcio-diaz May 9, 2019

Choose a reason for hiding this comment

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

I think is O(validators) now, worst case scenario, since we store only one message by validated signer.

}
}

// match slot_header_map.entry(slot) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The commented-out code should either be removed or uncommented.

// };

if slot % PRUNING_BOUND == 0 {
// slot_header_map = slot_header_map.split_off(&(slot - MAX_SLOT_CAPACITY));
Copy link
Contributor

Choose a reason for hiding this comment

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

Same

@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch 2 times, most recently from 097392b to 502d47e Compare May 9, 2019 11:48
@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 502d47e to 5ee6d79 Compare May 9, 2019 12:02
@marcio-diaz
Copy link
Contributor Author

I addressed the previous issues and it's ready for another round of review.

@marcio-diaz marcio-diaz dismissed stale reviews from Demi-Marie and andresilva May 9, 2019 18:47

fixed

@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 21c00a9 to eb6d098 Compare May 13, 2019 08:08
Copy link

@DemiMarie-temp DemiMarie-temp left a comment

Choose a reason for hiding this comment

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

The algorithm for finding equivocations is rather subtle. Would adding some comments be a good idea?

public.clone()
) {
Ok(Some(equivocation_proof)) => {
info!(

Choose a reason for hiding this comment

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

Can the code duplication between this and the following statement be removed?

Ok(CheckedHeader::Checked(header, digest_item))
},
Err(e) => {
println!("{}", e.to_string());

Choose a reason for hiding this comment

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

This should be logged as error!, not written to stdout.

snd_header: header.clone(),
}));
} else {
return Ok(None)

Choose a reason for hiding this comment

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

This appears to be correct, since at least the first equivocation will be reported. That said, I suspect a comment explaining why would be justified.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added some comments, hope it helps.

@gavofyork
Copy link
Member

@demimarie-parity happy with this now?

@@ -1103,4 +1163,40 @@ mod tests {
Keyring::Charlie.into()
]);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

stray newline


pub use aura_primitives::*;
pub use consensus_common::{SyncOracle, ExtraVerification};


Copy link
Contributor

Choose a reason for hiding this comment

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

stray newline

}
}

#[derive(Debug, Clone)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing docs on public item

}

impl<H> EquivocationProof<H> {
pub fn slot(&self) -> u64 {
Copy link
Contributor

Choose a reason for hiding this comment

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

docs

where
H: Header,
C: AuxStore,
P: Encode + Decode + PartialEq + std::fmt::Debug,
Copy link
Contributor

Choose a reason for hiding this comment

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

Debug bound seems unnecessary.

@@ -290,7 +290,7 @@ impl<T: AsMut<[u8]> + AsRef<[u8]> + Default + Derive> Ss58Codec for T {
#[cfg(feature = "std")]
pub trait Pair: Sized + 'static {
/// TThe type which is used to encode a public key.
type Public;
type Public: Clone + std::fmt::Debug;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think these are necessary.

@marcio-diaz marcio-diaz force-pushed the marcio/equivocation-block-production branch from 8da401f to a821f9e Compare May 14, 2019 13:27
@gavofyork gavofyork requested a review from andresilva May 14, 2019 15:51
Copy link
Contributor

@andresilva andresilva left a comment

Choose a reason for hiding this comment

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

underflow

core/consensus/slots/src/aux_schema.rs Outdated Show resolved Hide resolved
core/consensus/slots/src/aux_schema.rs Outdated Show resolved Hide resolved
seerscode and others added 2 commits May 14, 2019 18:38
Co-Authored-By: André Silva <andre.beat@gmail.com>
Co-Authored-By: André Silva <andre.beat@gmail.com>
@marcio-diaz marcio-diaz merged commit 541e9c8 into master May 15, 2019
@marcio-diaz marcio-diaz deleted the marcio/equivocation-block-production branch May 15, 2019 10:22
MTDK1 pushed a commit to bdevux/substrate that referenced this pull request Jul 10, 2019
* init store for slots

* fix: add check_equivocation to Aura/Babe

* fix tests

* fix: add pruning bound

Co-Authored-By: André Silva <andre.beat@gmail.com>

* use saturating_sub
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants