Skip to content

Commit

Permalink
fix: cucumber test for events, remove resource event
Browse files Browse the repository at this point in the history
  • Loading branch information
sdbondi committed Jan 27, 2025
1 parent c2d22d3 commit 2cad0d0
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 40 deletions.
4 changes: 2 additions & 2 deletions dan_layer/engine/src/runtime/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,8 @@ pub enum RuntimeError {
#[error("Address allocation type mismatch: {address}")]
AddressAllocationTypeMismatch { address: SubstateId },

#[error("Invalid event topic {topic}")]
InvalidEventTopic { topic: String },
#[error("Invalid event topic '{topic}': 'std' prefix is reserved for built-in events")]
InvalidEventTopicStdPrefix { topic: String },

#[error("Numeric conversion error: {details}")]
NumericConversionError { details: String },
Expand Down
50 changes: 18 additions & 32 deletions dan_layer/engine/src/runtime/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,6 @@ use crate::{

const LOG_TARGET: &str = "tari::dan::engine::runtime::impl";

// Topics for builtin events emmitted by the engine
const STANDARD_TOPIC_PREFIX: &str = "std.";
const VAULT_DEPOSIT_TOPIC: &str = "std.vault.deposit";
const VAULT_WITHDRAW_TOPIC: &str = "std.vault.withdraw";

#[derive(Clone)]
pub struct RuntimeInterfaceImpl<TTemplateProvider> {
tracker: StateTracker,
Expand Down Expand Up @@ -224,45 +219,36 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte

fn emit_vault_events<T: Into<String>>(
&self,
topic: T,
action: T,
vault_id: VaultId,
vault_lock: &LockedSubstate,
amount: Amount,
resource_type: ResourceType,
state: &mut WorkingState,
) -> Result<(), RuntimeError> {
let tx_hash = self.entity_id_provider.transaction_hash();
let (template_address, _) = state.current_template()?;
let resource_address = state.get_vault(vault_lock)?.resource_address();
let (&template_address, _) = state.current_template()?;
let &resource_address = state.get_vault(vault_lock)?.resource_address();

let mut payload = Metadata::new();
payload.insert("vault_id", vault_id.to_string());
payload.insert("resource_address", resource_address.to_string());
payload.insert("resource_type", resource_type.to_string());
payload.insert("amount", amount.to_string());
let payload = Metadata::from_iter([
("vault_id", vault_id.to_string()),
("resource_address", resource_address.to_string()),
("resource_type", resource_type.to_string()),
("amount", amount.to_string()),
]);

let topic = topic.into();
let action = action.into();

// we emit multiple events referencing vault and resource address
// this way indexers/clients can search by any one
let vault_event = Event::new(
let vault_event = Event::std(
Some(SubstateId::Vault(vault_id)),
*template_address,
tx_hash,
topic.clone(),
payload.clone(),
);
let resource_event = Event::new(
Some(SubstateId::Resource(*resource_address)),
*template_address,
template_address,
tx_hash,
topic,
"vault",
&action,
payload,
);
debug!(target: LOG_TARGET, "Emitted vault event {}", vault_event);
debug!(target: LOG_TARGET, "Emitted resource event {}", resource_event);
state.push_event(vault_event);
state.push_event(resource_event);

Ok(())
}
Expand Down Expand Up @@ -425,8 +411,8 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte

fn emit_event(&self, topic: String, payload: Metadata) -> Result<(), RuntimeError> {
// forbid template users to emit events that can be confused with the ones emitted by the engine
if topic.starts_with(STANDARD_TOPIC_PREFIX) {
return Err(RuntimeError::InvalidEventTopic { topic });
if Event::topic_has_std_prefix(&topic) {
return Err(RuntimeError::InvalidEventTopicStdPrefix { topic });
}

self.invoke_modules_on_runtime_call("emit_event")?;
Expand Down Expand Up @@ -1194,7 +1180,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte

// Emit a builtin event for the deposit
self.emit_vault_events(
VAULT_DEPOSIT_TOPIC.to_owned(),
"deposit",
vault_id,
&vault_lock,
bucket.amount(),
Expand Down Expand Up @@ -1270,7 +1256,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte

// Emit a builtin event for the withdraw
self.emit_vault_events(
VAULT_WITHDRAW_TOPIC,
"withdraw",
vault_id,
&vault_lock,
amount,
Expand Down
5 changes: 3 additions & 2 deletions dan_layer/engine/src/runtime/tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,12 @@ impl StateTracker {

state.new_substate(substate_id.clone(), SubstateValue::Component(component))?;

state.push_event(Event::new(
state.push_event(Event::std(
Some(substate_id),
template_address,
state.transaction_hash(),
"component-created".to_string(),
"component",
"created",
Metadata::from([("module_name".to_string(), module_name)]),
));

Expand Down
5 changes: 3 additions & 2 deletions dan_layer/engine/src/runtime/working_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,12 @@ impl WorkingState {

// add event to indicate that there is a change in component
let (template_address, module_name) = self.current_template().map(|(addr, name)| (*addr, name.to_string()))?;
self.push_event(Event::new(
self.push_event(Event::std(
Some(locked.address().clone()),
template_address,
self.transaction_hash(),
"std.component.updated".to_string(),
"component",
"updated",
tari_template_lib::models::Metadata::from([("module_name".to_string(), module_name)]),
));

Expand Down
2 changes: 1 addition & 1 deletion dan_layer/engine/tests/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn cannot_use_standard_topic() {
.build_and_seal(&private_key),
[].into(),
);
assert_reject_reason(reason, RuntimeError::InvalidEventTopic {
assert_reject_reason(reason, RuntimeError::InvalidEventTopicStdPrefix {
topic: invalid_topic.to_owned(),
});
}
Expand Down
28 changes: 28 additions & 0 deletions dan_layer/engine_types/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ use ts_rs::TS;

use crate::{serde_with, substate::SubstateId};

// Topics for builtin events emitted by the engine
const STANDARD_TOPIC_PREFIX: &str = "std";

fn std_event(object_name: &str, action_name: &str) -> String {
format!("{}.{}.{}", STANDARD_TOPIC_PREFIX, object_name, action_name)
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "ts", derive(TS), ts(export, export_to = "../../bindings/src/types/"))]
pub struct Event {
Expand Down Expand Up @@ -65,6 +72,27 @@ impl Event {
}
}

pub fn std(
substate_id: Option<SubstateId>,
template_address: TemplateAddress,
tx_hash: Hash,
object_name: &str,
action_name: &str,
payload: Metadata,
) -> Self {
Self::new(
substate_id,
template_address,
tx_hash,
std_event(object_name, action_name),
payload,
)
}

pub fn topic_has_std_prefix<T: AsRef<str>>(topic: T) -> bool {
topic.as_ref().starts_with(STANDARD_TOPIC_PREFIX)
}

pub fn substate_id(&self) -> Option<&SubstateId> {
self.substate_id.as_ref()
}
Expand Down
8 changes: 8 additions & 0 deletions dan_layer/template_lib/src/models/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ impl IntoIterator for Metadata {
}
}

impl<K: ToString, V: Into<String>> FromIterator<(K, V)> for Metadata {
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
Self(BorTag::new(
iter.into_iter().map(|(k, v)| (k.to_string(), v.into())).collect(),
))
}
}

impl Default for Metadata {
fn default() -> Self {
Self::new()
Expand Down
2 changes: 1 addition & 1 deletion integration_tests/tests/features/indexer.feature
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Feature: Indexer node
# Then the indexer IDX returns 6 non fungibles for resource NFT/resources/0

# Scan the network for the event emitted on ACC creation
When indexer IDX scans the network events for account ACC with topics component-created,pay_fee,pay_fee,pay_fee,pay_fee,pay_fee,pay_fee,pay_fee,deposit,component-created,pay_fee,pay_fee,deposit,deposit,deposit,deposit,deposit,deposit
When indexer IDX scans the network events for account ACC with topics std.component.created,pay_fee,pay_fee,pay_fee,pay_fee,pay_fee,pay_fee,pay_fee,deposit,std.component.updated,std.component.created,pay_fee,pay_fee,deposit,std.component.updated,deposit,deposit,deposit,deposit,deposit

Scenario: Indexer GraphQL requests work
# Initialize a base node, wallet, miner and VN
Expand Down

0 comments on commit 2cad0d0

Please sign in to comment.