Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 6d28d2e

Browse files
coderobepgherveou
andauthored
Contracts add code_len to ContractsInfo (#14523) (#14580)
* add code_len to v12 * fix * Update frame/contracts/src/wasm/mod.rs * fix * fixes * rm test * add test back * fix * update test * Fix comments * fix build * del * fix clippy * fix * re-rename Co-authored-by: PG Herveou <[email protected]>
1 parent 2b76b44 commit 6d28d2e

File tree

5 files changed

+54
-24
lines changed

5 files changed

+54
-24
lines changed

frame/contracts/src/migration/v12.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub struct CodeInfo<T: Config> {
8080
#[codec(compact)]
8181
refcount: u64,
8282
determinism: Determinism,
83+
code_len: u32,
8384
}
8485

8586
#[storage_alias]
@@ -177,6 +178,7 @@ impl<T: Config> MigrationStep for Migration<T> {
177178
owner: old_info.owner,
178179
deposit,
179180
refcount: old_info.refcount,
181+
code_len: code_len as u32,
180182
};
181183

182184
let amount = old_info.deposit.saturating_sub(info.deposit);
@@ -221,6 +223,7 @@ impl<T: Config> MigrationStep for Migration<T> {
221223
deposit: v.deposit,
222224
refcount: v.refcount,
223225
owner: v.owner,
226+
code_len: module.code.len() as u32,
224227
};
225228
(k, info)
226229
})

frame/contracts/src/tests.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// This file is part of Substrate.
2+
mod pallet_dummy;
23

34
// Copyright (C) Parity Technologies (UK) Ltd.
45
// SPDX-License-Identifier: Apache-2.0
@@ -72,6 +73,7 @@ frame_support::construct_runtime!(
7273
Utility: pallet_utility::{Pallet, Call, Storage, Event},
7374
Contracts: pallet_contracts::{Pallet, Call, Storage, Event<T>},
7475
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>},
76+
Dummy: pallet_dummy
7577
}
7678
);
7779

@@ -378,6 +380,8 @@ impl pallet_proxy::Config for Test {
378380
type AnnouncementDepositFactor = ConstU64<1>;
379381
}
380382

383+
impl pallet_dummy::Config for Test {}
384+
381385
parameter_types! {
382386
pub MySchedule: Schedule<Test> = {
383387
let schedule = <Schedule<Test>>::default();
@@ -3004,7 +3008,7 @@ fn gas_estimation_call_runtime() {
30043008
.unwrap()
30053009
.account_id;
30063010

3007-
let addr_callee = Contracts::bare_instantiate(
3011+
Contracts::bare_instantiate(
30083012
ALICE,
30093013
min_balance * 100,
30103014
GAS_LIMIT,
@@ -3016,15 +3020,11 @@ fn gas_estimation_call_runtime() {
30163020
CollectEvents::Skip,
30173021
)
30183022
.result
3019-
.unwrap()
3020-
.account_id;
3023+
.unwrap();
30213024

30223025
// Call something trivial with a huge gas limit so that we can observe the effects
30233026
// of pre-charging. This should create a difference between consumed and required.
3024-
let call = RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death {
3025-
dest: addr_callee,
3026-
value: min_balance * 10,
3027-
});
3027+
let call = RuntimeCall::Dummy(pallet_dummy::Call::overestimate_pre_charge {});
30283028
let result = Contracts::bare_call(
30293029
ALICE,
30303030
addr_caller.clone(),
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
pub use pallet::*;
2+
3+
#[frame_support::pallet(dev_mode)]
4+
pub mod pallet {
5+
use frame_support::{
6+
dispatch::{Pays, PostDispatchInfo},
7+
pallet_prelude::DispatchResultWithPostInfo,
8+
weights::Weight,
9+
};
10+
use frame_system::pallet_prelude::*;
11+
12+
#[pallet::pallet]
13+
pub struct Pallet<T>(_);
14+
15+
#[pallet::config]
16+
pub trait Config: frame_system::Config {}
17+
18+
#[pallet::call]
19+
impl<T: Config> Pallet<T> {
20+
/// Dummy function that overcharges the predispatch weight, allowing us to test the correct
21+
/// values of [`ContractResult::gas_consumed`] and [`ContractResult::gas_required`] in
22+
/// tests.
23+
#[pallet::call_index(1)]
24+
#[pallet::weight(Weight::from_parts(10_000_000, 0))]
25+
pub fn overestimate_pre_charge(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
26+
ensure_signed(origin)?;
27+
Ok(PostDispatchInfo {
28+
actual_weight: Some(Weight::from_parts(100, 0)),
29+
pays_fee: Pays::Yes,
30+
})
31+
}
32+
}
33+
}

frame/contracts/src/wasm/mod.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ pub struct CodeInfo<T: Config> {
9292
/// to be run on-chain. Specifically, such a code can never be instantiated into a contract
9393
/// and can just be used through a delegate call.
9494
determinism: Determinism,
95+
/// length of the code in bytes.
96+
code_len: u32,
9597
}
9698

9799
/// Defines the required determinism level of a wasm blob when either running or uploading code.
@@ -268,15 +270,11 @@ impl<T: Config> WasmBlob<T> {
268270
fn load_code(
269271
code_hash: CodeHash<T>,
270272
gas_meter: &mut GasMeter<T>,
271-
) -> Result<CodeVec<T>, DispatchError> {
272-
let max_code_len = T::MaxCodeLen::get();
273-
let charged = gas_meter.charge(CodeLoadToken(max_code_len))?;
274-
273+
) -> Result<(CodeVec<T>, CodeInfo<T>), DispatchError> {
274+
let code_info = <CodeInfoOf<T>>::get(code_hash).ok_or(Error::<T>::CodeNotFound)?;
275+
gas_meter.charge(CodeLoadToken(code_info.code_len))?;
275276
let code = <PristineCode<T>>::get(code_hash).ok_or(Error::<T>::CodeNotFound)?;
276-
let code_len = code.len() as u32;
277-
gas_meter.adjust_gas(charged, CodeLoadToken(code_len));
278-
279-
Ok(code)
277+
Ok((code, code_info))
280278
}
281279

282280
/// Create the module without checking the passed code.
@@ -309,13 +307,7 @@ impl<T: Config> Executable<T> for WasmBlob<T> {
309307
code_hash: CodeHash<T>,
310308
gas_meter: &mut GasMeter<T>,
311309
) -> Result<Self, DispatchError> {
312-
let code = Self::load_code(code_hash, gas_meter)?;
313-
// We store `code_info` at the same time as contract code,
314-
// therefore this query shouldn't really fail.
315-
// We consider its failure equal to `CodeNotFound`, as contract code without
316-
// `code_info` is unusable in this pallet.
317-
let code_info = <CodeInfoOf<T>>::get(code_hash).ok_or(Error::<T>::CodeNotFound)?;
318-
310+
let (code, code_info) = Self::load_code(code_hash, gas_meter)?;
319311
Ok(Self { code, code_info, code_hash })
320312
}
321313

frame/contracts/src/wasm/prepare.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,12 @@ where
286286
validate::<E, T>(code.as_ref(), schedule, determinism)?;
287287

288288
// Calculate deposit for storing contract code and `code_info` in two different storage items.
289-
let bytes_added = code.len().saturating_add(<CodeInfo<T>>::max_encoded_len()) as u32;
289+
let code_len = code.len() as u32;
290+
let bytes_added = code_len.saturating_add(<CodeInfo<T>>::max_encoded_len() as u32);
290291
let deposit = Diff { bytes_added, items_added: 2, ..Default::default() }
291292
.update_contract::<T>(None)
292293
.charge_or_zero();
293-
let code_info = CodeInfo { owner, deposit, determinism, refcount: 0 };
294+
let code_info = CodeInfo { owner, deposit, determinism, refcount: 0, code_len };
294295
let code_hash = T::Hashing::hash(&code);
295296

296297
Ok(WasmBlob { code, code_info, code_hash })
@@ -320,6 +321,7 @@ pub mod benchmarking {
320321
// this is a helper function for benchmarking which skips deposit collection
321322
deposit: Default::default(),
322323
refcount: 0,
324+
code_len: code.len() as u32,
323325
determinism,
324326
};
325327
let code_hash = T::Hashing::hash(&code);

0 commit comments

Comments
 (0)