Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions prdoc/pr_10193.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
title: '[v2] pallet-revive: support uploading EVM bytecode via upload_code'
doc:
- audience: Runtime Dev
description: |-
Fixes https://github.com/paritytech/contract-issues/issues/182

Add support for EVM bytecode to the upload_code extrinsic.
Tests in issue https://github.com/paritytech/contract-issues/issues/182 send hardhat_setCode, which uses revive's upload_code API; this change makes that flow accept and store the EVM bytecode using upload_code extrinsic.

This PR deprecates PR: https://github.com/paritytech/polkadot-sdk/pull/10095

Comment explaining test configuration requirements: https://github.com/paritytech/polkadot-sdk/pull/10095#issuecomment-3456450460
crates:
- name: pallet-revive
bump: patch
12 changes: 11 additions & 1 deletion substrate/frame/revive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1990,10 +1990,20 @@ impl<T: Config> Pallet<T> {
storage_deposit_limit: BalanceOf<T>,
) -> CodeUploadResult<BalanceOf<T>> {
let origin = T::UploadOrigin::ensure_origin(origin)?;

let bytecode_type = if code.starts_with(&polkavm_common::program::BLOB_MAGIC) {
BytecodeType::Pvm
} else {
if !T::AllowEVMBytecode::get() {
return Err(<Error<T>>::CodeRejected.into())
}
BytecodeType::Evm
};

let (module, deposit) = Self::try_upload_code(
origin,
code,
BytecodeType::Pvm,
bytecode_type,
storage_deposit_limit,
&ExecConfig::new_substrate_tx(),
)?;
Expand Down
53 changes: 50 additions & 3 deletions substrate/frame/revive/src/tests/sol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use crate::{
tests::{
builder,
test_utils::{contract_base_deposit, ensure_stored, get_contract},
DebugFlag, ExtBuilder, Test,
AllowEvmBytecode, DebugFlag, ExtBuilder, RuntimeOrigin, Test,
},
Code, Config, Error, GenesisConfig, PristineCode,
Code, Config, Error, GenesisConfig, Pallet, PristineCode,
};
use alloy_core::sol_types::{SolCall, SolInterface};
use frame_support::{assert_err, assert_ok, traits::fungible::Mutate};
Expand Down Expand Up @@ -205,7 +205,6 @@ fn upload_evm_runtime_code_works() {
exec::Executable,
primitives::ExecConfig,
storage::{AccountInfo, ContractInfo},
Pallet,
};

let (runtime_code, _runtime_hash) =
Expand Down Expand Up @@ -240,3 +239,51 @@ fn upload_evm_runtime_code_works() {
assert_eq!(55u64, decoded, "Contract should correctly compute fibonacci(10)");
});
}

#[test]
fn upload_and_remove_code_works_for_evm() {
use crate::tests::{initialize_block, test_utils::expected_deposit};

let storage_deposit_limit = 1000u64;
let (code, code_hash) = compile_module_with_type("dummy", FixtureType::Solc).unwrap();

ExtBuilder::default().build().execute_with(|| {
let deployer_addr = ALICE_ADDR;
let amount = 5_000_000_000u64;
let _ = Pallet::<Test>::set_evm_balance(&deployer_addr, amount.into());

// Drop previous events
initialize_block(2);

// Ensure the code is not already stored.
assert!(!PristineCode::<Test>::contains_key(&code_hash));

// Upload the code.
assert_ok!(Pallet::<Test>::upload_code(
RuntimeOrigin::signed(ALICE),
code,
storage_deposit_limit
));

// Ensure the contract was stored and get expected deposit amount to be reserved.
expected_deposit(ensure_stored(code_hash));

// Now remove the code.
assert_ok!(Pallet::<Test>::remove_code(RuntimeOrigin::signed(ALICE), code_hash));
});
}

#[test]
fn upload_fails_if_evm_bytecode_disabled() {
let storage_deposit_limit = 1000u64;
let (code, _) = compile_module_with_type("dummy", FixtureType::Solc).unwrap();

AllowEvmBytecode::set(false); // Disable support for EVM bytecode.
ExtBuilder::default().build().execute_with(|| {
// Upload should fail since support for EVM bytecode is disabled.
assert_err!(
Pallet::<Test>::upload_code(RuntimeOrigin::signed(ALICE), code, storage_deposit_limit),
<Error<Test>>::CodeRejected
);
});
}
Loading