Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node"),
impl_name: create_runtime_str!("substrate-node"),
authoring_version: 10,
spec_version: 78,
impl_version: 78,
spec_version: 79,
impl_version: 79,
apis: RUNTIME_API_VERSIONS,
};

Expand Down
71 changes: 56 additions & 15 deletions srml/contract/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub type CallOf<T> = <T as Trait>::Call;
pub type MomentOf<T> = <T as timestamp::Trait>::Moment;
pub type SeedOf<T> = <T as system::Trait>::Hash;

/// A type that represents a topic of an event. At the moment a hash is used.
pub type TopicOf<T> = <T as system::Trait>::Hash;

#[cfg_attr(test, derive(Debug))]
pub struct InstantiateReceipt<AccountId> {
pub address: AccountId,
Expand Down Expand Up @@ -106,8 +109,10 @@ pub trait Ext {
/// Returns a reference to the random seed for the current block
fn random_seed(&self) -> &SeedOf<Self::T>;

/// Deposit an event.
fn deposit_event(&mut self, data: Vec<u8>);
/// Deposit an event with the given topics.
///
/// There should not be any duplicates in `topics`.
fn deposit_event(&mut self, topics: Vec<TopicOf<Self::T>>, data: Vec<u8>);

/// Set rent allowance of the contract
fn set_rent_allowance(&mut self, rent_allowance: BalanceOf<Self::T>);
Expand Down Expand Up @@ -189,6 +194,16 @@ impl VmExecResult {
}
}

/// Struct that records a request to deposit an event with a list of topics.
#[cfg_attr(feature = "std", derive(Debug))]
#[derive(PartialEq, Eq)]
pub struct IndexedEvent<T: Trait> {
/// A list of topics this event will be deposited with.
pub topics: Vec<T::Hash>,
/// The event to deposit.
pub event: Event<T>,
}

/// A trait that represent a virtual machine.
///
/// You can view a virtual machine as something that takes code, an input data buffer,
Expand Down Expand Up @@ -238,7 +253,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> {
pub self_trie_id: Option<TrieId>,
pub overlay: OverlayAccountDb<'a, T>,
pub depth: usize,
pub events: Vec<Event<T>>,
pub events: Vec<IndexedEvent<T>>,
pub calls: Vec<(T::AccountId, T::Call)>,
pub config: &'a Config<T>,
pub vm: &'a V,
Expand Down Expand Up @@ -418,7 +433,10 @@ where
.into_result()?;

// Deposit an instantiation event.
nested.events.push(RawEvent::Instantiated(self.self_account.clone(), dest.clone()));
nested.events.push(IndexedEvent {
event: RawEvent::Instantiated(self.self_account.clone(), dest.clone()),
topics: Vec::new(),
});

(nested.overlay.into_change_set(), nested.events, nested.calls)
};
Expand Down Expand Up @@ -545,8 +563,10 @@ fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
if transactor != dest {
ctx.overlay.set_balance(transactor, new_from_balance);
ctx.overlay.set_balance(dest, new_to_balance);
ctx.events
.push(RawEvent::Transfer(transactor.clone(), dest.clone(), value));
ctx.events.push(IndexedEvent {
event: RawEvent::Transfer(transactor.clone(), dest.clone(), value),
topics: Vec::new(),
});
}

Ok(())
Expand Down Expand Up @@ -631,8 +651,11 @@ where
&self.timestamp
}

fn deposit_event(&mut self, data: Vec<u8>) {
self.ctx.events.push(RawEvent::Contract(self.ctx.self_account.clone(), data));
fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
self.ctx.events.push(IndexedEvent {
topics,
event: RawEvent::Contract(self.ctx.self_account.clone(), data),
});
}

fn set_rent_allowance(&mut self, rent_allowance: BalanceOf<T>) {
Expand All @@ -659,7 +682,7 @@ where
mod tests {
use super::{
BalanceOf, ExecFeeToken, ExecutionContext, Ext, Loader, EmptyOutputBuf, TransferFeeKind, TransferFeeToken,
Vm, VmExecResult, InstantiateReceipt, RawEvent,
Vm, VmExecResult, InstantiateReceipt, RawEvent, IndexedEvent,
};
use crate::account_db::AccountDb;
use crate::gas::GasMeter;
Expand Down Expand Up @@ -1262,8 +1285,14 @@ mod tests {
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events, &[
RawEvent::Transfer(ALICE, created_contract_address, 100),
RawEvent::Instantiated(ALICE, created_contract_address),
IndexedEvent {
event: RawEvent::Transfer(ALICE, created_contract_address, 100),
topics: Vec::new(),
},
IndexedEvent {
event: RawEvent::Instantiated(ALICE, created_contract_address),
topics: Vec::new(),
}
]);
}
);
Expand Down Expand Up @@ -1314,9 +1343,18 @@ mod tests {
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events, &[
RawEvent::Transfer(ALICE, BOB, 20),
RawEvent::Transfer(BOB, created_contract_address, 15),
RawEvent::Instantiated(BOB, created_contract_address),
IndexedEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
IndexedEvent {
event: RawEvent::Transfer(BOB, created_contract_address, 15),
topics: Vec::new(),
},
IndexedEvent {
event: RawEvent::Instantiated(BOB, created_contract_address),
topics: Vec::new(),
},
]);
}
);
Expand Down Expand Up @@ -1362,7 +1400,10 @@ mod tests {
// The contract wasn't created so we don't expect to see an instantiation
// event here.
assert_eq!(&ctx.events, &[
RawEvent::Transfer(ALICE, BOB, 20),
IndexedEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
]);
}
);
Expand Down
26 changes: 22 additions & 4 deletions srml/contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,12 @@ decl_module! {
DirectAccountDb.commit(ctx.overlay.into_change_set());

// Then deposit all events produced.
ctx.events.into_iter().for_each(Self::deposit_event);
ctx.events.into_iter().for_each(|indexed_event| {
<system::Module<T>>::deposit_event_indexed(
&*indexed_event.topics,
<T as Trait>::Event::from(indexed_event.event).into(),
);
});
}

// Refund cost of the unused gas.
Expand Down Expand Up @@ -447,7 +452,12 @@ decl_module! {
DirectAccountDb.commit(ctx.overlay.into_change_set());

// Then deposit all events produced.
ctx.events.into_iter().for_each(Self::deposit_event);
ctx.events.into_iter().for_each(|indexed_event| {
<system::Module<T>>::deposit_event_indexed(
&*indexed_event.topics,
<T as Trait>::Event::from(indexed_event.event).into(),
);
});
}

// Refund cost of the unused gas.
Expand Down Expand Up @@ -653,15 +663,21 @@ pub struct Schedule<Gas> {
/// Gas cost to deposit an event; the per-byte portion.
pub event_data_per_byte_cost: Gas,

/// Gas cost to deposit an event; the cost per topic.
pub event_per_topic_cost: Gas,

/// Gas cost to deposit an event; the base.
pub event_data_base_cost: Gas,
pub event_base_cost: Gas,

/// Gas cost per one byte read from the sandbox memory.
pub sandbox_data_read_cost: Gas,

/// Gas cost per one byte written to the sandbox memory.
pub sandbox_data_write_cost: Gas,

/// The maximum number of topics supported by an event.
pub max_event_topics: u32,

/// Maximum allowed stack height.
///
/// See https://wiki.parity.io/WebAssembly-StackHeight to find out
Expand All @@ -685,9 +701,11 @@ impl<Gas: As<u64>> Default for Schedule<Gas> {
regular_op_cost: Gas::sa(1),
return_data_per_byte_cost: Gas::sa(1),
event_data_per_byte_cost: Gas::sa(1),
event_data_base_cost: Gas::sa(1),
event_per_topic_cost: Gas::sa(1),
event_base_cost: Gas::sa(1),
sandbox_data_read_cost: Gas::sa(1),
sandbox_data_write_cost: Gas::sa(1),
max_event_topics: 4,
max_stack_height: 64 * 1024,
max_memory_pages: 16,
enable_println: false,
Expand Down
12 changes: 7 additions & 5 deletions srml/contract/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl_outer_dispatch! {
}
}

#[derive(Clone, Eq, PartialEq)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl system::Trait for Test {
type Origin = Origin;
Expand Down Expand Up @@ -313,14 +313,16 @@ fn account_removal_removes_storage() {
const CODE_RETURN_FROM_START_FN: &str = r#"
(module
(import "env" "ext_return" (func $ext_return (param i32 i32)))
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32)))
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32)))
(import "env" "memory" (memory 1 1))

(start $start)
(func $start
(call $ext_deposit_event
(i32.const 8)
(i32.const 4)
(i32.const 0) ;; The topics buffer
(i32.const 0) ;; The topics buffer's length
(i32.const 8) ;; The data buffer
(i32.const 4) ;; The data buffer's length
)
(call $ext_return
(i32.const 8)
Expand All @@ -337,7 +339,7 @@ const CODE_RETURN_FROM_START_FN: &str = r#"
(data (i32.const 8) "\01\02\03\04")
)
"#;
const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("abb4194bdea47b2904fe90b4fd674bd40d96f423956627df8c39d2b1a791ab9d");
const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("66c45bd7c473a1746e1d241176166ef53b1f207f56c5e87d1b6650140704181b");

#[test]
fn instantiate_and_call_and_deposit_event() {
Expand Down
Loading