mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-20 20:41:00 +00:00
Allow arbitrary call data size (#135)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
Generated
+925
-1515
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -52,7 +52,7 @@ rayon = "1.8"
|
|||||||
clap = { version = "4", default-features = false, features = ["derive"] }
|
clap = { version = "4", default-features = false, features = ["derive"] }
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
polkavm-common = "0.17"
|
polkavm-common = "0.17"
|
||||||
polkavm-linker = "0.17"
|
polkavm-linker = "0.17.1"
|
||||||
polkavm-disassembler = "0.17"
|
polkavm-disassembler = "0.17"
|
||||||
polkavm = "0.17"
|
polkavm = "0.17"
|
||||||
alloy-primitives = { version = "0.8", features = ["serde"] }
|
alloy-primitives = { version = "0.8", features = ["serde"] }
|
||||||
@@ -68,7 +68,7 @@ git2 = "0.19.0"
|
|||||||
# 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 = "447902eff4a574e66894ad60cb41999b05bf5e84" }
|
polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk", rev = "4a0e3f624f42816cb4ca687d3ff9bba8e1a6bf19" }
|
||||||
|
|
||||||
# llvm
|
# llvm
|
||||||
[workspace.dependencies.inkwell]
|
[workspace.dependencies.inkwell]
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"Baseline": 1073,
|
"Baseline": 1126,
|
||||||
"Computation": 2469,
|
"Computation": 2405,
|
||||||
"DivisionArithmetics": 15041,
|
"DivisionArithmetics": 14486,
|
||||||
"ERC20": 23282,
|
"ERC20": 22755,
|
||||||
"Events": 1615,
|
"Events": 1620,
|
||||||
"FibonacciIterative": 1676,
|
"FibonacciIterative": 1670,
|
||||||
"Flipper": 2378,
|
"Flipper": 2005,
|
||||||
"SHA1": 17076
|
"SHA1": 16832
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,6 @@ pub static XLEN: usize = revive_common::BIT_LENGTH_X32;
|
|||||||
/// The heap memory pointer pointer global variable name.
|
/// The heap memory pointer pointer global variable name.
|
||||||
pub static GLOBAL_HEAP_MEMORY_POINTER: &str = "memory_pointer";
|
pub static GLOBAL_HEAP_MEMORY_POINTER: &str = "memory_pointer";
|
||||||
|
|
||||||
/// The calldata pointer global variable name.
|
|
||||||
pub static GLOBAL_CALLDATA_POINTER: &str = "ptr_calldata";
|
|
||||||
|
|
||||||
/// The calldata size global variable name.
|
/// The calldata size global variable name.
|
||||||
pub static GLOBAL_CALLDATA_SIZE: &str = "calldatasize";
|
pub static GLOBAL_CALLDATA_SIZE: &str = "calldatasize";
|
||||||
|
|
||||||
|
|||||||
@@ -18,23 +18,12 @@ impl Entry {
|
|||||||
/// The call flags argument index.
|
/// The call flags argument index.
|
||||||
pub const ARGUMENT_INDEX_CALL_FLAGS: usize = 0;
|
pub const ARGUMENT_INDEX_CALL_FLAGS: usize = 0;
|
||||||
|
|
||||||
/// Reserve 1kb for calldata.
|
|
||||||
pub const MAX_CALLDATA_SIZE: usize = 1024;
|
|
||||||
|
|
||||||
/// Initializes the global variables.
|
/// Initializes the global variables.
|
||||||
/// The pointers are not initialized, because it's not possible to create a null pointer.
|
/// The pointers are not initialized, because it's not possible to create a null pointer.
|
||||||
pub fn initialize_globals<D>(context: &mut Context<D>) -> anyhow::Result<()>
|
pub fn initialize_globals<D>(context: &mut Context<D>) -> anyhow::Result<()>
|
||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
let calldata_type = context.array_type(context.byte_type(), Self::MAX_CALLDATA_SIZE);
|
|
||||||
context.set_global(
|
|
||||||
crate::polkavm::GLOBAL_CALLDATA_POINTER,
|
|
||||||
calldata_type,
|
|
||||||
AddressSpace::Stack,
|
|
||||||
calldata_type.get_undef(),
|
|
||||||
);
|
|
||||||
|
|
||||||
context.set_global(
|
context.set_global(
|
||||||
crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER,
|
crate::polkavm::GLOBAL_HEAP_MEMORY_POINTER,
|
||||||
context.llvm().ptr_type(AddressSpace::Heap.into()),
|
context.llvm().ptr_type(AddressSpace::Heap.into()),
|
||||||
@@ -53,9 +42,9 @@ impl Entry {
|
|||||||
|
|
||||||
context.set_global(
|
context.set_global(
|
||||||
crate::polkavm::GLOBAL_CALLDATA_SIZE,
|
crate::polkavm::GLOBAL_CALLDATA_SIZE,
|
||||||
context.word_type(),
|
context.xlen_type(),
|
||||||
AddressSpace::Stack,
|
AddressSpace::Stack,
|
||||||
context.word_undef(),
|
context.xlen_type().get_undef(),
|
||||||
);
|
);
|
||||||
|
|
||||||
context.set_global(
|
context.set_global(
|
||||||
@@ -68,54 +57,30 @@ impl Entry {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load the calldata via seal `input` and initialize the calldata end
|
/// Populate the calldata size global value.
|
||||||
/// and calldata size globals.
|
pub fn load_calldata_size<D>(context: &mut Context<D>) -> anyhow::Result<()>
|
||||||
pub fn load_calldata<D>(context: &mut Context<D>) -> anyhow::Result<()>
|
|
||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
let input_pointer = context
|
let call_data_size_pointer = context
|
||||||
.get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)?
|
.get_global(crate::polkavm::GLOBAL_CALLDATA_SIZE)?
|
||||||
.value
|
.value
|
||||||
.as_pointer_value();
|
.as_pointer_value();
|
||||||
let input_pointer_casted = context.builder.build_ptr_to_int(
|
let call_data_size_pointer_arg =
|
||||||
input_pointer,
|
context.build_alloca_at_entry(context.word_type(), "call_data_size_pointer_arg");
|
||||||
context.xlen_type(),
|
|
||||||
"input_pointer_casted",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let length_pointer = context.build_alloca_at_entry(context.xlen_type(), "len_ptr");
|
|
||||||
let length_pointer_casted = context.builder.build_ptr_to_int(
|
|
||||||
length_pointer.value,
|
|
||||||
context.xlen_type(),
|
|
||||||
"length_pointer_casted",
|
|
||||||
)?;
|
|
||||||
|
|
||||||
context.build_store(
|
|
||||||
length_pointer,
|
|
||||||
context.integer_const(crate::polkavm::XLEN, Self::MAX_CALLDATA_SIZE as u64),
|
|
||||||
)?;
|
|
||||||
context.build_runtime_call(
|
context.build_runtime_call(
|
||||||
revive_runtime_api::polkavm_imports::INPUT,
|
revive_runtime_api::polkavm_imports::CALL_DATA_SIZE,
|
||||||
&[input_pointer_casted.into(), length_pointer_casted.into()],
|
&[call_data_size_pointer_arg.to_int(context).into()],
|
||||||
);
|
);
|
||||||
|
let value = context.build_load(call_data_size_pointer_arg, "call_data_size_load")?;
|
||||||
// Store the calldata size
|
let value_truncated = context.builder().build_int_truncate(
|
||||||
let calldata_size = context
|
value.into_int_value(),
|
||||||
.build_load(length_pointer, "input_size")?
|
context.xlen_type(),
|
||||||
.into_int_value();
|
"call_data_size_truncated",
|
||||||
let calldata_size_casted = context.builder().build_int_z_extend(
|
|
||||||
calldata_size,
|
|
||||||
context.word_type(),
|
|
||||||
"zext_input_len",
|
|
||||||
)?;
|
)?;
|
||||||
context.set_global(
|
context
|
||||||
crate::polkavm::GLOBAL_CALLDATA_SIZE,
|
.builder()
|
||||||
context.word_type(),
|
.build_store(call_data_size_pointer, value_truncated)?;
|
||||||
AddressSpace::Stack,
|
|
||||||
calldata_size_casted,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +185,7 @@ where
|
|||||||
context.set_basic_block(context.current_function().borrow().entry_block());
|
context.set_basic_block(context.current_function().borrow().entry_block());
|
||||||
|
|
||||||
Self::initialize_globals(context)?;
|
Self::initialize_globals(context)?;
|
||||||
Self::load_calldata(context)?;
|
Self::load_calldata_size(context)?;
|
||||||
Self::leave_entry(context)?;
|
Self::leave_entry(context)?;
|
||||||
|
|
||||||
context.build_unconditional_branch(context.current_function().borrow().return_block());
|
context.build_unconditional_branch(context.current_function().borrow().return_block());
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
//! Translates the calldata instructions.
|
//! Translates the calldata instructions.
|
||||||
|
|
||||||
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;
|
||||||
use inkwell::types::BasicType;
|
|
||||||
|
|
||||||
/// Translates the calldata load.
|
/// Translates the calldata load.
|
||||||
pub fn load<'ctx, D>(
|
pub fn load<'ctx, D>(
|
||||||
@@ -14,19 +11,15 @@ pub fn load<'ctx, D>(
|
|||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
let calldata_pointer = context
|
let output_pointer = context.build_alloca_at_entry(context.word_type(), "call_data_output");
|
||||||
.get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)?
|
let offset = context.safe_truncate_int_to_xlen(offset)?;
|
||||||
.value
|
|
||||||
.as_pointer_value();
|
context.build_runtime_call(
|
||||||
let offset = context.build_gep(
|
revive_runtime_api::polkavm_imports::CALL_DATA_LOAD,
|
||||||
Pointer::new(context.byte_type(), AddressSpace::Stack, calldata_pointer),
|
&[output_pointer.to_int(context).into(), offset.into()],
|
||||||
&[offset],
|
|
||||||
context.word_type().as_basic_type_enum(),
|
|
||||||
"calldata_pointer_with_offset",
|
|
||||||
);
|
);
|
||||||
context
|
|
||||||
.build_load(offset, "calldata_value")
|
context.build_load(output_pointer, "call_data_load_value")
|
||||||
.and_then(|value| context.build_byte_swap(value))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translates the calldata size.
|
/// Translates the calldata size.
|
||||||
@@ -37,8 +30,14 @@ where
|
|||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
let value = context.get_global_value(crate::polkavm::GLOBAL_CALLDATA_SIZE)?;
|
let value = context.get_global_value(crate::polkavm::GLOBAL_CALLDATA_SIZE)?;
|
||||||
|
Ok(context
|
||||||
Ok(value)
|
.builder()
|
||||||
|
.build_int_z_extend(
|
||||||
|
value.into_int_value(),
|
||||||
|
context.word_type(),
|
||||||
|
"call_data_size_value",
|
||||||
|
)?
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translates the calldata copy.
|
/// Translates the calldata copy.
|
||||||
@@ -51,20 +50,19 @@ pub fn copy<'ctx, D>(
|
|||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
let offset = context.safe_truncate_int_to_xlen(destination_offset)?;
|
let source_offset = context.safe_truncate_int_to_xlen(source_offset)?;
|
||||||
let size = context.safe_truncate_int_to_xlen(size)?;
|
let size = context.safe_truncate_int_to_xlen(size)?;
|
||||||
let destination = context.build_heap_gep(offset, size)?;
|
let destination_offset = context.safe_truncate_int_to_xlen(destination_offset)?;
|
||||||
|
let output_pointer = context.build_heap_gep(destination_offset, size)?;
|
||||||
|
|
||||||
let calldata_pointer = context
|
context.build_runtime_call(
|
||||||
.get_global(crate::polkavm::GLOBAL_CALLDATA_POINTER)?
|
revive_runtime_api::polkavm_imports::CALL_DATA_COPY,
|
||||||
.value
|
&[
|
||||||
.as_pointer_value();
|
output_pointer.to_int(context).into(),
|
||||||
let source = context.build_gep(
|
size.into(),
|
||||||
Pointer::new(context.byte_type(), AddressSpace::Stack, calldata_pointer),
|
source_offset.into(),
|
||||||
&[context.safe_truncate_int_to_xlen(source_offset)?],
|
],
|
||||||
context.byte_type(),
|
|
||||||
"calldata_pointer_with_offset",
|
|
||||||
);
|
);
|
||||||
|
|
||||||
context.build_memcpy(destination, source, size, "calldata_copy_memcpy_from_child")
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -421,7 +421,7 @@ impl Specs {
|
|||||||
origin,
|
origin,
|
||||||
value,
|
value,
|
||||||
gas_limit.unwrap_or(GAS_LIMIT),
|
gas_limit.unwrap_or(GAS_LIMIT),
|
||||||
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT),
|
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT).into(),
|
||||||
code,
|
code,
|
||||||
data,
|
data,
|
||||||
salt.0,
|
salt.0,
|
||||||
@@ -461,7 +461,7 @@ impl Specs {
|
|||||||
dest.to_eth_addr(&results),
|
dest.to_eth_addr(&results),
|
||||||
value,
|
value,
|
||||||
gas_limit.unwrap_or(GAS_LIMIT),
|
gas_limit.unwrap_or(GAS_LIMIT),
|
||||||
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT),
|
storage_deposit_limit.unwrap_or(DEPOSIT_LIMIT).into(),
|
||||||
data,
|
data,
|
||||||
DebugInfo::Skip,
|
DebugInfo::Skip,
|
||||||
CollectEvents::Skip,
|
CollectEvents::Skip,
|
||||||
|
|||||||
@@ -76,6 +76,12 @@ POLKAVM_IMPORT(void, block_number, uint32_t)
|
|||||||
|
|
||||||
POLKAVM_IMPORT(uint64_t, call, uint32_t)
|
POLKAVM_IMPORT(uint64_t, call, uint32_t)
|
||||||
|
|
||||||
|
POLKAVM_IMPORT(uint64_t, call_data_copy, uint32_t, uint32_t, uint32_t)
|
||||||
|
|
||||||
|
POLKAVM_IMPORT(uint64_t, call_data_load, uint32_t, uint32_t)
|
||||||
|
|
||||||
|
POLKAVM_IMPORT(uint64_t, call_data_size, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(uint64_t, delegate_call, uint32_t)
|
POLKAVM_IMPORT(uint64_t, delegate_call, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(void, caller, uint32_t)
|
POLKAVM_IMPORT(void, caller, uint32_t)
|
||||||
@@ -94,8 +100,6 @@ POLKAVM_IMPORT(uint64_t, get_storage, uint32_t, uint32_t, uint32_t, uint32_t, ui
|
|||||||
|
|
||||||
POLKAVM_IMPORT(void, hash_keccak_256, uint32_t, uint32_t, uint32_t)
|
POLKAVM_IMPORT(void, hash_keccak_256, uint32_t, uint32_t, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(void, input, uint32_t, uint32_t)
|
|
||||||
|
|
||||||
POLKAVM_IMPORT(uint64_t, instantiate, uint32_t)
|
POLKAVM_IMPORT(uint64_t, instantiate, uint32_t)
|
||||||
|
|
||||||
POLKAVM_IMPORT(void, now, uint32_t)
|
POLKAVM_IMPORT(void, now, uint32_t)
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ pub static BLOCK_NUMBER: &str = "block_number";
|
|||||||
|
|
||||||
pub static CALL: &str = "call";
|
pub static CALL: &str = "call";
|
||||||
|
|
||||||
|
pub static CALL_DATA_COPY: &str = "call_data_copy";
|
||||||
|
|
||||||
|
pub static CALL_DATA_LOAD: &str = "call_data_load";
|
||||||
|
|
||||||
|
pub static CALL_DATA_SIZE: &str = "call_data_size";
|
||||||
|
|
||||||
pub static DELEGATE_CALL: &str = "delegate_call";
|
pub static DELEGATE_CALL: &str = "delegate_call";
|
||||||
|
|
||||||
pub static CALLER: &str = "caller";
|
pub static CALLER: &str = "caller";
|
||||||
@@ -44,8 +50,6 @@ pub static GET_STORAGE: &str = "get_storage";
|
|||||||
|
|
||||||
pub static HASH_KECCAK_256: &str = "hash_keccak_256";
|
pub static HASH_KECCAK_256: &str = "hash_keccak_256";
|
||||||
|
|
||||||
pub static INPUT: &str = "input";
|
|
||||||
|
|
||||||
pub static INSTANTIATE: &str = "instantiate";
|
pub static INSTANTIATE: &str = "instantiate";
|
||||||
|
|
||||||
pub static NOW: &str = "now";
|
pub static NOW: &str = "now";
|
||||||
@@ -68,7 +72,7 @@ pub static WEIGHT_TO_FEE: &str = "weight_to_fee";
|
|||||||
|
|
||||||
/// All imported runtime API symbols.
|
/// All imported runtime API symbols.
|
||||||
/// Useful for configuring common attributes and linkage.
|
/// Useful for configuring common attributes and linkage.
|
||||||
pub static IMPORTS: [&str; 28] = [
|
pub static IMPORTS: [&str; 30] = [
|
||||||
SBRK,
|
SBRK,
|
||||||
MEMORY_SIZE,
|
MEMORY_SIZE,
|
||||||
ADDRESS,
|
ADDRESS,
|
||||||
@@ -77,6 +81,9 @@ pub static IMPORTS: [&str; 28] = [
|
|||||||
BLOCK_HASH,
|
BLOCK_HASH,
|
||||||
BLOCK_NUMBER,
|
BLOCK_NUMBER,
|
||||||
CALL,
|
CALL,
|
||||||
|
CALL_DATA_COPY,
|
||||||
|
CALL_DATA_LOAD,
|
||||||
|
CALL_DATA_SIZE,
|
||||||
DELEGATE_CALL,
|
DELEGATE_CALL,
|
||||||
CALLER,
|
CALLER,
|
||||||
CHAIN_ID,
|
CHAIN_ID,
|
||||||
@@ -86,7 +93,6 @@ pub static IMPORTS: [&str; 28] = [
|
|||||||
GET_IMMUTABLE_DATA,
|
GET_IMMUTABLE_DATA,
|
||||||
GET_STORAGE,
|
GET_STORAGE,
|
||||||
HASH_KECCAK_256,
|
HASH_KECCAK_256,
|
||||||
INPUT,
|
|
||||||
INSTANTIATE,
|
INSTANTIATE,
|
||||||
NOW,
|
NOW,
|
||||||
ORIGIN,
|
ORIGIN,
|
||||||
|
|||||||
Reference in New Issue
Block a user