Skip to content

Commit 90d83ea

Browse files
A0-1541: Unit tests for pallet snarcos (#722)
1 parent de0e521 commit 90d83ea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+236
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pallets/snarcos/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ sp-std = { default-features = false, git = "https://github.com/Cardinal-Cryptogr
3636

3737
primitives = { path = "../../primitives", default-features = false }
3838

39+
[dev-dependencies]
40+
sp-runtime = { default-features = false, git = "https://github.com/Cardinal-Cryptography/substrate.git", branch = "liminal" }
41+
3942
[features]
4043
default = ["std"]
4144
std = [
@@ -61,6 +64,7 @@ std = [
6164
"sp-core/std",
6265
"sp-io/std",
6366
"sp-std/std",
67+
"sp-runtime/std",
6468

6569
"primitives/std",
6670
]

pallets/snarcos/src/benchmarking/import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ macro_rules! get_artifacts {
3838
macro_rules! get_artifact {
3939
($system:tt, $relation:tt, $artifact:tt $(,)?) => {
4040
include_bytes!(concat!(
41-
"resources/",
41+
"../resources/",
4242
$crate::system!($system),
4343
"/",
4444
$crate::relation!($relation),

pallets/snarcos/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22

33
#[cfg(feature = "runtime-benchmarks")]
44
mod benchmarking;
5+
mod systems;
6+
#[cfg(test)]
7+
mod tests;
58
mod weights;
9+
610
use frame_support::pallet_prelude::StorageVersion;
711
pub use pallet::*;
12+
pub use systems::ProvingSystem;
813
pub use weights::{AlephWeight, WeightInfo};
914

1015
/// The current storage version.
@@ -13,9 +18,6 @@ const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);
1318
/// We store verification keys under short identifiers.
1419
pub type VerificationKeyIdentifier = [u8; 4];
1520

16-
mod systems;
17-
pub use systems::ProvingSystem;
18-
1921
#[frame_support::pallet]
2022
pub mod pallet {
2123
use ark_serialize::CanonicalDeserialize;

pallets/snarcos/src/tests/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mod setup;
2+
mod suite;

pallets/snarcos/src/tests/setup.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use frame_support::{
2+
construct_runtime,
3+
pallet_prelude::ConstU32,
4+
sp_runtime,
5+
sp_runtime::{
6+
testing::{Header, H256},
7+
traits::IdentityLookup,
8+
},
9+
traits::Everything,
10+
};
11+
use frame_system::mocking::{MockBlock, MockUncheckedExtrinsic};
12+
use sp_io::TestExternalities;
13+
use sp_runtime::traits::BlakeTwo256;
14+
15+
use crate as pallet_snarcos;
16+
17+
construct_runtime!(
18+
pub enum TestRuntime where
19+
Block = MockBlock<TestRuntime>,
20+
NodeBlock = MockBlock<TestRuntime>,
21+
UncheckedExtrinsic = MockUncheckedExtrinsic<TestRuntime>,
22+
{
23+
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
24+
Snarcos: pallet_snarcos::{Pallet, Call, Storage, Event<T>},
25+
}
26+
);
27+
28+
impl frame_system::Config for TestRuntime {
29+
type BaseCallFilter = Everything;
30+
type BlockWeights = ();
31+
type BlockLength = ();
32+
type Origin = Origin;
33+
type Call = Call;
34+
type Index = u64;
35+
type BlockNumber = u64;
36+
type Hash = H256;
37+
type Hashing = BlakeTwo256;
38+
type AccountId = u128;
39+
type Lookup = IdentityLookup<Self::AccountId>;
40+
type Header = Header;
41+
type Event = Event;
42+
type BlockHashCount = ();
43+
type DbWeight = ();
44+
type Version = ();
45+
type PalletInfo = PalletInfo;
46+
type AccountData = ();
47+
type OnNewAccount = ();
48+
type OnKilledAccount = ();
49+
type SystemWeightInfo = ();
50+
type SS58Prefix = ();
51+
type OnSetCode = ();
52+
type MaxConsumers = ConstU32<16>;
53+
}
54+
55+
impl pallet_snarcos::Config for TestRuntime {
56+
type Event = Event;
57+
type WeightInfo = ();
58+
type MaximumVerificationKeyLength = ConstU32<10_000>;
59+
}
60+
61+
pub(super) fn new_test_ext() -> TestExternalities {
62+
let t = frame_system::GenesisConfig::default()
63+
.build_storage::<TestRuntime>()
64+
.unwrap();
65+
66+
TestExternalities::new(t)
67+
}

pallets/snarcos/src/tests/suite.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
use frame_support::{assert_err, assert_ok, sp_runtime, BoundedVec};
2+
use frame_system::{pallet_prelude::OriginFor, Config};
3+
use sp_runtime::traits::Get;
4+
5+
use super::setup::*;
6+
use crate::{Error, ProvingSystem, VerificationKeyIdentifier, VerificationKeys};
7+
8+
type Snarcos = crate::Pallet<TestRuntime>;
9+
10+
const IDENTIFIER: VerificationKeyIdentifier = [0; 4];
11+
const SYSTEM: ProvingSystem = ProvingSystem::Groth16;
12+
13+
fn vk() -> Vec<u8> {
14+
include_bytes!("../resources/groth16/xor.vk.bytes").to_vec()
15+
}
16+
17+
fn proof() -> Vec<u8> {
18+
include_bytes!("../resources/groth16/xor.proof.bytes").to_vec()
19+
}
20+
21+
fn input() -> Vec<u8> {
22+
include_bytes!("../resources/groth16/xor.public_input.bytes").to_vec()
23+
}
24+
25+
fn caller() -> OriginFor<TestRuntime> {
26+
<TestRuntime as Config>::Origin::signed(0)
27+
}
28+
29+
fn put_key() {
30+
VerificationKeys::<TestRuntime>::insert(IDENTIFIER, BoundedVec::try_from(vk()).unwrap());
31+
}
32+
33+
#[test]
34+
fn stores_vk_with_fresh_identifier() {
35+
new_test_ext().execute_with(|| {
36+
assert_ok!(Snarcos::store_key(caller(), IDENTIFIER, vk()));
37+
38+
let stored_key = VerificationKeys::<TestRuntime>::get(IDENTIFIER);
39+
assert!(stored_key.is_some());
40+
assert_eq!(stored_key.unwrap().to_vec(), vk());
41+
});
42+
}
43+
44+
#[test]
45+
fn does_not_overwrite_registered_key() {
46+
new_test_ext().execute_with(|| {
47+
put_key();
48+
49+
assert_err!(
50+
Snarcos::store_key(caller(), IDENTIFIER, vk()),
51+
Error::<TestRuntime>::IdentifierAlreadyInUse
52+
);
53+
});
54+
}
55+
56+
#[test]
57+
fn does_not_store_too_long_key() {
58+
new_test_ext().execute_with(|| {
59+
let limit: u32 = <TestRuntime as crate::Config>::MaximumVerificationKeyLength::get();
60+
61+
assert_err!(
62+
Snarcos::store_key(caller(), IDENTIFIER, vec![0; (limit + 1) as usize]),
63+
Error::<TestRuntime>::VerificationKeyTooLong
64+
);
65+
});
66+
}
67+
68+
#[test]
69+
fn verifies_proof() {
70+
new_test_ext().execute_with(|| {
71+
put_key();
72+
73+
assert_ok!(Snarcos::verify(
74+
caller(),
75+
IDENTIFIER,
76+
proof(),
77+
input(),
78+
SYSTEM
79+
));
80+
});
81+
}
82+
83+
#[test]
84+
fn verify_shouts_when_no_key_was_registered() {
85+
new_test_ext().execute_with(|| {
86+
assert_err!(
87+
Snarcos::verify(caller(), IDENTIFIER, proof(), input(), SYSTEM),
88+
Error::<TestRuntime>::UnknownVerificationKeyIdentifier
89+
);
90+
});
91+
}
92+
93+
#[test]
94+
fn verify_shouts_when_key_is_not_decodable() {
95+
new_test_ext().execute_with(|| {
96+
VerificationKeys::<TestRuntime>::insert(
97+
IDENTIFIER,
98+
BoundedVec::try_from(vec![0, 1, 2]).unwrap(),
99+
);
100+
101+
assert_err!(
102+
Snarcos::verify(caller(), IDENTIFIER, proof(), input(), SYSTEM),
103+
Error::<TestRuntime>::DeserializingVerificationKeyFailed
104+
);
105+
});
106+
}
107+
108+
#[test]
109+
fn verify_shouts_when_proof_is_not_decodable() {
110+
new_test_ext().execute_with(|| {
111+
put_key();
112+
113+
assert_err!(
114+
Snarcos::verify(caller(), IDENTIFIER, input(), input(), SYSTEM),
115+
Error::<TestRuntime>::DeserializingProofFailed
116+
);
117+
});
118+
}
119+
120+
#[test]
121+
fn verify_shouts_when_input_is_not_decodable() {
122+
new_test_ext().execute_with(|| {
123+
put_key();
124+
125+
assert_err!(
126+
Snarcos::verify(caller(), IDENTIFIER, proof(), proof(), SYSTEM),
127+
Error::<TestRuntime>::DeserializingPublicInputFailed
128+
);
129+
});
130+
}
131+
132+
#[test]
133+
fn verify_shouts_when_verification_fails() {
134+
new_test_ext().execute_with(|| {
135+
put_key();
136+
let other_input = include_bytes!("../resources/groth16/linear_equation.public_input.bytes");
137+
138+
assert_err!(
139+
Snarcos::verify(caller(), IDENTIFIER, proof(), other_input.to_vec(), SYSTEM),
140+
Error::<TestRuntime>::VerificationFailed
141+
);
142+
});
143+
}
144+
145+
#[test]
146+
fn verify_shouts_when_proof_is_incorrect() {
147+
new_test_ext().execute_with(|| {
148+
put_key();
149+
let other_proof = include_bytes!("../resources/groth16/linear_equation.proof.bytes");
150+
151+
assert_err!(
152+
Snarcos::verify(caller(), IDENTIFIER, other_proof.to_vec(), input(), SYSTEM),
153+
Error::<TestRuntime>::IncorrectProof
154+
);
155+
});
156+
}

0 commit comments

Comments
 (0)