Compare commits

...

2 Commits

Author SHA1 Message Date
Cyrill Leutwiler f985f42370 update polkadot-sdk and inkwell dependencies (#101)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2024-10-29 11:27:44 +01:00
Ermal Kaleci aae25107a2 support full storage key space (#100)
- The storage pointer values will no longer be truncated to the register size, allowing for the use of arbitrary storage keys
- Failed storage value reads will now guarantee to return the zero value
2024-10-28 10:18:11 +01:00
10 changed files with 612 additions and 597 deletions
Generated
+521 -521
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -67,11 +67,12 @@ log = { version = "0.4" }
# polkadot-sdk and friends # polkadot-sdk and friends
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" } codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
scale-info = { version = "2.11.1", default-features = false } scale-info = { version = "2.11.1", default-features = false }
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "aeebf2f383390f2f86527d70212162d5dbea8b93" } polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "35535efb3d9f4d3b3be63c3c2bcf963883ab6af1" }
# llvm # llvm
[workspace.dependencies.inkwell] [workspace.dependencies.inkwell]
version = "0.5" git = "https://github.com/TheDan64/inkwell.git"
rev = "7b410298b6a93450adaa90b1841d5805a3038f12"
default-features = false default-features = false
features = ["serde", "llvm18-0", "no-libffi-linking", "target-riscv"] features = ["serde", "llvm18-0", "no-libffi-linking", "target-riscv"]
+2 -2
View File
@@ -2,9 +2,9 @@
"Baseline": 989, "Baseline": 989,
"Computation": 4153, "Computation": 4153,
"DivisionArithmetics": 40614, "DivisionArithmetics": 40614,
"ERC20": 47343, "ERC20": 47348,
"Events": 1781, "Events": 1781,
"FibonacciIterative": 3035, "FibonacciIterative": 3035,
"Flipper": 3393, "Flipper": 3448,
"SHA1": 33553 "SHA1": 33553
} }
+45 -4
View File
@@ -4,11 +4,27 @@ pragma solidity ^0.8;
/* runner.json /* runner.json
{ {
"differential": true,
"actions": [ "actions": [
{ {
"Instantiate": {} "Upload": {
} "code": {
] "Solidity": {
"contract": "ERC20"
}
}
}
},
{
"Instantiate": {
"code": {
"Solidity": {
"contract": "ERC20Tester"
}
}
}
}
]
} }
*/ */
@@ -82,3 +98,28 @@ contract ERC20 is IERC20 {
emit Transfer(msg.sender, address(0), amount); emit Transfer(msg.sender, address(0), amount);
} }
} }
contract ERC20Tester {
constructor() {
address BOB = address(0xffffffffffffffffffffffffffffffffffffff);
ERC20 token = new ERC20();
assert(token.decimals() == 18);
// use call directly when code_size is implemented on pallet-revive
address(token).call(abi.encodeWithSignature("mint(uint256)", 300));
assert(token.balanceOf(address(this)) == 300);
token.transfer(BOB, 100);
assert(token.balanceOf(address(this)) == 200);
assert(token.balanceOf(BOB) == 100);
token.approve(address(this), 100);
token.transferFrom(address(this), BOB, 100);
assert(token.balanceOf(BOB) == 200);
assert(token.balanceOf(address(this)) == 100);
address(token).call(abi.encodeWithSignature("burn(uint256)", 100));
assert(token.balanceOf(address(this)) == 0);
}
}
+17 -1
View File
@@ -22,6 +22,14 @@ pragma solidity ^0.8;
}, },
"data": "fabc9efaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "data": "fabc9efaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
} }
},
{
"Call": {
"dest": {
"Instantiated": 0
},
"data": "558b9f9bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
}
} }
] ]
} }
@@ -30,10 +38,18 @@ pragma solidity ^0.8;
contract Storage { contract Storage {
function transient(uint value) public returns (uint ret) { function transient(uint value) public returns (uint ret) {
assembly { assembly {
let slot := 123 let slot := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
tstore(slot, value) tstore(slot, value)
let success := call(0, 0, 0, 0, 0, 0, 0) let success := call(0, 0, 0, 0, 0, 0, 0)
ret := tload(slot) ret := tload(slot)
} }
} }
function persistent(uint value) public returns (uint ret) {
assembly {
let slot := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
sstore(slot, value)
ret := sload(slot)
}
}
} }
+4 -30
View File
@@ -669,22 +669,10 @@ where
self.build_byte_swap(value) self.build_byte_swap(value)
} }
AddressSpace::Storage | AddressSpace::TransientStorage => { AddressSpace::Storage | AddressSpace::TransientStorage => {
let storage_key_value = self.builder().build_ptr_to_int(
pointer.value,
self.word_type(),
"storage_ptr_to_int",
)?;
let storage_key_pointer = self.build_alloca(self.word_type(), "storage_key");
let storage_key_pointer_casted = self.builder().build_ptr_to_int(
storage_key_pointer.value,
self.xlen_type(),
"storage_key_pointer_casted",
)?;
self.builder()
.build_store(storage_key_pointer.value, storage_key_value)?;
let storage_value_pointer = let storage_value_pointer =
self.build_alloca(self.word_type(), "storage_value_pointer"); self.build_alloca(self.word_type(), "storage_value_pointer");
self.build_store(storage_value_pointer, self.word_const(0))?;
let storage_value_length_pointer = let storage_value_length_pointer =
self.build_alloca(self.xlen_type(), "storage_value_length_pointer"); self.build_alloca(self.xlen_type(), "storage_value_length_pointer");
self.build_store( self.build_store(
@@ -698,7 +686,7 @@ where
revive_runtime_api::polkavm_imports::GET_STORAGE, revive_runtime_api::polkavm_imports::GET_STORAGE,
&[ &[
self.xlen_type().const_int(transient as u64, false).into(), self.xlen_type().const_int(transient as u64, false).into(),
storage_key_pointer_casted.into(), pointer.to_int(self).into(),
self.xlen_type().const_all_ones().into(), self.xlen_type().const_all_ones().into(),
storage_value_pointer.to_int(self).into(), storage_value_pointer.to_int(self).into(),
storage_value_length_pointer.to_int(self).into(), storage_value_length_pointer.to_int(self).into(),
@@ -767,18 +755,6 @@ where
self.word_type().as_basic_type_enum() self.word_type().as_basic_type_enum()
); );
let storage_key_value = self.builder().build_ptr_to_int(
pointer.value,
self.word_type(),
"storage_ptr_to_int",
)?;
let storage_key_pointer = self.build_alloca(self.word_type(), "storage_key");
let storage_key_pointer_casted = self.builder().build_ptr_to_int(
storage_key_pointer.value,
self.xlen_type(),
"storage_key_pointer_casted",
)?;
let storage_value_pointer = self.build_alloca(self.word_type(), "storage_value"); let storage_value_pointer = self.build_alloca(self.word_type(), "storage_value");
let storage_value_pointer_casted = self.builder().build_ptr_to_int( let storage_value_pointer_casted = self.builder().build_ptr_to_int(
storage_value_pointer.value, storage_value_pointer.value,
@@ -786,8 +762,6 @@ where
"storage_value_pointer_casted", "storage_value_pointer_casted",
)?; )?;
self.builder()
.build_store(storage_key_pointer.value, storage_key_value)?;
self.builder() self.builder()
.build_store(storage_value_pointer.value, value)?; .build_store(storage_value_pointer.value, value)?;
@@ -797,7 +771,7 @@ where
revive_runtime_api::polkavm_imports::SET_STORAGE, revive_runtime_api::polkavm_imports::SET_STORAGE,
&[ &[
self.xlen_type().const_int(transient as u64, false).into(), self.xlen_type().const_int(transient as u64, false).into(),
storage_key_pointer_casted.into(), pointer.to_int(self).into(),
self.xlen_type().const_all_ones().into(), self.xlen_type().const_all_ones().into(),
storage_value_pointer_casted.into(), storage_value_pointer_casted.into(),
self.integer_const(crate::polkavm::XLEN, 32).into(), self.integer_const(crate::polkavm::XLEN, 32).into(),
+16 -33
View File
@@ -1,7 +1,6 @@
//! Translates the storage operations. //! Translates the storage operations.
use crate::polkavm::context::address_space::AddressSpace; use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::pointer::Pointer;
use crate::polkavm::context::Context; use crate::polkavm::context::Context;
use crate::polkavm::Dependency; use crate::polkavm::Dependency;
@@ -13,14 +12,10 @@ pub fn load<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let position_pointer = Pointer::new_with_offset( let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
context, slot_ptr.address_space = AddressSpace::Storage;
AddressSpace::Storage, context.builder().build_store(slot_ptr.value, position)?;
context.word_type(), context.build_load(slot_ptr, "storage_load_value")
position,
"storage_load_position_pointer",
);
context.build_load(position_pointer, "storage_load_value")
} }
/// Translates the storage store. /// Translates the storage store.
@@ -32,14 +27,10 @@ pub fn store<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let position_pointer = Pointer::new_with_offset( let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
context, slot_ptr.address_space = AddressSpace::Storage;
AddressSpace::Storage, context.builder().build_store(slot_ptr.value, position)?;
context.word_type(), context.build_store(slot_ptr, value)?;
position,
"storage_store_position_pointer",
);
context.build_store(position_pointer, value)?;
Ok(()) Ok(())
} }
@@ -51,14 +42,10 @@ pub fn transient_load<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let position_pointer = Pointer::new_with_offset( let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
context, slot_ptr.address_space = AddressSpace::TransientStorage;
AddressSpace::TransientStorage, context.builder().build_store(slot_ptr.value, position)?;
context.word_type(), context.build_load(slot_ptr, "transient_storage_load_value")
position,
"transient_storage_load_position_pointer",
);
context.build_load(position_pointer, "transient_storage_load_value")
} }
/// Translates the transient storage store. /// Translates the transient storage store.
@@ -70,13 +57,9 @@ pub fn transient_store<'ctx, D>(
where where
D: Dependency + Clone, D: Dependency + Clone,
{ {
let position_pointer = Pointer::new_with_offset( let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
context, slot_ptr.address_space = AddressSpace::TransientStorage;
AddressSpace::TransientStorage, context.builder().build_store(slot_ptr.value, position)?;
context.word_type(), context.build_store(slot_ptr, value)?;
position,
"transient_storage_store_position_pointer",
);
context.build_store(position_pointer, value)?;
Ok(()) Ok(())
} }
+1 -1
View File
@@ -72,7 +72,7 @@ impl ExtBuilder {
Self { Self {
balance_genesis_config: value balance_genesis_config: value
.iter() .iter()
.map(|(address, balance)| (AccountId::to_account_id(address), *balance)) .map(|(address, balance)| (AccountId::to_fallback_account_id(address), *balance))
.collect(), .collect(),
} }
} }
+3 -2
View File
@@ -1,5 +1,6 @@
use frame_support::runtime; use frame_support::runtime;
use pallet_revive::AccountId32Mapper;
use polkadot_sdk::*; use polkadot_sdk::*;
use polkadot_sdk::{ use polkadot_sdk::{
polkadot_sdk_frame::{log, runtime::prelude::*}, polkadot_sdk_frame::{log, runtime::prelude::*},
@@ -7,7 +8,7 @@ use polkadot_sdk::{
}; };
pub type Balance = u128; pub type Balance = u128;
pub type AccountId = pallet_revive::DefaultAddressMapper; pub type AccountId = pallet_revive::AccountId32Mapper<Runtime>;
pub type Block = frame_system::mocking::MockBlock<Runtime>; pub type Block = frame_system::mocking::MockBlock<Runtime>;
pub type Hash = <Runtime as frame_system::Config>::Hash; pub type Hash = <Runtime as frame_system::Config>::Hash;
pub type EventRecord = pub type EventRecord =
@@ -74,7 +75,7 @@ impl pallet_revive::Config for Runtime {
type ChainExtension = (); type ChainExtension = ();
type DepositPerByte = DepositPerByte; type DepositPerByte = DepositPerByte;
type DepositPerItem = DepositPerItem; type DepositPerItem = DepositPerItem;
type AddressMapper = AccountId; type AddressMapper = AccountId32Mapper<Self>;
type RuntimeMemory = ConstU32<{ 512 * 1024 * 1024 }>; type RuntimeMemory = ConstU32<{ 512 * 1024 * 1024 }>;
type PVFMemory = ConstU32<{ 1024 * 1024 * 1024 }>; type PVFMemory = ConstU32<{ 1024 * 1024 * 1024 }>;
type UnsafeUnstableInterface = UnstableInterface; type UnsafeUnstableInterface = UnstableInterface;
-1
View File
@@ -1,6 +1,5 @@
use std::time::Instant; use std::time::Instant;
use pallet_revive::AddressMapper;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::*; use crate::*;