Unverified Commit 2f44ce41 authored by Shawn Tabrizi's avatar Shawn Tabrizi Committed by GitHub
Browse files

Benchmark Polkadot Claims Pallet (#876)



* fix

* Starting to add benchmarks

* make compile

* add benchmarks

* Make work with Substrate master

* Bench validate unsigned

* back to polkadot master

* starting to add cli with feature flag

* more stuff

* Add to kusama

* Update Cargo.lock

* fix dev dep

* bump wasm builder

* Remove encode from keccak benchmark

* bump spec

* Add weight documentation

* Update Cargo.lock

* Update check_runtime.sh

* Update publish_draft_release.sh

* Update Cargo.lock
Co-authored-by: thiolliere's avatarthiolliere <gui.thiolliere@gmail.com>
parent 4b617974
Pipeline #82777 failed with stages
in 15 minutes and 4 seconds
This diff is collapsed.
...@@ -56,3 +56,6 @@ maintenance = { status = "actively-developed" } ...@@ -56,3 +56,6 @@ maintenance = { status = "actively-developed" }
[profile.release] [profile.release]
# Polkadot runtime requires unwinding. # Polkadot runtime requires unwinding.
panic = "unwind" panic = "unwind"
[features]
runtime-benchmarks=["cli/runtime-benchmarks"]
...@@ -17,7 +17,6 @@ crate-type = ["cdylib", "rlib"] ...@@ -17,7 +17,6 @@ crate-type = ["cdylib", "rlib"]
log = "0.4.8" log = "0.4.8"
futures = { version = "0.3.4", features = ["compat"] } futures = { version = "0.3.4", features = ["compat"] }
structopt = "0.3.8" structopt = "0.3.8"
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
...@@ -28,6 +27,8 @@ sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polka ...@@ -28,6 +27,8 @@ sc-executor = { git = "https://github.com/paritytech/substrate", branch = "polka
service = { package = "polkadot-service", path = "../service", default-features = false } service = { package = "polkadot-service", path = "../service", default-features = false }
tokio = { version = "0.2.10", features = ["rt-threaded"], optional = true } tokio = { version = "0.2.10", features = ["rt-threaded"], optional = true }
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true }
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", optional = true }
wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen = { version = "0.2.57", optional = true }
wasm-bindgen-futures = { version = "0.4.7", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true }
...@@ -40,6 +41,7 @@ rocksdb = [ "service/rocksdb" ] ...@@ -40,6 +41,7 @@ rocksdb = [ "service/rocksdb" ]
cli = [ cli = [
"tokio", "tokio",
"sc-cli", "sc-cli",
"frame-benchmarking-cli",
"service/full-node", "service/full-node",
] ]
browser = [ browser = [
...@@ -47,3 +49,4 @@ browser = [ ...@@ -47,3 +49,4 @@ browser = [
"wasm-bindgen-futures", "wasm-bindgen-futures",
"browser-utils", "browser-utils",
] ]
runtime-benchmarks = ["service/runtime-benchmarks"]
...@@ -29,6 +29,13 @@ pub enum Subcommand { ...@@ -29,6 +29,13 @@ pub enum Subcommand {
#[allow(missing_docs)] #[allow(missing_docs)]
#[structopt(name = "validation-worker", setting = structopt::clap::AppSettings::Hidden)] #[structopt(name = "validation-worker", setting = structopt::clap::AppSettings::Hidden)]
ValidationWorker(ValidationWorkerCommand), ValidationWorker(ValidationWorkerCommand),
/// The custom benchmark subcommmand benchmarking runtime pallets.
#[structopt(
name = "benchmark",
about = "Benchmark runtime pallets."
)]
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
} }
#[allow(missing_docs)] #[allow(missing_docs)]
......
...@@ -98,6 +98,18 @@ pub fn run(version: VersionInfo) -> sc_cli::Result<()> { ...@@ -98,6 +98,18 @@ pub fn run(version: VersionInfo) -> sc_cli::Result<()> {
Ok(()) Ok(())
} }
}, },
Some(Subcommand::Benchmark(cmd)) => {
cmd.init(&version)?;
cmd.update_config(&mut config, load_spec, &version)?;
let is_kusama = config.chain_spec.as_ref().map_or(false, |s| s.is_kusama());
if is_kusama {
cmd.run::<_, _, service::kusama_runtime::Block, service::KusamaExecutor>(config)
} else {
cmd.run::<_, _, service::polkadot_runtime::Block, service::PolkadotExecutor>(config)
}
},
} }
} }
......
...@@ -9,7 +9,7 @@ edition = "2018" ...@@ -9,7 +9,7 @@ edition = "2018"
codec = { package = "parity-scale-codec", version = "1.1.0", default-features = false, features = [ "derive" ] } codec = { package = "parity-scale-codec", version = "1.1.0", default-features = false, features = [ "derive" ] }
derive_more = { version = "0.99.2", optional = true } derive_more = { version = "0.99.2", optional = true }
serde = { version = "1.0.102", default-features = false, features = [ "derive" ], optional = true } serde = { version = "1.0.102", default-features = false, features = [ "derive" ], optional = true }
rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-runtime-interface = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-runtime-interface = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-wasm-interface = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-wasm-interface = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
...@@ -35,7 +35,7 @@ std = [ ...@@ -35,7 +35,7 @@ std = [
"codec/std", "codec/std",
"derive_more", "derive_more",
"serde/std", "serde/std",
"rstd/std", "sp-std/std",
"shared_memory", "shared_memory",
"sp-core/std", "sp-core/std",
"lazy_static", "lazy_static",
......
...@@ -48,7 +48,7 @@ pub mod wasm_executor; ...@@ -48,7 +48,7 @@ pub mod wasm_executor;
mod wasm_api; mod wasm_api;
use rstd::vec::Vec; use sp_std::vec::Vec;
use codec::{Encode, Decode, CompactAs}; use codec::{Encode, Decode, CompactAs};
use sp_core::{RuntimeDebug, TypeId}; use sp_core::{RuntimeDebug, TypeId};
...@@ -117,7 +117,7 @@ impl Id { ...@@ -117,7 +117,7 @@ impl Id {
pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START } pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START }
} }
impl rstd::ops::Add<u32> for Id { impl sp_std::ops::Add<u32> for Id {
type Output = Self; type Output = Self;
fn add(self, other: u32) -> Self { fn add(self, other: u32) -> Self {
...@@ -192,7 +192,7 @@ pub enum ParachainDispatchOrigin { ...@@ -192,7 +192,7 @@ pub enum ParachainDispatchOrigin {
Root, Root,
} }
impl rstd::convert::TryFrom<u8> for ParachainDispatchOrigin { impl sp_std::convert::TryFrom<u8> for ParachainDispatchOrigin {
type Error = (); type Error = ();
fn try_from(x: u8) -> core::result::Result<ParachainDispatchOrigin, ()> { fn try_from(x: u8) -> core::result::Result<ParachainDispatchOrigin, ()> {
const SIGNED: u8 = ParachainDispatchOrigin::Signed as u8; const SIGNED: u8 = ParachainDispatchOrigin::Signed as u8;
......
...@@ -42,7 +42,7 @@ pub trait Parachain { ...@@ -42,7 +42,7 @@ pub trait Parachain {
/// function's entry point. /// function's entry point.
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
pub unsafe fn load_params(params: *const u8, len: usize) -> crate::ValidationParams { pub unsafe fn load_params(params: *const u8, len: usize) -> crate::ValidationParams {
let mut slice = rstd::slice::from_raw_parts(params, len); let mut slice = sp_std::slice::from_raw_parts(params, len);
codec::Decode::decode(&mut slice).expect("Invalid input data") codec::Decode::decode(&mut slice).expect("Invalid input data")
} }
......
...@@ -12,7 +12,7 @@ inherents = { package = "sp-inherents", git = "https://github.com/paritytech/sub ...@@ -12,7 +12,7 @@ inherents = { package = "sp-inherents", git = "https://github.com/paritytech/sub
application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } application-crypto = { package = "sp-application-crypto", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-version = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
runtime_primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } runtime_primitives = { package = "sp-runtime", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
polkadot-parachain = { path = "../parachain", default-features = false } polkadot-parachain = { path = "../parachain", default-features = false }
trie = { package = "sp-trie", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } trie = { package = "sp-trie", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
...@@ -31,7 +31,7 @@ std = [ ...@@ -31,7 +31,7 @@ std = [
"inherents/std", "inherents/std",
"trie/std", "trie/std",
"sp-api/std", "sp-api/std",
"rstd/std", "sp-std/std",
"sp-version/std", "sp-version/std",
"runtime_primitives/std", "runtime_primitives/std",
"serde", "serde",
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
//! Polkadot parachain types. //! Polkadot parachain types.
use rstd::prelude::*; use sp_std::prelude::*;
use rstd::cmp::Ordering; use sp_std::cmp::Ordering;
use parity_scale_codec::{Encode, Decode}; use parity_scale_codec::{Encode, Decode};
use bitvec::vec::BitVec; use bitvec::vec::BitVec;
use super::{Hash, Balance}; use super::{Hash, Balance};
...@@ -646,7 +646,7 @@ pub struct FeeSchedule { ...@@ -646,7 +646,7 @@ pub struct FeeSchedule {
impl FeeSchedule { impl FeeSchedule {
/// Compute the fee for a message of given size. /// Compute the fee for a message of given size.
pub fn compute_fee(&self, n_bytes: usize) -> Balance { pub fn compute_fee(&self, n_bytes: usize) -> Balance {
use rstd::mem; use sp_std::mem;
debug_assert!(mem::size_of::<Balance>() >= mem::size_of::<usize>()); debug_assert!(mem::size_of::<Balance>() >= mem::size_of::<usize>());
let n_bytes = n_bytes as Balance; let n_bytes = n_bytes as Balance;
......
...@@ -14,7 +14,7 @@ serde_derive = { version = "1.0.102", optional = true } ...@@ -14,7 +14,7 @@ serde_derive = { version = "1.0.102", optional = true }
sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
rstd = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } sp-staking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
...@@ -28,14 +28,14 @@ staking = { package = "pallet-staking", git = "https://github.com/paritytech/sub ...@@ -28,14 +28,14 @@ staking = { package = "pallet-staking", git = "https://github.com/paritytech/sub
system = { package = "frame-system", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } system = { package = "frame-system", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
timestamp = { package = "pallet-timestamp", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } timestamp = { package = "pallet-timestamp", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
vesting = { package = "pallet-vesting", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } vesting = { package = "pallet-vesting", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false, optional = true }
primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false } primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false }
polkadot-parachain = { path = "../../parachain", default-features = false } polkadot-parachain = { path = "../../parachain", default-features = false }
libsecp256k1 = { version = "0.3.2", default-features = false, optional = true }
[dev-dependencies] [dev-dependencies]
hex-literal = "0.2.1" hex-literal = "0.2.1"
libsecp256k1 = "0.3.2"
tiny-keccak = "1.5.0"
keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" } sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot-master" }
babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } babe = { package = "pallet-babe", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
...@@ -44,6 +44,7 @@ pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate", ...@@ -44,6 +44,7 @@ pallet-staking-reward-curve = { git = "https://github.com/paritytech/substrate",
treasury = { package = "pallet-treasury", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false } treasury = { package = "pallet-treasury", git = "https://github.com/paritytech/substrate", branch = "polkadot-master", default-features = false }
trie-db = "0.20.0" trie-db = "0.20.0"
serde_json = "1.0.41" serde_json = "1.0.41"
libsecp256k1 = "0.3.2"
[features] [features]
default = [] default = []
...@@ -57,7 +58,7 @@ std = [ ...@@ -57,7 +58,7 @@ std = [
"sp-core/std", "sp-core/std",
"polkadot-parachain/std", "polkadot-parachain/std",
"sp-api/std", "sp-api/std",
"rstd/std", "sp-std/std",
"sp-io/std", "sp-io/std",
"frame-support/std", "frame-support/std",
"authorship/std", "authorship/std",
...@@ -73,3 +74,4 @@ std = [ ...@@ -73,3 +74,4 @@ std = [
"serde/std", "serde/std",
"log", "log",
] ]
runtime-benchmarks = ["frame-benchmarking", "libsecp256k1"]
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
//! In the future, it is planned that this module will handle dispute resolution //! In the future, it is planned that this module will handle dispute resolution
//! as well. //! as well.
use rstd::prelude::*; use sp_std::prelude::*;
use codec::{Encode, Decode}; use codec::{Encode, Decode};
use frame_support::{ use frame_support::{
decl_storage, decl_module, decl_error, ensure, dispatch::DispatchResult, traits::Get decl_storage, decl_module, decl_error, ensure, dispatch::DispatchResult, traits::Get
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
//! Module to process claims from Ethereum addresses. //! Module to process claims from Ethereum addresses.
use rstd::prelude::*; use sp_std::prelude::*;
use sp_io::{hashing::keccak_256, crypto::secp256k1_ecdsa_recover}; use sp_io::{hashing::keccak_256, crypto::secp256k1_ecdsa_recover};
use frame_support::{decl_event, decl_storage, decl_module, decl_error}; use frame_support::{decl_event, decl_storage, decl_module, decl_error};
use frame_support::weights::SimpleDispatchInfo; use frame_support::weights::SimpleDispatchInfo;
...@@ -85,8 +85,8 @@ impl PartialEq for EcdsaSignature { ...@@ -85,8 +85,8 @@ impl PartialEq for EcdsaSignature {
} }
} }
impl rstd::fmt::Debug for EcdsaSignature { impl sp_std::fmt::Debug for EcdsaSignature {
fn fmt(&self, f: &mut rstd::fmt::Formatter<'_>) -> rstd::fmt::Result { fn fmt(&self, f: &mut sp_std::fmt::Formatter<'_>) -> sp_std::fmt::Result {
write!(f, "EcdsaSignature({:?})", &self.0[..]) write!(f, "EcdsaSignature({:?})", &self.0[..])
} }
} }
...@@ -149,7 +149,38 @@ decl_module! { ...@@ -149,7 +149,38 @@ decl_module! {
/// Deposit one of this module's events by using the default implementation. /// Deposit one of this module's events by using the default implementation.
fn deposit_event() = default; fn deposit_event() = default;
/// Make a claim. /// Make a claim to collect your DOTs.
///
/// The dispatch origin for this call must be _None_.
///
/// Unsigned Validation:
/// A call to claim is deemed valid if the signature provided matches
/// the expected signed message of:
///
/// > Ethereum Signed Message:
/// > (configured prefix string)(address)
///
/// and `address` matches the `dest` account.
///
/// Parameters:
/// - `dest`: The destination account to payout the claim.
/// - `ethereum_signature`: The signature of an ethereum signed message
/// matching the format described above.
///
/// <weight>
/// The weight of this call is invariant over the input parameters.
/// - One `eth_recover` operation which involves a keccak hash and a
/// ecdsa recover.
/// - Three storage reads to check if a claim exists for the user, to
/// get the current pot size, to see if there exists a vesting schedule.
/// - Up to one storage write for adding a new vesting schedule.
/// - One `deposit_creating` Currency call.
/// - One storage write to update the total.
/// - Two storage removals for vesting and claims information.
/// - One deposit event.
///
/// Total Complexity: O(1)
/// </weight>
#[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)]
fn claim(origin, dest: T::AccountId, ethereum_signature: EcdsaSignature) { fn claim(origin, dest: T::AccountId, ethereum_signature: EcdsaSignature) {
ensure_none(origin)?; ensure_none(origin)?;
...@@ -180,7 +211,23 @@ decl_module! { ...@@ -180,7 +211,23 @@ decl_module! {
Self::deposit_event(RawEvent::Claimed(dest, signer, balance_due)); Self::deposit_event(RawEvent::Claimed(dest, signer, balance_due));
} }
/// Add a new claim, if you are root. /// Mint a new claim to collect DOTs.
///
/// The dispatch origin for this call must be _Root_.
///
/// Parameters:
/// - `who`: The Ethereum address allowed to collect this claim.
/// - `value`: The number of DOTs that will be claimed.
/// - `vesting_schedule`: An optional vesting schedule for these DOTs.
///
/// <weight>
/// The weight of this call is invariant over the input parameters.
/// - One storage mutate to increase the total claims available.
/// - One storage write to add a new claim.
/// - Up to one storage write to add a new vesting schedule.
///
/// Total Complexity: O(1)
/// </weight>
#[weight = SimpleDispatchInfo::FixedNormal(30_000)] #[weight = SimpleDispatchInfo::FixedNormal(30_000)]
fn mint_claim(origin, fn mint_claim(origin,
who: EthereumAddress, who: EthereumAddress,
...@@ -274,12 +321,35 @@ impl<T: Trait> sp_runtime::traits::ValidateUnsigned for Module<T> { ...@@ -274,12 +321,35 @@ impl<T: Trait> sp_runtime::traits::ValidateUnsigned for Module<T> {
} }
} }
#[cfg(any(test, feature = "runtime-benchmarks"))]
mod secp_utils {
use super::*;
use secp256k1;
pub fn public(secret: &secp256k1::SecretKey) -> secp256k1::PublicKey {
secp256k1::PublicKey::from_secret_key(secret)
}
pub fn eth(secret: &secp256k1::SecretKey) -> EthereumAddress {
let mut res = EthereumAddress::default();
res.0.copy_from_slice(&keccak_256(&public(secret).serialize()[1..65])[12..]);
res
}
pub fn sig<T: Trait>(secret: &secp256k1::SecretKey, what: &[u8]) -> EcdsaSignature {
let msg = keccak_256(&<super::Module<T>>::ethereum_signable_message(&to_ascii_hex(what)[..]));
let (sig, recovery_id) = secp256k1::sign(&secp256k1::Message::parse(&msg), secret);
let mut r = [0u8; 65];
r[0..64].copy_from_slice(&sig.serialize()[..]);
r[64] = recovery_id.serialize();
EcdsaSignature(r)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use secp256k1; use secp256k1;
use tiny_keccak::keccak256;
use hex_literal::hex; use hex_literal::hex;
use super::*; use super::*;
use secp_utils::*;
use sp_core::H256; use sp_core::H256;
use codec::Encode; use codec::Encode;
...@@ -363,26 +433,10 @@ mod tests { ...@@ -363,26 +433,10 @@ mod tests {
type Claims = Module<Test>; type Claims = Module<Test>;
fn alice() -> secp256k1::SecretKey { fn alice() -> secp256k1::SecretKey {
secp256k1::SecretKey::parse(&keccak256(b"Alice")).unwrap() secp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap()
} }
fn bob() -> secp256k1::SecretKey { fn bob() -> secp256k1::SecretKey {
secp256k1::SecretKey::parse(&keccak256(b"Bob")).unwrap() secp256k1::SecretKey::parse(&keccak_256(b"Bob")).unwrap()
}
fn public(secret: &secp256k1::SecretKey) -> secp256k1::PublicKey {
secp256k1::PublicKey::from_secret_key(secret)
}
fn eth(secret: &secp256k1::SecretKey) -> EthereumAddress {
let mut res = EthereumAddress::default();
res.0.copy_from_slice(&keccak256(&public(secret).serialize()[1..65])[12..]);
res
}
fn sig(secret: &secp256k1::SecretKey, what: &[u8]) -> EcdsaSignature {
let msg = keccak256(&Claims::ethereum_signable_message(&to_ascii_hex(what)[..]));
let (sig, recovery_id) = secp256k1::sign(&secp256k1::Message::parse(&msg), secret);
let mut r = [0u8; 65];
r[0..64].copy_from_slice(&sig.serialize()[..]);
r[64] = recovery_id.serialize();
EcdsaSignature(r)
} }
// This function basically just builds a genesis storage key/value store according to // This function basically just builds a genesis storage key/value store according to
...@@ -421,7 +475,7 @@ mod tests { ...@@ -421,7 +475,7 @@ mod tests {
fn claiming_works() { fn claiming_works() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::free_balance(42), 0);
assert_ok!(Claims::claim(Origin::NONE, 42, sig(&alice(), &42u64.encode()))); assert_ok!(Claims::claim(Origin::NONE, 42, sig::<Test>(&alice(), &42u64.encode())));
assert_eq!(Balances::free_balance(&42), 100); assert_eq!(Balances::free_balance(&42), 100);
assert_eq!(Vesting::vesting_balance(&42), Some(50)); assert_eq!(Vesting::vesting_balance(&42), Some(50));
assert_eq!(Claims::total(), 0); assert_eq!(Claims::total(), 0);
...@@ -437,12 +491,12 @@ mod tests { ...@@ -437,12 +491,12 @@ mod tests {
); );
assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::free_balance(42), 0);
assert_noop!( assert_noop!(
Claims::claim(Origin::NONE, 69, sig(&bob(), &69u64.encode())), Claims::claim(Origin::NONE, 69, sig::<Test>(&bob(), &69u64.encode())),
Error::<Test>::SignerHasNoClaim, Error::<Test>::SignerHasNoClaim,
); );
assert_ok!(Claims::mint_claim(Origin::ROOT, eth(&bob()), 200, None)); assert_ok!(Claims::mint_claim(Origin::ROOT, eth(&bob()), 200, None));
assert_eq!(Claims::total(), 300); assert_eq!(Claims::total(), 300);
assert_ok!(Claims::claim(Origin::NONE, 69, sig(&bob(), &69u64.encode()))); assert_ok!(Claims::claim(Origin::NONE, 69, sig::<Test>(&bob(), &69u64.encode())));
assert_eq!(Balances::free_balance(&69), 200); assert_eq!(Balances::free_balance(&69), 200);
assert_eq!(Vesting::vesting_balance(&69), None); assert_eq!(Vesting::vesting_balance(&69), None);
assert_eq!(Claims::total(), 100); assert_eq!(Claims::total(), 100);
...@@ -458,11 +512,11 @@ mod tests { ...@@ -458,11 +512,11 @@ mod tests {
); );
assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::free_balance(42), 0);
assert_noop!( assert_noop!(
Claims::claim(Origin::NONE, 69, sig(&bob(), &69u64.encode())), Claims::claim(Origin::NONE, 69, sig::<Test>(&bob(), &69u64.encode())),
Error::<Test>::SignerHasNoClaim Error::<Test>::SignerHasNoClaim
); );
assert_ok!(Claims::mint_claim(Origin::ROOT, eth(&bob()), 200, Some((50, 10, 1)))); assert_ok!(Claims::mint_claim(Origin::ROOT, eth(&bob()), 200, Some((50, 10, 1))));
assert_ok!(Claims::claim(Origin::NONE, 69, sig(&bob(), &69u64.encode()))); assert_ok!(Claims::claim(Origin::NONE, 69, sig::<Test>(&bob(), &69u64.encode())));
assert_eq!(Balances::free_balance(&69), 200); assert_eq!(Balances::free_balance(&69), 200);
assert_eq!(Vesting::vesting_balance(&69), Some(50)); assert_eq!(Vesting::vesting_balance(&69), Some(50));
}); });
...@@ -473,7 +527,7 @@ mod tests { ...@@ -473,7 +527,7 @@ mod tests {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::free_balance(42), 0);
assert_err!( assert_err!(
Claims::claim(Origin::signed(42), 42, sig(&alice(), &42u64.encode())), Claims::claim(Origin::signed(42), 42, sig::<Test>(&alice(), &42u64.encode())),
sp_runtime::traits::BadOrigin, sp_runtime::traits::BadOrigin,
); );
}); });
...@@ -483,9 +537,9 @@ mod tests { ...@@ -483,9 +537,9 @@ mod tests {
fn double_claiming_doesnt_work() { fn double_claiming_doesnt_work() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::free_balance(42), 0);
assert_ok!(Claims::claim(Origin::NONE, 42, sig(&alice(), &42u64.encode()))); assert_ok!(Claims::claim(Origin::NONE, 42, sig::<Test>(&alice(), &42u64.encode())));