mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 22:41:07 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 36d9317831 | |||
| 5b3b90db83 | |||
| a4043ecde7 | |||
| f985f42370 | |||
| aae25107a2 |
Generated
+589
-570
File diff suppressed because it is too large
Load Diff
+7
-6
@@ -51,10 +51,10 @@ path-slash = "0.2"
|
||||
rayon = "1.8"
|
||||
clap = { version = "4", default-features = false, features = ["derive"] }
|
||||
rand = "0.8"
|
||||
polkavm-common = "0.13"
|
||||
polkavm-linker = "0.13"
|
||||
polkavm-disassembler = "0.13"
|
||||
polkavm = "0.13"
|
||||
polkavm-common = "0.14"
|
||||
polkavm-linker = "0.14"
|
||||
polkavm-disassembler = "0.14"
|
||||
polkavm = "0.14"
|
||||
alloy-primitives = { version = "0.8", features = ["serde"] }
|
||||
alloy-sol-types = "0.8"
|
||||
alloy-genesis = "0.3"
|
||||
@@ -67,11 +67,12 @@ log = { version = "0.4" }
|
||||
# polkadot-sdk and friends
|
||||
codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" }
|
||||
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 = "db40a66db71e8e7fe943dda5cd0e28078efa2a19" }
|
||||
|
||||
# llvm
|
||||
[workspace.dependencies.inkwell]
|
||||
version = "0.5"
|
||||
git = "https://github.com/TheDan64/inkwell.git"
|
||||
rev = "7b410298b6a93450adaa90b1841d5805a3038f12"
|
||||
default-features = false
|
||||
features = ["serde", "llvm18-0", "no-libffi-linking", "target-riscv"]
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"Baseline": 989,
|
||||
"Computation": 4153,
|
||||
"DivisionArithmetics": 40614,
|
||||
"ERC20": 47343,
|
||||
"Events": 1781,
|
||||
"FibonacciIterative": 3035,
|
||||
"Flipper": 3393,
|
||||
"SHA1": 33553
|
||||
"Baseline": 967,
|
||||
"Computation": 4022,
|
||||
"DivisionArithmetics": 31787,
|
||||
"ERC20": 44233,
|
||||
"Events": 1743,
|
||||
"FibonacciIterative": 2927,
|
||||
"Flipper": 3408,
|
||||
"SHA1": 26009
|
||||
}
|
||||
@@ -4,9 +4,25 @@ pragma solidity ^0.8;
|
||||
|
||||
/* runner.json
|
||||
{
|
||||
"differential": true,
|
||||
"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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,14 @@ pragma solidity ^0.8;
|
||||
},
|
||||
"data": "fabc9efaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Call": {
|
||||
"dest": {
|
||||
"Instantiated": 0
|
||||
},
|
||||
"data": "558b9f9bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -30,10 +38,18 @@ pragma solidity ^0.8;
|
||||
contract Storage {
|
||||
function transient(uint value) public returns (uint ret) {
|
||||
assembly {
|
||||
let slot := 123
|
||||
let slot := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
|
||||
tstore(slot, value)
|
||||
let success := call(0, 0, 0, 0, 0, 0, 0)
|
||||
ret := tload(slot)
|
||||
}
|
||||
}
|
||||
|
||||
function persistent(uint value) public returns (uint ret) {
|
||||
assembly {
|
||||
let slot := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
|
||||
sstore(slot, value)
|
||||
ret := sload(slot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/* runner.json
|
||||
{
|
||||
"differential": true,
|
||||
"actions": [
|
||||
{
|
||||
"Upload": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "TransactionOrigin"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Instantiate": {
|
||||
"code": {
|
||||
"Solidity": {
|
||||
"contract": "TransactionTester"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Call": {
|
||||
"dest": {
|
||||
"Instantiated": 0
|
||||
},
|
||||
"data": "f8a8fd6d"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
|
||||
contract TransactionTester {
|
||||
constructor() payable {
|
||||
assert(tx.origin == new TransactionOrigin().test());
|
||||
}
|
||||
|
||||
function test() public payable returns (address ret) {
|
||||
ret = tx.origin;
|
||||
}
|
||||
}
|
||||
|
||||
contract TransactionOrigin {
|
||||
function test() public payable returns (address ret) {
|
||||
assert(msg.sender != tx.origin);
|
||||
|
||||
ret = tx.origin;
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ test_spec!(call, "Caller", "Call.sol");
|
||||
test_spec!(transfer, "Transfer", "Transfer.sol");
|
||||
test_spec!(return_data_oob, "ReturnDataOob", "ReturnDataOob.sol");
|
||||
test_spec!(immutables, "Immutables", "Immutables.sol");
|
||||
test_spec!(transaction, "Transaction", "Transaction.sol");
|
||||
|
||||
fn instantiate(path: &str, contract: &str) -> Vec<SpecsAction> {
|
||||
vec![Instantiate {
|
||||
|
||||
@@ -669,22 +669,10 @@ where
|
||||
self.build_byte_swap(value)
|
||||
}
|
||||
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 =
|
||||
self.build_alloca(self.word_type(), "storage_value_pointer");
|
||||
self.build_store(storage_value_pointer, self.word_const(0))?;
|
||||
|
||||
let storage_value_length_pointer =
|
||||
self.build_alloca(self.xlen_type(), "storage_value_length_pointer");
|
||||
self.build_store(
|
||||
@@ -698,7 +686,7 @@ where
|
||||
revive_runtime_api::polkavm_imports::GET_STORAGE,
|
||||
&[
|
||||
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(),
|
||||
storage_value_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()
|
||||
);
|
||||
|
||||
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_casted = self.builder().build_ptr_to_int(
|
||||
storage_value_pointer.value,
|
||||
@@ -786,8 +762,6 @@ where
|
||||
"storage_value_pointer_casted",
|
||||
)?;
|
||||
|
||||
self.builder()
|
||||
.build_store(storage_key_pointer.value, storage_key_value)?;
|
||||
self.builder()
|
||||
.build_store(storage_value_pointer.value, value)?;
|
||||
|
||||
@@ -797,7 +771,7 @@ where
|
||||
revive_runtime_api::polkavm_imports::SET_STORAGE,
|
||||
&[
|
||||
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(),
|
||||
storage_value_pointer_casted.into(),
|
||||
self.integer_const(crate::polkavm::XLEN, 32).into(),
|
||||
|
||||
@@ -27,12 +27,19 @@ where
|
||||
|
||||
/// Translates the `tx.origin` instruction.
|
||||
pub fn origin<'ctx, D>(
|
||||
_context: &mut Context<'ctx, D>,
|
||||
context: &mut Context<'ctx, D>,
|
||||
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
||||
where
|
||||
D: Dependency + Clone,
|
||||
{
|
||||
todo!()
|
||||
let address_type = context.integer_type(revive_common::BIT_LENGTH_ETH_ADDRESS);
|
||||
let address_pointer = context.build_alloca_at_entry(address_type, "origin_address");
|
||||
context.build_store(address_pointer, address_type.const_zero())?;
|
||||
context.build_runtime_call(
|
||||
revive_runtime_api::polkavm_imports::ORIGIN,
|
||||
&[address_pointer.to_int(context).into()],
|
||||
);
|
||||
context.build_load_address(address_pointer)
|
||||
}
|
||||
|
||||
/// Translates the `chain_id` instruction.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//! Translates the storage operations.
|
||||
|
||||
use crate::polkavm::context::address_space::AddressSpace;
|
||||
use crate::polkavm::context::pointer::Pointer;
|
||||
use crate::polkavm::context::Context;
|
||||
use crate::polkavm::Dependency;
|
||||
|
||||
@@ -13,14 +12,10 @@ pub fn load<'ctx, D>(
|
||||
where
|
||||
D: Dependency + Clone,
|
||||
{
|
||||
let position_pointer = Pointer::new_with_offset(
|
||||
context,
|
||||
AddressSpace::Storage,
|
||||
context.word_type(),
|
||||
position,
|
||||
"storage_load_position_pointer",
|
||||
);
|
||||
context.build_load(position_pointer, "storage_load_value")
|
||||
let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
|
||||
slot_ptr.address_space = AddressSpace::Storage;
|
||||
context.builder().build_store(slot_ptr.value, position)?;
|
||||
context.build_load(slot_ptr, "storage_load_value")
|
||||
}
|
||||
|
||||
/// Translates the storage store.
|
||||
@@ -32,14 +27,10 @@ pub fn store<'ctx, D>(
|
||||
where
|
||||
D: Dependency + Clone,
|
||||
{
|
||||
let position_pointer = Pointer::new_with_offset(
|
||||
context,
|
||||
AddressSpace::Storage,
|
||||
context.word_type(),
|
||||
position,
|
||||
"storage_store_position_pointer",
|
||||
);
|
||||
context.build_store(position_pointer, value)?;
|
||||
let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
|
||||
slot_ptr.address_space = AddressSpace::Storage;
|
||||
context.builder().build_store(slot_ptr.value, position)?;
|
||||
context.build_store(slot_ptr, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -51,14 +42,10 @@ pub fn transient_load<'ctx, D>(
|
||||
where
|
||||
D: Dependency + Clone,
|
||||
{
|
||||
let position_pointer = Pointer::new_with_offset(
|
||||
context,
|
||||
AddressSpace::TransientStorage,
|
||||
context.word_type(),
|
||||
position,
|
||||
"transient_storage_load_position_pointer",
|
||||
);
|
||||
context.build_load(position_pointer, "transient_storage_load_value")
|
||||
let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
|
||||
slot_ptr.address_space = AddressSpace::TransientStorage;
|
||||
context.builder().build_store(slot_ptr.value, position)?;
|
||||
context.build_load(slot_ptr, "transient_storage_load_value")
|
||||
}
|
||||
|
||||
/// Translates the transient storage store.
|
||||
@@ -70,13 +57,9 @@ pub fn transient_store<'ctx, D>(
|
||||
where
|
||||
D: Dependency + Clone,
|
||||
{
|
||||
let position_pointer = Pointer::new_with_offset(
|
||||
context,
|
||||
AddressSpace::TransientStorage,
|
||||
context.word_type(),
|
||||
position,
|
||||
"transient_storage_store_position_pointer",
|
||||
);
|
||||
context.build_store(position_pointer, value)?;
|
||||
let mut slot_ptr = context.build_alloca_at_entry(context.word_type(), "slot_pointer");
|
||||
slot_ptr.address_space = AddressSpace::TransientStorage;
|
||||
context.builder().build_store(slot_ptr.value, position)?;
|
||||
context.build_store(slot_ptr, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ impl TargetMachine {
|
||||
|
||||
/// LLVM target features.
|
||||
#[cfg(feature = "riscv-zbb")]
|
||||
pub const VM_FEATURES: &'static str = "+zbb,+e,+m,+c";
|
||||
pub const VM_FEATURES: &'static str = "+zbb,+a,+e,+m,+c,+fast-unaligned-access,+xtheadcondmov";
|
||||
#[cfg(not(feature = "riscv-zbb"))]
|
||||
pub const VM_FEATURES: &'static str = "+e,+m,+c";
|
||||
pub const VM_FEATURES: &'static str = "+a,+e,+m,+c,+fast-unaligned-access,+xtheadcondmov";
|
||||
|
||||
/// A shortcut constructor.
|
||||
/// A separate instance for every optimization level is created.
|
||||
|
||||
@@ -72,7 +72,7 @@ impl ExtBuilder {
|
||||
Self {
|
||||
balance_genesis_config: value
|
||||
.iter()
|
||||
.map(|(address, balance)| (AccountId::to_account_id(address), *balance))
|
||||
.map(|(address, balance)| (AccountId::to_fallback_account_id(address), *balance))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@ pub enum Code {
|
||||
/// A contract blob
|
||||
Bytes(Vec<u8>),
|
||||
/// Pre-existing contract hash
|
||||
Hash(Hash),
|
||||
Hash(crate::runtime::Hash),
|
||||
}
|
||||
|
||||
impl Default for Code {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use frame_support::runtime;
|
||||
|
||||
use pallet_revive::AccountId32Mapper;
|
||||
use polkadot_sdk::*;
|
||||
use polkadot_sdk::{
|
||||
polkadot_sdk_frame::{log, runtime::prelude::*},
|
||||
@@ -7,7 +8,7 @@ use polkadot_sdk::{
|
||||
};
|
||||
|
||||
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 Hash = <Runtime as frame_system::Config>::Hash;
|
||||
pub type EventRecord =
|
||||
@@ -74,7 +75,7 @@ impl pallet_revive::Config for Runtime {
|
||||
type ChainExtension = ();
|
||||
type DepositPerByte = DepositPerByte;
|
||||
type DepositPerItem = DepositPerItem;
|
||||
type AddressMapper = AccountId;
|
||||
type AddressMapper = AccountId32Mapper<Self>;
|
||||
type RuntimeMemory = ConstU32<{ 512 * 1024 * 1024 }>;
|
||||
type PVFMemory = ConstU32<{ 1024 * 1024 * 1024 }>;
|
||||
type UnsafeUnstableInterface = UnstableInterface;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::time::Instant;
|
||||
|
||||
use pallet_revive::AddressMapper;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::*;
|
||||
|
||||
@@ -96,6 +96,8 @@ POLKAVM_IMPORT(uint32_t, instantiate, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, now, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, origin, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(void, seal_return, uint32_t, uint32_t, uint32_t)
|
||||
|
||||
POLKAVM_IMPORT(uint32_t, set_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)
|
||||
|
||||
@@ -46,6 +46,8 @@ pub static INSTANTIATE: &str = "instantiate";
|
||||
|
||||
pub static NOW: &str = "now";
|
||||
|
||||
pub static ORIGIN: &str = "origin";
|
||||
|
||||
pub static RETURN: &str = "seal_return";
|
||||
|
||||
pub static SET_STORAGE: &str = "set_storage";
|
||||
@@ -60,7 +62,7 @@ pub static VALUE_TRANSFERRED: &str = "value_transferred";
|
||||
|
||||
/// All imported runtime API symbols.
|
||||
/// Useful for configuring common attributes and linkage.
|
||||
pub static IMPORTS: [&str; 24] = [
|
||||
pub static IMPORTS: [&str; 25] = [
|
||||
SBRK,
|
||||
MEMORY_SIZE,
|
||||
ADDRESS,
|
||||
@@ -79,6 +81,7 @@ pub static IMPORTS: [&str; 24] = [
|
||||
INPUT,
|
||||
INSTANTIATE,
|
||||
NOW,
|
||||
ORIGIN,
|
||||
RETURN,
|
||||
RETURNDATACOPY,
|
||||
RETURNDATASIZE,
|
||||
|
||||
Reference in New Issue
Block a user