From dfb7fef654a28174f945743f9fb4fa96e9947950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kru=CC=88ger?= Date: Mon, 12 Feb 2018 19:14:57 +0100 Subject: [PATCH] bridge/src/signature.rs: 100% test coverage with quickcheck --- Cargo.lock | 22 ++++++++++++++++++++++ bridge/Cargo.toml | 1 + bridge/src/lib.rs | 3 +++ bridge/src/signature.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 503ddc3..323b240 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,6 +84,7 @@ dependencies = [ "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -169,6 +170,15 @@ dependencies = [ "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "env_logger" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error-chain" version = "0.11.0" @@ -552,6 +562,16 @@ dependencies = [ "difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quickcheck" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quote" version = "0.3.15" @@ -1031,6 +1051,7 @@ dependencies = [ "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" +"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum ethabi 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8385a48c8ed984778dcca27efc0de162a191a14ed733a41a07d9b0cfaa999e" "checksum ethabi-contract 5.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca2263c24359e827348ac99aa1f2e28ba5bab0d6c0b83941fa252de8a9e9c073" @@ -1073,6 +1094,7 @@ dependencies = [ "checksum parking_lot_core 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8c47785371ae3ca397fe9eb2350e5a3ac5cfd7d329f3d9ea8375e39f1a55f377" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pretty_assertions 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d510007841e87c7a6d829a36f7f0acb72aef12e38cc89073fe39810c1d976ac" +"checksum quickcheck 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15cda2c09a11b72e8563c57760dd5cf8b1fb3bb595df5759b5653048ab04e030" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" diff --git a/bridge/Cargo.toml b/bridge/Cargo.toml index fa42da4..5e9120a 100644 --- a/bridge/Cargo.toml +++ b/bridge/Cargo.toml @@ -23,3 +23,4 @@ pretty_assertions = "0.2.1" [dev-dependencies] tempdir = "0.3" +quickcheck = "0.6.1" diff --git a/bridge/src/lib.rs b/bridge/src/lib.rs index 61f14bc..aa1b0df 100644 --- a/bridge/src/lib.rs +++ b/bridge/src/lib.rs @@ -21,6 +21,9 @@ extern crate log; extern crate ethereum_types; #[macro_use] extern crate pretty_assertions; +#[cfg(test)] +#[macro_use] +extern crate quickcheck; #[macro_use] mod macros; diff --git a/bridge/src/signature.rs b/bridge/src/signature.rs index 0304fcc..e41c488 100644 --- a/bridge/src/signature.rs +++ b/bridge/src/signature.rs @@ -7,6 +7,8 @@ use ethabi; pub const SIGNATURE_LENGTH: usize = 65; +/// an ECDSA signature consisting of `v`, `r` and `s` +#[derive(PartialEq, Debug)] pub struct Signature { pub v: u8, pub r: H256, @@ -48,3 +50,41 @@ impl Signature { ethabi::encode(&[ethabi::Token::Bytes(self.to_bytes())]) } } + +#[cfg(test)] +mod test { + use quickcheck::TestResult; + use super::*; + + quickcheck! { + fn quickcheck_signature_roundtrips(v: u8, r_raw: Vec, s_raw: Vec) -> TestResult { + if r_raw.len() != 32 || s_raw.len() != 32 { + return TestResult::discard(); + } + + let r: H256 = r_raw.as_slice().into(); + let s: H256 = s_raw.as_slice().into(); + let signature = Signature { v, r, s }; + assert_eq!(v, signature.v); + assert_eq!(r, signature.r); + assert_eq!(s, signature.s); + + let bytes = signature.to_bytes(); + assert_eq!(v, Signature::v_from_bytes(bytes.as_slice())); + assert_eq!(r, Signature::r_from_bytes(bytes.as_slice())); + assert_eq!(s, Signature::s_from_bytes(bytes.as_slice())); + + let signature2 = Signature::from_bytes(bytes.as_slice()); + assert_eq!(signature, signature2); + + let payload = signature.to_payload(); + let mut tokens = ethabi::decode(&[ethabi::ParamType::Bytes], payload.as_slice()) + .unwrap(); + let decoded = tokens.pop().unwrap().to_bytes().unwrap(); + + assert_eq!(signature, Signature::from_bytes(decoded.as_slice())); + + TestResult::passed() + } + } +}