Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 10 additions & 0 deletions prdoc/pr_9801.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
title: '[pallet-revive] allow changing immutables'
doc:
- audience: Runtime Dev
description: |-
Adds pallet revive methods for reading and setting immutables data of a contract.

Fixes: https://github.com/paritytech/foundry-polkadot/issues/277
crates:
- name: pallet-revive
bump: major
21 changes: 21 additions & 0 deletions substrate/frame/revive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,27 @@ where
Ok(maybe_value)
}

/// Get the immutable data of a specified contract.
///
/// Returns `None` if the contract does not exist or has no immutable data.
pub fn get_immutables(address: H160) -> Option<ImmutableData> {
let immutable_data = <ImmutableDataOf<T>>::get(address);
immutable_data
}

/// Sets immutable data of a contract
///
/// Returns an error if the contract does not exist.
///
/// # Warning
///
/// Does not collect any storage deposit. Not safe to be called by user controlled code.
Comment on lines +1696 to +1698
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should reflect that in the method's name too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any suggestion on how you want me to prefix/suffix it ?

pub fn set_immutables(address: H160, data: ImmutableData) -> Result<(), ContractAccessError> {
AccountInfo::<T>::load_contract(&address).ok_or(ContractAccessError::DoesntExist)?;
<ImmutableDataOf<T>>::insert(address, data);
Ok(())
}

/// Query storage of a specified contract under a specified variable-sized key.
pub fn get_storage_var_key(address: H160, key: Vec<u8>) -> GetStorageResult {
let contract_info =
Expand Down
26 changes: 25 additions & 1 deletion substrate/frame/revive/src/tests/pvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use pallet_revive_uapi::{ReturnErrorCode as RuntimeReturnCode, ReturnFlags};
use pretty_assertions::{assert_eq, assert_ne};
use sp_core::{Get, U256};
use sp_io::hashing::blake2_256;
use sp_runtime::{testing::H256, traits::Zero, AccountId32, DispatchError, TokenError};
use sp_runtime::{testing::H256, traits::Zero, AccountId32, BoundedVec, DispatchError, TokenError};

#[test]
fn transfer_with_dust_works() {
Expand Down Expand Up @@ -5148,3 +5148,27 @@ fn get_set_storage_var_key_works() {
assert_eq!(storage_value, new_value_to_write);
});
}

#[test]
fn get_set_immutables_works() {
let (code, _code_hash) = compile_module("immutable_data").unwrap();

ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
let _ = <Test as Config>::Currency::set_balance(&ALICE, 1_000_000);
let data = [0xfe; 8];

let Contract { addr, .. } = builder::bare_instantiate(Code::Upload(code))
.data(data.to_vec())
.build_and_unwrap_contract();

// Checking non-existing keys gets created.
let immutable_data = Pallet::<Test>::get_immutables(addr).unwrap();
assert_eq!(immutable_data, data.to_vec());

let new_data = [0xdeu8; 8].to_vec();

Pallet::<Test>::set_immutables(addr, BoundedVec::truncate_from(new_data.clone())).unwrap();
let immutable_data = Pallet::<Test>::get_immutables(addr).unwrap();
assert_eq!(immutable_data, new_data);
});
}
Loading