compact/compact.rs
1// This file is part of Substrate.
2
3// Copyright (C) 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
18use frame_election_provider_solution_type::generate_solution_type;
19use honggfuzz::fuzz;
20use sp_arithmetic::Percent;
21use sp_runtime::codec::{Encode, Error};
22
23fn main() {
24 generate_solution_type!(
25 #[compact] pub struct InnerTestSolutionCompact::<
26 VoterIndex = u32,
27 TargetIndex = u32,
28 Accuracy = Percent,
29 MaxVoters = frame_support::traits::ConstU32::<100_000>,
30 >(16));
31 loop {
32 fuzz!(|fuzzer_data: &[u8]| {
33 let result_decoded: Result<InnerTestSolutionCompact, Error> =
34 <InnerTestSolutionCompact as codec::Decode>::decode(&mut &*fuzzer_data);
35 // Ignore errors as not every random sequence of bytes can be decoded as
36 // InnerTestSolutionCompact
37 if let Ok(decoded) = result_decoded {
38 // Decoding works, let's re-encode it and compare results.
39 let reencoded: std::vec::Vec<u8> = decoded.encode();
40 // The reencoded value may or may not be equal to the original fuzzer output.
41 // However, the original decoder should be optimal (in the sense that there is no
42 // shorter encoding of the same object). So let's see if the fuzzer can find
43 // something shorter:
44 if fuzzer_data.len() < reencoded.len() {
45 panic!("fuzzer_data.len() < reencoded.len()");
46 }
47 // The reencoded value should definitely be decodable (if unwrap() fails that is a
48 // valid panic/finding for the fuzzer):
49 let decoded2: InnerTestSolutionCompact =
50 <InnerTestSolutionCompact as codec::Decode>::decode(&mut reencoded.as_slice())
51 .unwrap();
52 // And it should be equal to the original decoded object (resulting from directly
53 // decoding fuzzer_data):
54 assert_eq!(decoded, decoded2);
55 }
56 });
57 }
58}