Skip to content

Commit c4b496e

Browse files
authored
babe: report equivocations (#6362)
* slots: create primitives crate for consensus slots * offences: add method to check if an offence is unknown * babe: initial equivocation reporting implementation * babe: organize imports * babe: working equivocation reporting * babe: add slot number to equivocation proof * session: move duplicate traits to session primitives * babe: move equivocation stuff to its own file * offences: fix test * session: don't have primitives depend on frame_support * babe: use opaque type for key owner proof * babe: cleanup client equivocation reporting * babe: cleanup equivocation code in pallet * babe: allow sending signed equivocation reports * node: fix compilation * fix test compilation * babe: return bool on check_equivocation_proof * babe: add test for equivocation reporting * babe: add more tests * babe: add test for validate unsigned * babe: take slot number in generate_key_ownership_proof API * babe: add benchmark for equivocation proof checking * session: add benchmark for membership proof checking * offences: fix babe benchmark * babe: add weights based on benchmark results * babe: adjust weights after benchmarking on reference hardware * babe: reorder checks in check_and_report_equivocation
1 parent 22f6f5f commit c4b496e

File tree

6 files changed

+1312
-119
lines changed

6 files changed

+1312
-119
lines changed

Cargo.toml

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,52 @@ targets = ["x86_64-unknown-linux-gnu"]
1313

1414
[dependencies]
1515
codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] }
16-
serde = { version = "1.0.101", optional = true }
17-
sp-inherents = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/inherents" }
18-
sp-application-crypto = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/application-crypto" }
19-
sp-std = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/std" }
20-
sp-runtime = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/runtime" }
21-
sp-staking = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/staking" }
16+
frame-benchmarking = { version = "2.0.0-rc4", default-features = false, path = "../benchmarking", optional = true }
2217
frame-support = { version = "2.0.0-rc4", default-features = false, path = "../support" }
2318
frame-system = { version = "2.0.0-rc4", default-features = false, path = "../system" }
24-
pallet-timestamp = { version = "2.0.0-rc4", default-features = false, path = "../timestamp" }
25-
sp-timestamp = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/timestamp" }
19+
pallet-authorship = { version = "2.0.0-rc4", default-features = false, path = "../authorship" }
2620
pallet-session = { version = "2.0.0-rc4", default-features = false, path = "../session" }
21+
pallet-timestamp = { version = "2.0.0-rc4", default-features = false, path = "../timestamp" }
22+
serde = { version = "1.0.101", optional = true }
23+
sp-application-crypto = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/application-crypto" }
2724
sp-consensus-babe = { version = "0.8.0-rc4", default-features = false, path = "../../primitives/consensus/babe" }
2825
sp-consensus-vrf = { version = "0.8.0-rc4", default-features = false, path = "../../primitives/consensus/vrf" }
26+
sp-inherents = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/inherents" }
2927
sp-io = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/io" }
28+
sp-runtime = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/runtime" }
29+
sp-session = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/session" }
30+
sp-staking = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/staking" }
31+
sp-std = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/std" }
32+
sp-timestamp = { version = "2.0.0-rc4", default-features = false, path = "../../primitives/timestamp" }
3033

3134
[dev-dependencies]
35+
frame-benchmarking = { version = "2.0.0-rc4", path = "../benchmarking" }
36+
pallet-balances = { version = "2.0.0-rc4", path = "../balances" }
37+
pallet-offences = { version = "2.0.0-rc4", path = "../offences" }
38+
pallet-staking = { version = "2.0.0-rc4", path = "../staking" }
39+
pallet-staking-reward-curve = { version = "2.0.0-rc4", path = "../staking/reward-curve" }
3240
sp-core = { version = "2.0.0-rc4", path = "../../primitives/core" }
3341

3442
[features]
3543
default = ["std"]
3644
std = [
3745
"codec/std",
38-
"serde",
39-
"sp-std/std",
40-
"sp-application-crypto/std",
46+
"frame-benchmarking/std",
4147
"frame-support/std",
42-
"sp-runtime/std",
43-
"sp-staking/std",
4448
"frame-system/std",
49+
"pallet-authorship/std",
50+
"pallet-session/std",
4551
"pallet-timestamp/std",
46-
"sp-timestamp/std",
47-
"sp-inherents/std",
52+
"serde",
53+
"sp-application-crypto/std",
4854
"sp-consensus-babe/std",
4955
"sp-consensus-vrf/std",
50-
"pallet-session/std",
56+
"sp-inherents/std",
5157
"sp-io/std",
58+
"sp-runtime/std",
59+
"sp-session/std",
60+
"sp-staking/std",
61+
"sp-std/std",
62+
"sp-timestamp/std",
5263
]
64+
runtime-benchmarks = ["frame-benchmarking"]

src/benchmarking.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) 2020 Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
//! Benchmarks for the BABE Pallet.
19+
20+
#![cfg_attr(not(feature = "std"), no_std)]
21+
22+
use super::*;
23+
use frame_benchmarking::benchmarks;
24+
25+
type Header = sp_runtime::generic::Header<u64, sp_runtime::traits::BlakeTwo256>;
26+
27+
benchmarks! {
28+
_ { }
29+
30+
check_equivocation_proof {
31+
let x in 0 .. 1;
32+
33+
// NOTE: generated with the test below `test_generate_equivocation_report_blob`.
34+
// the output is not deterministic since keys are generated randomly (and therefore
35+
// signature content changes). it should not affect the benchmark.
36+
// with the current benchmark setup it is not possible to generate this programatically
37+
// from the benchmark setup.
38+
const EQUIVOCATION_PROOF_BLOB: [u8; 416] = [
39+
222, 241, 46, 66, 243, 228, 135, 233, 177, 64, 149, 170, 141, 92, 193, 106, 51, 73, 31,
40+
27, 80, 218, 220, 248, 129, 29, 20, 128, 243, 250, 134, 39, 11, 0, 0, 0, 0, 0, 0, 0,
41+
158, 4, 7, 240, 67, 153, 134, 190, 251, 196, 229, 95, 136, 165, 234, 228, 255, 18, 2,
42+
187, 76, 125, 108, 50, 67, 33, 196, 108, 38, 115, 179, 86, 40, 36, 27, 5, 105, 58, 228,
43+
94, 198, 65, 212, 218, 213, 61, 170, 21, 51, 249, 182, 121, 101, 91, 204, 25, 31, 87,
44+
219, 208, 43, 119, 211, 185, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 66, 65, 66, 69, 52, 2, 0, 0, 0, 0, 11,
46+
0, 0, 0, 0, 0, 0, 0, 5, 66, 65, 66, 69, 1, 1, 188, 192, 217, 91, 138, 78, 217, 80, 8,
47+
29, 140, 55, 242, 210, 170, 184, 73, 98, 135, 212, 236, 209, 115, 52, 200, 79, 175,
48+
172, 242, 161, 199, 47, 236, 93, 101, 95, 43, 34, 141, 16, 247, 220, 33, 59, 31, 197,
49+
27, 7, 196, 62, 12, 238, 236, 124, 136, 191, 29, 36, 22, 238, 242, 202, 57, 139, 0, 0,
50+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51+
0, 40, 23, 175, 153, 83, 6, 33, 65, 123, 51, 80, 223, 126, 186, 226, 225, 240, 105, 28,
52+
169, 9, 54, 11, 138, 46, 194, 201, 250, 48, 242, 125, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0,
53+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 66, 65,
54+
66, 69, 52, 2, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 5, 66, 65, 66, 69, 1, 1, 142, 12,
55+
124, 11, 167, 227, 103, 88, 78, 23, 228, 33, 96, 41, 207, 183, 227, 189, 114, 70, 254,
56+
30, 128, 243, 233, 83, 214, 45, 74, 182, 120, 119, 64, 243, 219, 119, 63, 240, 205,
57+
123, 231, 82, 205, 174, 143, 70, 2, 86, 182, 20, 16, 141, 145, 91, 116, 195, 58, 223,
58+
175, 145, 255, 7, 121, 133
59+
];
60+
61+
let equivocation_proof1: sp_consensus_babe::EquivocationProof<Header> =
62+
Decode::decode(&mut &EQUIVOCATION_PROOF_BLOB[..]).unwrap();
63+
64+
let equivocation_proof2 = equivocation_proof1.clone();
65+
}: {
66+
sp_consensus_babe::check_equivocation_proof::<Header>(equivocation_proof1);
67+
} verify {
68+
assert!(sp_consensus_babe::check_equivocation_proof::<Header>(equivocation_proof2));
69+
}
70+
}
71+
72+
#[cfg(test)]
73+
mod tests {
74+
use super::*;
75+
use crate::mock::*;
76+
use frame_support::assert_ok;
77+
78+
#[test]
79+
fn test_benchmarks() {
80+
new_test_ext(3).execute_with(|| {
81+
assert_ok!(test_benchmark_check_equivocation_proof::<Test>());
82+
})
83+
}
84+
85+
#[test]
86+
fn test_generate_equivocation_report_blob() {
87+
let (pairs, mut ext) = new_test_ext_with_pairs(3);
88+
89+
let offending_authority_index = 0;
90+
let offending_authority_pair = &pairs[0];
91+
92+
ext.execute_with(|| {
93+
start_era(1);
94+
95+
let equivocation_proof = generate_equivocation_proof(
96+
offending_authority_index,
97+
offending_authority_pair,
98+
CurrentSlot::get() + 1,
99+
);
100+
101+
println!("equivocation_proof: {:?}", equivocation_proof);
102+
println!(
103+
"equivocation_proof.encode(): {:?}",
104+
equivocation_proof.encode()
105+
);
106+
});
107+
}
108+
}

0 commit comments

Comments
 (0)