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

Submit equivocation reports#2800

Closed
marcio-diaz wants to merge 75 commits intomasterfrom
mar-report-equivocation-grandpa
Closed

Submit equivocation reports#2800
marcio-diaz wants to merge 75 commits intomasterfrom
mar-report-equivocation-grandpa

Conversation

@marcio-diaz
Copy link
Contributor

No description provided.

delay: Mutex<Option<std::sync::mpsc::Receiver<()>>>,
}

impl txpool::ChainApi for TestPoolApi {
Copy link
Contributor

Choose a reason for hiding this comment

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

(e.g. if we didn't tightly couple to PoolApi we could have a much more useful Report hook for tests).

equiv_proof.first_header().hash(),
equiv_proof.second_header().hash(),
);
// transaction_pool.as_ref().map(|txpool|
Copy link
Contributor

Choose a reason for hiding this comment

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

commented-out code?

/// Submit report call to the transaction pool.
pub fn submit_report_call<C, T, Block>(
client: &Arc<C>,
transaction_pool: &Arc<T>,
Copy link
Contributor

Choose a reason for hiding this comment

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

These seem like they could both be &X instead of &Arc<X>. Why leak Arc into it?

) {
warn!(target: "afg", "Detected prevote equivocation in the finality worker: {:?}", equivocation);
// nothing yet; this could craft misbehavior reports of some kind.
let proof = (self.set_id, round, equivocation).encode();
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nice to have this be a struct in finality-grandpa-primitives.

submit_report_call(
&self.inner,
&self.transaction_pool,
Call::Grandpa(GrandpaCall::report_precommit_equivocation(equivocation.encode())),
Copy link
Contributor

Choose a reason for hiding this comment

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

prevote equivocations take the (set_id, round) as well. That seems right to me -- any reason it's only equivocation here?

serde = { version = "1.0", optional = true }
serde = { version = "1.0", optional = true, features = ["derive"] }

# substrate-primitives = { package = "substrate-primitives", path = "../../core/primitives" }
Copy link
Contributor

Choose a reason for hiding this comment

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

commented-out?


let proof_is_valid = fst_author.map_or(false, |f| snd_author.map_or(false, |s| f == s));

if proof_is_valid {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if proof_is_valid {
if proof_is_valid {

None
}

fn handle_equivocation_proof<T>(proof: &Vec<u8>) -> TransactionValidity
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fn handle_equivocation_proof<T>(proof: &Vec<u8>) -> TransactionValidity
fn handle_equivocation_proof<T>(proof: &[u8]) -> TransactionValidity

pub struct Module<T: Trait> for enum Call where origin: T::Origin { }
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
/// Report equivocation in block production.
fn report_equivocation(_origin, _equivocation_proof: Vec<u8>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't the equivocation_proof be strongly typed as AuraEquivocationProof?

Do I understand right that this is invoked as a no-op after ValidateUnsigned checks the call and this is the place where slashing::slash would be invoked?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, exactly.


type Signature: Verify + Codec + Clone;
// type DigestItem: CompatibleDigestItem<Self::Signature>
// + DigestItem<Hash = Self::Hash>;
Copy link
Contributor

Choose a reason for hiding this comment

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

more commented-out code

// FIXME: https://github.com/paritytech/substrate/issues/1112
}
/// Report Prevote equivocation in Grandpa.
fn report_prevote_equivocation(_origin, _equivocation_proof: Vec<u8>) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

likewise here: I'm surprised we can't strongly-type the call.

/// Report some misbehavior.
fn report_misbehavior(origin, _report: Vec<u8>) {
ensure_signed(origin)?;
// FIXME: https://github.com/paritytech/substrate/issues/1112
Copy link
Contributor

Choose a reason for hiding this comment

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

is this issue fixed?

Copy link
Contributor Author

@marcio-diaz marcio-diaz Jun 12, 2019

Choose a reason for hiding this comment

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

It's going to be handled here (grandpa equivocations), I'll link it.

Copy link
Contributor

@rphmeier rphmeier left a comment

Choose a reason for hiding this comment

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

Generally looks decent. A bunch of style issues, some questions, and some architecture issues that need to be addressed.
Most importantly, the SubmitReport trait instead of tightly coupling to the transaction pool would be nice -- unless there is a strong justification for it.

Blocking on:

  • Test that equivocations really do lead to reports in GRANDPA
  • Test that equivocations really do lead to reports in Aura
  • Test that equivocation reports are evaluated correctly on the runtime side.

@rphmeier rphmeier added A5-grumble and removed A0-please_review Pull request needs code review. labels Jun 11, 2019

use client;
use transaction_pool::txpool::{self, PoolApi};
use node_runtime::{UncheckedExtrinsic, Call};
Copy link
Contributor

@rphmeier rphmeier Jun 12, 2019

Choose a reason for hiding this comment

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

I didn't catch this in the first review, but coupling this to the node-runtime is wrong. We'll need general utilities for constructing calls.

Nothing in core should depend on anything in node.

fn slot_duration() -> u64;

/// Construct a call to report the equivocation.
fn construct_equiv_report_call(proof: AuraEquivProof<<Block as BlockT>::Header, Signature>) -> Vec<u8>;
Copy link
Contributor

Choose a reason for hiding this comment

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

style: no compact names. prefer construct_equivocation_report_call and AuraEquivocationProof

Copy link
Contributor Author

@marcio-diaz marcio-diaz Jun 15, 2019

Choose a reason for hiding this comment

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

I wonder if these constructor functions should/can be automatically generated using some kind of annotation in the target function.

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be cool to auto-generate them. I'm not sure what you mean by the target though

Copy link
Contributor Author

@marcio-diaz marcio-diaz Jun 20, 2019

Choose a reason for hiding this comment

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

The idea was to decorate the function using something like #[create_constructor]:

decl_module! {
	pub struct Module<T: Trait> for enum Call where origin: T::Origin { 
		#[create_constructor]
                fn report_equivocation(...) {
		}
	}
}

to avoid polluting the API declaration. That should implicitly implement the following runtime API call:

fn construct_report_equivocation_call(...) -> Vec<u8> {
    let report_call = Call::Aura(AuraCall::report_equivocation(proof));
    let extrinsic = UncheckedExtrinsic::new_unsigned(report_call);
    extrinsic.encode()
}

But now I don't like so much the idea of creating implicit API functions. (By implicit I mean that doesn't appear under decl_runtime_apis!)

Maybe @bkchr has an opinion on this.

Copy link
Member

Choose a reason for hiding this comment

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

I would really like to have implicit API functions, but this does not work. You can not export a function that involves some generics.

@bkchr bkchr deleted the mar-report-equivocation-grandpa branch June 21, 2019 12:30
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants