mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-12 09:21:01 +00:00
@@ -104,6 +104,15 @@ sol!(
|
||||
}
|
||||
);
|
||||
|
||||
sol!(
|
||||
contract Events {
|
||||
event A(uint) anonymous;
|
||||
event E(uint indexed, uint indexed, uint indexed);
|
||||
|
||||
function emitEvent(uint topics) public;
|
||||
}
|
||||
);
|
||||
|
||||
impl Contract {
|
||||
/// Execute the contract.
|
||||
///
|
||||
@@ -338,6 +347,18 @@ impl Contract {
|
||||
calldata: MStore8::mStore8Call::new((value,)).abi_encode(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event(topics: U256) -> Self {
|
||||
let code = include_str!("../contracts/Events.sol");
|
||||
let name = "Events";
|
||||
|
||||
Self {
|
||||
name,
|
||||
evm_runtime: crate::compile_evm_bin_runtime(name, code),
|
||||
pvm_runtime: crate::compile_blob(name, code),
|
||||
calldata: Events::emitEventCall::new((topics,)).abi_encode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -389,6 +410,7 @@ mod tests {
|
||||
Contract::erc20 as fn() -> Contract,
|
||||
(|| Contract::sha1(Vec::new())) as fn() -> Contract,
|
||||
(|| Contract::division_arithmetics_div(U256::ZERO, U256::ZERO)) as fn() -> Contract,
|
||||
(|| Contract::event(U256::ZERO)) as fn() -> Contract,
|
||||
]
|
||||
.into_par_iter()
|
||||
.map(extract_code_size)
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use alloy_primitives::{Address, U256};
|
||||
use cases::Contract;
|
||||
use mock_runtime::{CallOutput, State};
|
||||
|
||||
use crate::mock_runtime::ReturnFlags;
|
||||
use crate::mock_runtime::{Event, ReturnFlags};
|
||||
|
||||
pub mod cases;
|
||||
pub mod mock_runtime;
|
||||
@@ -82,7 +83,25 @@ pub fn assert_success(contract: &Contract, differential: bool) -> (State, CallOu
|
||||
if differential {
|
||||
let evm =
|
||||
revive_differential::prepare(contract.evm_runtime.clone(), contract.calldata.clone());
|
||||
assert_eq!(output.data.clone(), revive_differential::execute(evm));
|
||||
let (evm_output, evm_log) = revive_differential::execute(evm);
|
||||
|
||||
assert_eq!(output.data.clone(), evm_output);
|
||||
assert_eq!(output.events.len(), evm_log.len());
|
||||
assert_eq!(
|
||||
output.events,
|
||||
evm_log
|
||||
.iter()
|
||||
.map(|log| Event {
|
||||
address: Address::from_slice(log.address.as_bytes()),
|
||||
data: log.data.clone(),
|
||||
topics: log
|
||||
.topics
|
||||
.iter()
|
||||
.map(|topic| U256::from_be_bytes(topic.0))
|
||||
.collect(),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
);
|
||||
}
|
||||
|
||||
(state, output)
|
||||
|
||||
@@ -17,8 +17,9 @@ struct Account {
|
||||
}
|
||||
|
||||
/// Emitted event data.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
pub struct Event {
|
||||
pub address: Address,
|
||||
pub data: Vec<u8>,
|
||||
pub topics: Vec<U256>,
|
||||
}
|
||||
@@ -31,7 +32,7 @@ pub struct CallOutput {
|
||||
/// The contract call output.
|
||||
pub data: Vec<u8>,
|
||||
/// The emitted events.
|
||||
pub events: Event,
|
||||
pub events: Vec<Event>,
|
||||
}
|
||||
|
||||
/// The contract blob export to be called.
|
||||
@@ -570,6 +571,43 @@ fn link_host_functions(engine: &Engine) -> Linker<Transaction> {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
linker
|
||||
.func_wrap(
|
||||
runtime_api::DEPOSIT_EVENT,
|
||||
|caller: Caller<Transaction>,
|
||||
topics_ptr: u32,
|
||||
topics_len: u32,
|
||||
data_ptr: u32,
|
||||
data_len: u32| {
|
||||
let (caller, transaction) = caller.split();
|
||||
|
||||
let address = transaction.top_frame().callee;
|
||||
let data = if data_len != 0 {
|
||||
caller.read_memory_into_vec(data_ptr, data_len)?
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
let topics = if topics_len != 0 {
|
||||
caller
|
||||
.read_memory_into_vec(topics_ptr, topics_len)?
|
||||
.chunks(32)
|
||||
.map(|chunk| U256::from_be_slice(chunk))
|
||||
.collect()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
transaction.top_frame_mut().output.events.push(Event {
|
||||
address,
|
||||
data,
|
||||
topics,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
linker
|
||||
}
|
||||
|
||||
|
||||
@@ -415,3 +415,9 @@ fn signed_remainder() {
|
||||
assert_eq!(received, expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn events() {
|
||||
assert_success(&Contract::event(U256::ZERO), true);
|
||||
assert_success(&Contract::event(U256::from(123)), true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user