mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-06 11:27:25 +00:00
implement contract events (#2161)
* implement contract events * update runtime * renaming * update test code hash * improve complexity details * add deposit event base cost * add test * Revert "add deposit event base cost" This reverts commit 58ec010c0f4f4f0e16935ad41da32aedd17a8c57. * update test * Revert "update test" This reverts commit 6fe61a593ccf0d41f09a0b97472b28ed8751a999. * Revert "Revert "add deposit event base cost"" This reverts commit 145e8a9bac15313a4c380aa66b94fd4d36fa3f6d. * Fix format a bit
This commit is contained in:
@@ -203,6 +203,7 @@ mod tests {
|
||||
creates: Vec<CreateEntry>,
|
||||
transfers: Vec<TransferEntry>,
|
||||
dispatches: Vec<DispatchEntry>,
|
||||
events: Vec<Vec<u8>>,
|
||||
next_account_id: u64,
|
||||
random_seed: H256,
|
||||
}
|
||||
@@ -276,6 +277,10 @@ mod tests {
|
||||
fn random_seed(&self) -> &H256{
|
||||
&self.random_seed
|
||||
}
|
||||
|
||||
fn deposit_event(&mut self, data: Vec<u8>) {
|
||||
self.events.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
fn execute<E: Ext>(
|
||||
@@ -1166,4 +1171,43 @@ mod tests {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
const CODE_DEPOSIT_EVENT: &str = r#"
|
||||
(module
|
||||
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $ext_deposit_event
|
||||
(i32.const 8) ;; Pointer to the start of encoded call buffer
|
||||
(i32.const 13) ;; Length of the buffer
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
|
||||
(data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00")
|
||||
)
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn deposit_event() {
|
||||
// This test can fail due to the encoding changes. In case it becomes too annoying
|
||||
// let's rewrite so as we use this module controlled call or we serialize it in runtime.
|
||||
|
||||
let mut mock_ext = MockExt::default();
|
||||
let mut gas_meter = GasMeter::with_limit(50_000, 1);
|
||||
execute(
|
||||
CODE_DEPOSIT_EVENT,
|
||||
&[],
|
||||
&mut Vec::new(),
|
||||
&mut mock_ext,
|
||||
&mut gas_meter
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(gas_meter.gas_left(), 50_000
|
||||
- 4 // Explicit
|
||||
- 13 - 1 // Deposit event
|
||||
- 13 // read memory
|
||||
);
|
||||
assert_eq!(mock_ext.events, vec![vec![0, 1, 42, 0, 0, 0, 0, 0, 0, 0, 229, 20, 0]]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ use system;
|
||||
use rstd::prelude::*;
|
||||
use rstd::mem;
|
||||
use parity_codec::{Decode, Encode};
|
||||
use runtime_primitives::traits::{As, CheckedMul, Bounded};
|
||||
use runtime_primitives::traits::{As, CheckedMul, CheckedAdd, Bounded};
|
||||
|
||||
/// Enumerates all possible *special* trap conditions.
|
||||
///
|
||||
@@ -108,6 +108,9 @@ pub enum RuntimeToken<Gas> {
|
||||
ReturnData(u32),
|
||||
/// Dispatch fee calculated by `T::ComputeDispatchFee`.
|
||||
ComputedDispatchFee(Gas),
|
||||
/// The given number of bytes is read from the sandbox memory and
|
||||
/// deposit in as an event.
|
||||
DepositEvent(u32),
|
||||
}
|
||||
|
||||
impl<T: Trait> Token<T> for RuntimeToken<T::Gas> {
|
||||
@@ -126,6 +129,10 @@ impl<T: Trait> Token<T> for RuntimeToken<T::Gas> {
|
||||
ReturnData(byte_count) => metadata
|
||||
.return_data_per_byte_cost
|
||||
.checked_mul(&<T::Gas as As<u32>>::sa(byte_count)),
|
||||
DepositEvent(byte_count) => metadata
|
||||
.event_data_per_byte_cost
|
||||
.checked_mul(&<T::Gas as As<u32>>::sa(byte_count))
|
||||
.and_then(|e| e.checked_add(&metadata.event_data_base_cost)),
|
||||
ComputedDispatchFee(gas) => Some(gas),
|
||||
};
|
||||
|
||||
@@ -582,4 +589,23 @@ define_env!(Env, <E: Ext>,
|
||||
|
||||
Ok(())
|
||||
},
|
||||
|
||||
// Deposit a contract event with the data buffer.
|
||||
ext_deposit_event(ctx, data_ptr: u32, data_len: u32) => {
|
||||
match ctx
|
||||
.gas_meter
|
||||
.charge(
|
||||
ctx.schedule,
|
||||
RuntimeToken::DepositEvent(data_len)
|
||||
)
|
||||
{
|
||||
GasMeterResult::Proceed => (),
|
||||
GasMeterResult::OutOfGas => return Err(sandbox::HostError),
|
||||
}
|
||||
|
||||
let event_data = read_sandbox_memory(ctx, data_ptr, data_len)?;
|
||||
ctx.ext.deposit_event(event_data);
|
||||
|
||||
Ok(())
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user