contracts: Improve contract address derivation (#12883)

* Add prefix to address derivation

* Extend benchmark

* Fix node test

* ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts

* Adapt to new benchmark

* Update dispatchable benchmarks

* ".git/.scripts/bench-bot.sh" pallet dev pallet_contracts

* Use benchmark results

* Apply suggestions from code review

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

* Don't use T::AdressGenerator directly

* Rename constructor_args to input_data

Co-authored-by: command-bot <>
Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>
This commit is contained in:
Alexander Theißen
2022-12-22 15:52:48 +01:00
committed by GitHub
parent af15848be0
commit 4083b5358a
18 changed files with 1559 additions and 1479 deletions
@@ -41,7 +41,6 @@ use frame_support::{
traits::{Get, ReservableCurrency},
WeakBoundedVec,
};
use sp_core::crypto::UncheckedFrom;
use sp_runtime::traits::BadOrigin;
use sp_std::vec;
@@ -49,10 +48,7 @@ use sp_std::vec;
///
/// Increments the refcount of the in-storage `prefab_module` if it already exists in storage
/// under the specified `code_hash`.
pub fn store<T: Config>(mut module: PrefabWasmModule<T>, instantiated: bool) -> DispatchResult
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
pub fn store<T: Config>(mut module: PrefabWasmModule<T>, instantiated: bool) -> DispatchResult {
let code_hash = sp_std::mem::take(&mut module.code_hash);
<CodeStorage<T>>::mutate(&code_hash, |existing| match existing {
Some(existing) => {
@@ -135,10 +131,7 @@ pub fn increment_refcount<T: Config>(code_hash: CodeHash<T>) -> Result<(), Dispa
}
/// Try to remove code together with all associated information.
pub fn try_remove<T: Config>(origin: &T::AccountId, code_hash: CodeHash<T>) -> DispatchResult
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
pub fn try_remove<T: Config>(origin: &T::AccountId, code_hash: CodeHash<T>) -> DispatchResult {
<OwnerInfoOf<T>>::try_mutate_exists(&code_hash, |existing| {
if let Some(owner_info) = existing {
ensure!(owner_info.refcount == 0, <Error<T>>::CodeInUse);
@@ -164,10 +157,7 @@ pub fn load<T: Config>(
code_hash: CodeHash<T>,
schedule: &Schedule<T>,
gas_meter: &mut GasMeter<T>,
) -> Result<PrefabWasmModule<T>, DispatchError>
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
) -> Result<PrefabWasmModule<T>, DispatchError> {
let max_code_len = T::MaxCodeLen::get();
let charged = gas_meter.charge(CodeToken::Load(max_code_len))?;
@@ -192,10 +182,7 @@ where
pub fn reinstrument<T: Config>(
prefab_module: &mut PrefabWasmModule<T>,
schedule: &Schedule<T>,
) -> Result<u32, DispatchError>
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
) -> Result<u32, DispatchError> {
let original_code =
<PristineCode<T>>::get(&prefab_module.code_hash).ok_or(Error::<T>::CodeNotFound)?;
let original_code_len = original_code.len();
+4 -10
View File
@@ -36,7 +36,7 @@ use crate::{
};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::dispatch::{DispatchError, DispatchResult};
use sp_core::{crypto::UncheckedFrom, Get};
use sp_core::Get;
use sp_runtime::RuntimeDebug;
use sp_std::prelude::*;
#[cfg(test)]
@@ -140,10 +140,7 @@ impl ExportedFunction {
}
}
impl<T: Config> PrefabWasmModule<T>
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
impl<T: Config> PrefabWasmModule<T> {
/// Create the module by checking and instrumenting `original_code`.
///
/// This does **not** store the module. For this one need to either call [`Self::store`]
@@ -263,10 +260,7 @@ impl<T: Config> OwnerInfo<T> {
}
}
impl<T: Config> Executable<T> for PrefabWasmModule<T>
where
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
impl<T: Config> Executable<T> for PrefabWasmModule<T> {
fn from_storage(
code_hash: CodeHash<T>,
schedule: &Schedule<T>,
@@ -476,7 +470,7 @@ mod tests {
salt: salt.to_vec(),
});
Ok((
Contracts::<Test>::contract_address(&ALICE, &code_hash, salt),
Contracts::<Test>::contract_address(&ALICE, &code_hash, &data, salt),
ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() },
))
}
@@ -26,7 +26,6 @@ use crate::{
AccountIdOf, CodeVec, Config, Error, Schedule,
};
use codec::{Encode, MaxEncodedLen};
use sp_core::crypto::UncheckedFrom;
use sp_runtime::{traits::Hash, DispatchError};
use sp_std::prelude::*;
use wasm_instrument::{
@@ -396,7 +395,6 @@ fn instrument<E, T>(
where
E: Environment<()>,
T: Config,
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
// Do not enable any features here. Any additional feature needs to be carefully
// checked for potential security issues. For example, enabling multi value could lead
@@ -500,7 +498,6 @@ pub fn prepare<E, T>(
where
E: Environment<()>,
T: Config,
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
let (code, (initial, maximum)) =
instrument::<E, T>(original_code.as_ref(), schedule, determinism, try_instantiate)?;
@@ -547,7 +544,6 @@ pub fn reinstrument<E, T>(
where
E: Environment<()>,
T: Config,
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
instrument::<E, T>(original_code, schedule, determinism, TryInstantiate::Skip)
.map_err(|(err, msg)| {
+4 -18
View File
@@ -29,7 +29,6 @@ use codec::{Decode, DecodeLimit, Encode, MaxEncodedLen};
use frame_support::{dispatch::DispatchError, ensure, traits::Get, weights::Weight, RuntimeDebug};
use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
use pallet_contracts_proc_macro::define_env;
use sp_core::crypto::UncheckedFrom;
use sp_io::hashing::{blake2_128, blake2_256, keccak_256, sha2_256};
use sp_runtime::traits::{Bounded, Zero};
use sp_std::{fmt, prelude::*};
@@ -270,11 +269,7 @@ pub enum RuntimeCosts {
}
impl RuntimeCosts {
fn token<T>(&self, s: &HostFnWeights<T>) -> RuntimeToken
where
T: Config,
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
fn token<T: Config>(&self, s: &HostFnWeights<T>) -> RuntimeToken {
use self::RuntimeCosts::*;
let weight = match *self {
MeteringBlock(amount) => s.gas.saturating_add(amount),
@@ -324,7 +319,7 @@ impl RuntimeCosts {
CallInputCloned(len) => s.call_per_cloned_byte.saturating_mul(len.into()),
InstantiateBase { input_data_len, salt_len } => s
.instantiate
.saturating_add(s.return_per_byte.saturating_mul(input_data_len.into()))
.saturating_add(s.instantiate_per_input_byte.saturating_mul(input_data_len.into()))
.saturating_add(s.instantiate_per_salt_byte.saturating_mul(salt_len.into())),
InstantiateSurchargeTransfer => s.instantiate_transfer_surcharge,
HashSha256(len) => s
@@ -375,11 +370,7 @@ struct RuntimeToken {
weight: Weight,
}
impl<T> Token<T> for RuntimeToken
where
T: Config,
T::AccountId: UncheckedFrom<T::Hash> + AsRef<[u8]>,
{
impl<T: Config> Token<T> for RuntimeToken {
fn weight(&self) -> Weight {
self.weight
}
@@ -463,12 +454,7 @@ pub struct Runtime<'a, E: Ext + 'a> {
chain_extension: Option<Box<<E::T as Config>::ChainExtension>>,
}
impl<'a, E> Runtime<'a, E>
where
E: Ext + 'a,
<E::T as frame_system::Config>::AccountId:
UncheckedFrom<<E::T as frame_system::Config>::Hash> + AsRef<[u8]>,
{
impl<'a, E: Ext + 'a> Runtime<'a, E> {
pub fn new(ext: &'a mut E, input_data: Vec<u8>) -> Self {
Runtime {
ext,