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
@@ -109,6 +109,8 @@ pub enum ReturnCode {
/// ECDSA compressed pubkey conversion into Ethereum address failed (most probably
/// wrong pubkey provided).
EcdsaRecoverFailed = 11,
/// sr25519 signature verification failed.
Sr25519VerifyFailed = 12,
}
impl From<ExecReturnValue> for ReturnCode {
@@ -251,6 +253,8 @@ pub enum RuntimeCosts {
HashBlake128(u32),
/// Weight of calling `seal_ecdsa_recover`.
EcdsaRecovery,
/// Weight of calling `seal_sr25519_verify` for the given input size.
Sr25519Verify(u32),
/// Weight charged by a chain extension through `seal_call_chain_extension`.
ChainExtension(Weight),
/// Weight charged for calling into the runtime.
@@ -336,6 +340,9 @@ impl RuntimeCosts {
.hash_blake2_128
.saturating_add(s.hash_blake2_128_per_byte.saturating_mul(len.into())),
EcdsaRecovery => s.ecdsa_recover,
Sr25519Verify(len) => s
.sr25519_verify
.saturating_add(s.sr25519_verify_per_byte.saturating_mul(len.into())),
ChainExtension(weight) => weight,
CallRuntime(weight) => weight,
SetCodeHash => s.set_code_hash,
@@ -2466,6 +2473,46 @@ pub mod env {
}
}
/// Verify a sr25519 signature
///
/// # Parameters
///
/// - `signature_ptr`: the pointer into the linear memory where the signature is placed. Should
/// be a value of 64 bytes.
/// - `pub_key_ptr`: the pointer into the linear memory where the public key is placed. Should
/// be a value of 32 bytes.
/// - `message_len`: the length of the message payload.
/// - `message_ptr`: the pointer into the linear memory where the message is placed.
///
/// # Errors
///
/// - `ReturnCode::Sr25519VerifyFailed
#[unstable]
fn sr25519_verify(
ctx: _,
memory: _,
signature_ptr: u32,
pub_key_ptr: u32,
message_len: u32,
message_ptr: u32,
) -> Result<ReturnCode, TrapReason> {
ctx.charge_gas(RuntimeCosts::Sr25519Verify(message_len))?;
let mut signature: [u8; 64] = [0; 64];
ctx.read_sandbox_memory_into_buf(memory, signature_ptr, &mut signature)?;
let mut pub_key: [u8; 32] = [0; 32];
ctx.read_sandbox_memory_into_buf(memory, pub_key_ptr, &mut pub_key)?;
let message: Vec<u8> = ctx.read_sandbox_memory(memory, message_ptr, message_len)?;
if ctx.ext.sr25519_verify(&signature, &message, &pub_key) {
Ok(ReturnCode::Success)
} else {
Ok(ReturnCode::Sr25519VerifyFailed)
}
}
/// Replace the contract code at the specified address with new code.
///
/// # Note