mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-15 01:01:05 +00:00
@@ -8,4 +8,10 @@ contract ExtCode {
|
|||||||
ret := extcodesize(who)
|
ret := extcodesize(who)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CodeSize() public pure returns (uint ret) {
|
||||||
|
assembly {
|
||||||
|
ret := codesize()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,6 +126,8 @@ sol!(
|
|||||||
sol!(
|
sol!(
|
||||||
contract ExtCode {
|
contract ExtCode {
|
||||||
function ExtCodeSize(address who) public view returns (uint ret);
|
function ExtCodeSize(address who) public view returns (uint ret);
|
||||||
|
|
||||||
|
function CodeSize() public pure returns (uint ret);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -461,6 +463,18 @@ impl Contract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn code_size() -> Self {
|
||||||
|
let code = include_str!("../contracts/ExtCode.sol");
|
||||||
|
let name = "ExtCode";
|
||||||
|
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
||||||
|
pvm_runtime: crate::compile_blob(name, code),
|
||||||
|
calldata: ExtCode::CodeSizeCall::new(()).abi_encode(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn memcpy(payload: Vec<u8>) -> Self {
|
pub fn memcpy(payload: Vec<u8>) -> Self {
|
||||||
let code = include_str!("../contracts/MCopy.sol");
|
let code = include_str!("../contracts/MCopy.sol");
|
||||||
let name = "MCopy";
|
let name = "MCopy";
|
||||||
|
|||||||
@@ -884,20 +884,26 @@ fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
|||||||
|caller: Caller<Transaction>, address_ptr: u32| {
|
|caller: Caller<Transaction>, address_ptr: u32| {
|
||||||
let (caller, transaction) = caller.split();
|
let (caller, transaction) = caller.split();
|
||||||
|
|
||||||
let bytes = caller.read_memory_into_vec(address_ptr, 32)?;
|
let address = if address_ptr == u32::MAX {
|
||||||
let word = U256::from_le_slice(&bytes);
|
transaction.top_frame().callee
|
||||||
let address = Address::from_word(word.into());
|
} else {
|
||||||
|
let bytes = caller.read_memory_into_vec(address_ptr, 32)?;
|
||||||
|
let word = U256::from_le_slice(&bytes);
|
||||||
|
Address::from_word(word.into())
|
||||||
|
};
|
||||||
|
|
||||||
log::info!("{}", address);
|
let code_size = transaction
|
||||||
|
|
||||||
Ok(transaction
|
|
||||||
.state
|
.state
|
||||||
.accounts
|
.accounts
|
||||||
.get(&address)
|
.get(&address)
|
||||||
.and_then(|account| account.contract)
|
.and_then(|account| account.contract)
|
||||||
.and_then(|blob_hash| transaction.state.blobs.get(&blob_hash))
|
.and_then(|blob_hash| transaction.state.blobs.get(&blob_hash))
|
||||||
.map(|code| code.len())
|
.map(|code| code.len())
|
||||||
.unwrap_or_default() as u32)
|
.unwrap_or_default() as u32;
|
||||||
|
|
||||||
|
log::info!("code size of {address} = {code_size}");
|
||||||
|
|
||||||
|
Ok(code_size)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@@ -525,6 +525,15 @@ fn ext_code_size() {
|
|||||||
assert_eq!(received, expected);
|
assert_eq!(received, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn code_size() {
|
||||||
|
let contract = Contract::code_size();
|
||||||
|
let (_, output) = assert_success(&contract, false);
|
||||||
|
let expected = U256::from(contract.pvm_runtime.len());
|
||||||
|
let received = U256::from_be_slice(&output.data);
|
||||||
|
assert_eq!(expected, received);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn value_transfer() {
|
fn value_transfer() {
|
||||||
// Succeeds in remix (shanghai) but traps the interpreter
|
// Succeeds in remix (shanghai) but traps the interpreter
|
||||||
|
|||||||
@@ -1234,10 +1234,17 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the register witdh sized type.
|
/// Returns the register witdh sized type.
|
||||||
pub fn sentinel_pointer(&self) -> inkwell::values::PointerValue<'ctx> {
|
pub fn sentinel_pointer(&self) -> Pointer<'ctx> {
|
||||||
self.xlen_type()
|
let sentinel_pointer = self
|
||||||
|
.xlen_type()
|
||||||
.const_all_ones()
|
.const_all_ones()
|
||||||
.const_to_pointer(self.llvm().ptr_type(Default::default()))
|
.const_to_pointer(self.llvm().ptr_type(Default::default()));
|
||||||
|
|
||||||
|
Pointer::new(
|
||||||
|
sentinel_pointer.get_type(),
|
||||||
|
AddressSpace::Stack,
|
||||||
|
sentinel_pointer,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the runtime value width sized type.
|
/// Returns the runtime value width sized type.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ where
|
|||||||
let value_pointer = if let Some(value) = value {
|
let value_pointer = if let Some(value) = value {
|
||||||
let value_pointer = context.build_alloca(context.value_type(), "value");
|
let value_pointer = context.build_alloca(context.value_type(), "value");
|
||||||
context.build_store(value_pointer, value)?;
|
context.build_store(value_pointer, value)?;
|
||||||
value_pointer.value
|
value_pointer
|
||||||
} else {
|
} else {
|
||||||
context.sentinel_pointer()
|
context.sentinel_pointer()
|
||||||
};
|
};
|
||||||
@@ -66,8 +66,8 @@ where
|
|||||||
.next(address_pointer.value)?
|
.next(address_pointer.value)?
|
||||||
.next(gas)?
|
.next(gas)?
|
||||||
.skip()
|
.skip()
|
||||||
.next(context.sentinel_pointer())?
|
.next(context.sentinel_pointer().value)?
|
||||||
.next(value_pointer)?
|
.next(value_pointer.value)?
|
||||||
.next(input_pointer.value)?
|
.next(input_pointer.value)?
|
||||||
.next(input_length)?
|
.next(input_length)?
|
||||||
.next(output_pointer.value)?
|
.next(output_pointer.value)?
|
||||||
|
|||||||
@@ -66,14 +66,14 @@ where
|
|||||||
.next(code_hash_pointer.value)?
|
.next(code_hash_pointer.value)?
|
||||||
.skip()
|
.skip()
|
||||||
.skip()
|
.skip()
|
||||||
.next(context.sentinel_pointer())?
|
.next(context.sentinel_pointer().value)?
|
||||||
.next(value_pointer.value)?
|
.next(value_pointer.value)?
|
||||||
.next(input_data_pointer.value)?
|
.next(input_data_pointer.value)?
|
||||||
.next(input_length)?
|
.next(input_length)?
|
||||||
.next(address_pointer.value)?
|
.next(address_pointer.value)?
|
||||||
.next(address_length_pointer.value)?
|
.next(address_length_pointer.value)?
|
||||||
.next(context.sentinel_pointer())?
|
.next(context.sentinel_pointer().value)?
|
||||||
.next(context.sentinel_pointer())?
|
.next(context.sentinel_pointer().value)?
|
||||||
.next(salt_pointer.value)?
|
.next(salt_pointer.value)?
|
||||||
.next(
|
.next(
|
||||||
context
|
context
|
||||||
|
|||||||
@@ -6,16 +6,23 @@ use crate::polkavm::context::Context;
|
|||||||
use crate::polkavm::Dependency;
|
use crate::polkavm::Dependency;
|
||||||
use crate::polkavm_const::runtime_api;
|
use crate::polkavm_const::runtime_api;
|
||||||
|
|
||||||
/// Translates the `extcodesize` instruction.
|
/// Translates the `extcodesize` instruction if `address` is `Some`.
|
||||||
|
/// Otherwise, translates the `codesize` instruction.
|
||||||
pub fn size<'ctx, D>(
|
pub fn size<'ctx, D>(
|
||||||
context: &mut Context<'ctx, D>,
|
context: &mut Context<'ctx, D>,
|
||||||
address: inkwell::values::IntValue<'ctx>,
|
address: Option<inkwell::values::IntValue<'ctx>>,
|
||||||
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>>
|
||||||
where
|
where
|
||||||
D: Dependency + Clone,
|
D: Dependency + Clone,
|
||||||
{
|
{
|
||||||
let address_pointer = context.build_alloca(context.word_type(), "value");
|
let address_pointer = match address {
|
||||||
context.build_store(address_pointer, address)?;
|
Some(address) => {
|
||||||
|
let address_pointer = context.build_alloca(context.word_type(), "value");
|
||||||
|
context.build_store(address_pointer, address)?;
|
||||||
|
address_pointer
|
||||||
|
}
|
||||||
|
None => context.sentinel_pointer(),
|
||||||
|
};
|
||||||
|
|
||||||
let address_pointer_casted = context.builder().build_ptr_to_int(
|
let address_pointer_casted = context.builder().build_ptr_to_int(
|
||||||
address_pointer.value,
|
address_pointer.value,
|
||||||
|
|||||||
@@ -857,7 +857,7 @@ where
|
|||||||
revive_llvm_context::polkavm_evm_calldata::size(context).map(Some)
|
revive_llvm_context::polkavm_evm_calldata::size(context).map(Some)
|
||||||
}
|
}
|
||||||
revive_llvm_context::PolkaVMCodeType::Runtime => {
|
revive_llvm_context::PolkaVMCodeType::Runtime => {
|
||||||
todo!()
|
revive_llvm_context::polkavm_evm_ext_code::size(context, None).map(Some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -930,7 +930,7 @@ where
|
|||||||
let arguments = self.pop_arguments_llvm(context);
|
let arguments = self.pop_arguments_llvm(context);
|
||||||
revive_llvm_context::polkavm_evm_ext_code::size(
|
revive_llvm_context::polkavm_evm_ext_code::size(
|
||||||
context,
|
context,
|
||||||
arguments[0].into_int_value(),
|
Some(arguments[0].into_int_value()),
|
||||||
)
|
)
|
||||||
.map(Some)
|
.map(Some)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -591,7 +591,7 @@ impl FunctionCall {
|
|||||||
revive_llvm_context::polkavm_evm_calldata::size(context).map(Some)
|
revive_llvm_context::polkavm_evm_calldata::size(context).map(Some)
|
||||||
}
|
}
|
||||||
revive_llvm_context::PolkaVMCodeType::Runtime => {
|
revive_llvm_context::PolkaVMCodeType::Runtime => {
|
||||||
todo!()
|
revive_llvm_context::polkavm_evm_ext_code::size(context, None).map(Some)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,7 +632,7 @@ impl FunctionCall {
|
|||||||
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
|
let arguments = self.pop_arguments_llvm::<D, 1>(context)?;
|
||||||
revive_llvm_context::polkavm_evm_ext_code::size(
|
revive_llvm_context::polkavm_evm_ext_code::size(
|
||||||
context,
|
context,
|
||||||
arguments[0].into_int_value(),
|
Some(arguments[0].into_int_value()),
|
||||||
)
|
)
|
||||||
.map(Some)
|
.map(Some)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user