From af1016bafdb70ab47b0fc2b71e5c2f60cb800b3f Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Sat, 7 Sep 2024 12:02:24 +0200 Subject: [PATCH] rusk: Enrich contract events with transaction id --- rusk/src/lib/http.rs | 14 +++++++++ rusk/src/lib/http/event.rs | 30 +++++++------------ rusk/src/lib/node.rs | 2 ++ rusk/src/lib/node/rusk.rs | 60 +++++++++++++++++++++++++++++++------- rusk/src/lib/node/vm.rs | 8 ++++- 5 files changed, 83 insertions(+), 31 deletions(-) diff --git a/rusk/src/lib/http.rs b/rusk/src/lib/http.rs index 64eb6e4122..5e636b0399 100644 --- a/rusk/src/lib/http.rs +++ b/rusk/src/lib/http.rs @@ -1293,4 +1293,18 @@ mod tests { let data = data.to_vec().into(); Ok(RuesEvent { data, headers, uri }) } + + impl From for RuesEvent { + fn from(event: ContractEvent) -> Self { + Self { + uri: RuesEventUri { + component: "contracts".into(), + entity: Some(hex::encode(event.target.0.as_bytes())), + topic: event.topic, + }, + data: event.data.into(), + headers: Default::default(), + } + } + } } diff --git a/rusk/src/lib/http/event.rs b/rusk/src/lib/http/event.rs index 66e02e76d2..b59bc9c0d8 100644 --- a/rusk/src/lib/http/event.rs +++ b/rusk/src/lib/http/event.rs @@ -835,16 +835,6 @@ impl From for ContractEvent { } } -impl From for execution_core::Event { - fn from(event: ContractEvent) -> Self { - Self { - source: event.target.0, - topic: event.topic, - data: event.data, - } - } -} - /// A RUES event #[derive(Debug, Clone, Eq, PartialEq)] pub struct RuesEvent { @@ -982,26 +972,26 @@ impl RuesEvent { } } -impl From for RuesEvent { - fn from(event: ContractEvent) -> Self { +#[cfg(feature = "node")] +impl From for RuesEvent { + fn from(tx_event: crate::node::ContractTxEvent) -> Self { + let mut headers = serde_json::Map::new(); + if let Some(origin) = tx_event.origin { + headers.insert("Rusk-Origin".into(), hex::encode(origin).into()); + } + let event = tx_event.event; Self { uri: RuesEventUri { component: "contracts".into(), - entity: Some(hex::encode(event.target.0.as_bytes())), + entity: Some(hex::encode(event.source.as_bytes())), topic: event.topic, }, data: event.data.into(), - headers: Default::default(), + headers, } } } -impl From for RuesEvent { - fn from(event: execution_core::Event) -> Self { - Self::from(ContractEvent::from(event)) - } -} - #[cfg(feature = "node")] impl From for RuesEvent { fn from(value: node_data::events::Event) -> Self { diff --git a/rusk/src/lib/node.rs b/rusk/src/lib/node.rs index f347e46819..f6bc3ff0a2 100644 --- a/rusk/src/lib/node.rs +++ b/rusk/src/lib/node.rs @@ -31,6 +31,8 @@ use tokio::sync::{broadcast, mpsc}; use crate::http::{HandleRequest, RuesEvent}; +pub use vm::ContractTxEvent; + #[derive(Debug, Clone, Copy)] pub struct RuskTip { pub current: [u8; 32], diff --git a/rusk/src/lib/node/rusk.rs b/rusk/src/lib/node/rusk.rs index 921c422f87..8757b4b807 100644 --- a/rusk/src/lib/node/rusk.rs +++ b/rusk/src/lib/node/rusk.rs @@ -37,6 +37,7 @@ use rusk_abi::{CallReceipt, PiecrustError, Session, VM}; use rusk_profile::to_rusk_state_id_path; use tokio::sync::broadcast; +use super::vm::ContractTxEvent; use super::{coinbase_value, Rusk, RuskTip}; use crate::gen_id::gen_contract_id; use crate::http::RuesEvent; @@ -142,9 +143,10 @@ impl Rusk { break; } - let tx_id = hex::encode(unspent_tx.id()); + let tx_id = unspent_tx.id(); + let tx_id_hex = hex::encode(unspent_tx.id()); if unspent_tx.inner.gas_limit() > block_gas_left { - info!("Skipping {tx_id} due gas_limit greater than left: {block_gas_left}"); + info!("Skipping {tx_id_hex} due gas_limit greater than left: {block_gas_left}"); continue; } @@ -180,9 +182,18 @@ impl Rusk { // We're currently ignoring the result of successful calls let err = receipt.data.err().map(|e| format!("{e}")); - info!("Tx {tx_id} executed with {gas_spent} gas and err {err:?}"); + info!("Tx {tx_id_hex} executed with {gas_spent} gas and err {err:?}"); - update_hasher(&mut event_hasher, &receipt.events); + let tx_events: Vec<_> = receipt + .events + .into_iter() + .map(|event| ContractTxEvent { + event, + origin: Some(tx_id), + }) + .collect(); + + update_hasher(&mut event_hasher, &tx_events); block_gas_left -= gas_spent; let gas_price = unspent_tx.inner.gas_price(); @@ -205,7 +216,7 @@ impl Rusk { // nonce is unlocked } Err(e) => { - info!("discard tx {tx_id} due to {e:?}"); + info!("discard tx {tx_id_hex} due to {e:?}"); // An unspendable transaction should be discarded discarded_txs.push(unspent_tx); continue; @@ -221,6 +232,14 @@ impl Rusk { to_slash, voters, )?; + + let coinbase_events: Vec<_> = coinbase_events + .into_iter() + .map(|event| ContractTxEvent { + event, + origin: None, + }) + .collect(); update_hasher(&mut event_hasher, &coinbase_events); let state_root = session.root(); @@ -487,7 +506,7 @@ fn accept( Vec, VerificationOutput, Session, - Vec, + Vec, )> { let mut session = session; @@ -501,6 +520,7 @@ fn accept( for unspent_tx in txs { let tx = &unspent_tx.inner; + let tx_id = unspent_tx.id(); let receipt = execute( &mut session, tx, @@ -508,8 +528,17 @@ fn accept( min_deployment_gas_price, )?; - update_hasher(&mut event_hasher, &receipt.events); - events.extend(receipt.events); + let tx_events: Vec<_> = receipt + .events + .into_iter() + .map(|event| ContractTxEvent { + event, + origin: Some(tx_id), + }) + .collect(); + + update_hasher(&mut event_hasher, &tx_events); + events.extend(tx_events); let gas_spent = receipt.gas_spent; @@ -536,6 +565,13 @@ fn accept( voters, )?; + let coinbase_events: Vec<_> = coinbase_events + .into_iter() + .map(|event| ContractTxEvent { + event, + origin: None, + }) + .collect(); update_hasher(&mut event_hasher, &coinbase_events); events.extend(coinbase_events); @@ -714,8 +750,12 @@ fn execute( Ok(receipt) } -fn update_hasher(hasher: &mut Sha3_256, events: &[Event]) { - for event in events { +fn update_hasher(hasher: &mut Sha3_256, events: &[ContractTxEvent]) { + for tx_event in events { + if let Some(origin) = tx_event.origin { + hasher.update(origin); + } + let event = &tx_event.event; hasher.update(event.source.as_bytes()); hasher.update(event.topic.as_bytes()); hasher.update(&event.data); diff --git a/rusk/src/lib/node/vm.rs b/rusk/src/lib/node/vm.rs index f18e0ba807..2b8fcbfb45 100644 --- a/rusk/src/lib/node/vm.rs +++ b/rusk/src/lib/node/vm.rs @@ -14,13 +14,19 @@ use dusk_consensus::user::provisioners::Provisioners; use dusk_consensus::user::stake::Stake; use execution_core::{ signatures::bls::PublicKey as BlsPublicKey, stake::StakeData, - transfer::Transaction as ProtocolTransaction, + transfer::Transaction as ProtocolTransaction, Event, }; use node::vm::VMExecution; use node_data::ledger::{Block, Slash, SpentTransaction, Transaction}; use super::Rusk; +#[derive(Debug, Clone)] +pub struct ContractTxEvent { + pub event: Event, + pub origin: Option<[u8; 32]>, +} + impl VMExecution for Rusk { fn execute_state_transition>( &self,