contracts: add sr25519_verify (#13724)

* wip

* fix

* wip

* fix lint

* rm fixture fix

* missing comment

* fix lint

* add comment to the wsm file

* fix comment

* Apply suggestions from code review

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* wip

* wip weights

* wip weights

* PR comment: test with return code

* wip

* PR review add mock test

* remove

* lint

* Update frame/contracts/fixtures/sr25519_verify.wat

* fix comments

* Update frame/contracts/src/benchmarking/mod.rs

* Update frame/contracts/src/wasm/runtime.rs

* Update frame/contracts/fixtures/sr25519_verify.wat

* Update frame/contracts/src/benchmarking/mod.rs

* fix lint

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts

* Update frame/contracts/src/wasm/runtime.rs

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* PR: review use unstable + remove arbitrary index 4

* Add benchmark for calculating overhead of calling sr25519_verify

* fix message length encoding

* fix weights

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts

* Apply suggestions from code review

* Update frame/contracts/src/wasm/runtime.rs

* Update frame/contracts/src/wasm/runtime.rs

* Update frame/contracts/src/benchmarking/mod.rs

* Update frame/contracts/src/benchmarking/mod.rs

* Update frame/contracts/src/schedule.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* Update frame/contracts/src/schedule.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* Update frame/contracts/src/wasm/runtime.rs

* Update frame/contracts/src/wasm/runtime.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* PR review

---------

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>
Co-authored-by: command-bot <>
Co-authored-by: Alexander Theißen <alex.theissen@me.com>
This commit is contained in:
PG Herveou
2023-04-12 16:49:10 +02:00
committed by GitHub
parent 376a288fb6
commit 03c99fe003
8 changed files with 1332 additions and 894 deletions
@@ -2008,9 +2008,114 @@ benchmarks! {
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
// `n`: Message input length to verify in bytes.
#[pov_mode = Measured]
seal_sr25519_verify_per_byte {
let n in 0 .. T::MaxCodeLen::get() - 255; // need some buffer so the code size does not
// exceed the max code size.
let message = (0..n).zip((32u8..127u8).cycle()).map(|(_, c)| c).collect::<Vec<_>>();
let message_len = message.len() as i32;
let key_type = sp_core::crypto::KeyTypeId(*b"code");
let pub_key = sp_io::crypto::sr25519_generate(key_type, None);
let sig = sp_io::crypto::sr25519_sign(key_type, &pub_key, &message).expect("Generates signature");
let sig = AsRef::<[u8; 64]>::as_ref(&sig).to_vec();
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "sr25519_verify",
params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32],
return_type: Some(ValueType::I32),
}],
data_segments: vec![
DataSegment {
offset: 0,
value: sig,
},
DataSegment {
offset: 64,
value: pub_key.to_vec(),
},
DataSegment {
offset: 96,
value: message,
},
],
call_body: Some(body::plain(vec![
Instruction::I32Const(0), // signature_ptr
Instruction::I32Const(64), // pub_key_ptr
Instruction::I32Const(message_len), // message_len
Instruction::I32Const(96), // message_ptr
Instruction::Call(0),
Instruction::Drop,
Instruction::End,
])),
.. Default::default()
});
let instance = Contract::<T>::new(code, vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
// Only calling the function itself with valid arguments.
// It generates different private keys and signatures for the message "Hello world".
// This is a slow call: We redeuce the number of runs.
// This is a slow call: We reduce the number of runs.
#[pov_mode = Measured]
seal_sr25519_verify {
let r in 0 .. API_BENCHMARK_RUNS / 10;
let message = b"Hello world".to_vec();
let message_len = message.len() as i32;
let key_type = sp_core::crypto::KeyTypeId(*b"code");
let sig_params = (0..r)
.map(|i| {
let pub_key = sp_io::crypto::sr25519_generate(key_type, None);
let sig = sp_io::crypto::sr25519_sign(key_type, &pub_key, &message).expect("Generates signature");
let data: [u8; 96] = [AsRef::<[u8]>::as_ref(&sig), AsRef::<[u8]>::as_ref(&pub_key)].concat().try_into().unwrap();
data
})
.flatten()
.collect::<Vec<_>>();
let sig_params_len = sig_params.len() as i32;
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "sr25519_verify",
params: vec![ValueType::I32, ValueType::I32, ValueType::I32, ValueType::I32],
return_type: Some(ValueType::I32),
}],
data_segments: vec![
DataSegment {
offset: 0,
value: sig_params
},
DataSegment {
offset: sig_params_len as u32,
value: message,
},
],
call_body: Some(body::repeated_dyn(r, vec![
Counter(0, 96), // signature_ptr
Counter(64, 96), // pub_key_ptr
Regular(Instruction::I32Const(message_len)), // message_len
Regular(Instruction::I32Const(sig_params_len)), // message_ptr
Regular(Instruction::Call(0)),
Regular(Instruction::Drop),
])),
.. Default::default()
});
let instance = Contract::<T>::new(code, vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
// Only calling the function itself with valid arguments.
// It generates different private keys and signatures for the message "Hello world".
// This is a slow call: We reduce the number of runs.
#[pov_mode = Measured]
seal_ecdsa_recover {
let r in 0 .. API_BENCHMARK_RUNS / 10;