Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rusk: Enrich contract events with transaction id #2296

Merged
merged 1 commit into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions rusk/src/lib/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,4 +1293,18 @@ mod tests {
let data = data.to_vec().into();
Ok(RuesEvent { data, headers, uri })
}

impl From<ContractEvent> 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(),
}
}
}
}
30 changes: 10 additions & 20 deletions rusk/src/lib/http/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -835,16 +835,6 @@ impl From<execution_core::Event> for ContractEvent {
}
}

impl From<ContractEvent> 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 {
Expand Down Expand Up @@ -982,26 +972,26 @@ impl RuesEvent {
}
}

impl From<ContractEvent> for RuesEvent {
fn from(event: ContractEvent) -> Self {
#[cfg(feature = "node")]
impl From<crate::node::ContractTxEvent> 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<execution_core::Event> for RuesEvent {
fn from(event: execution_core::Event) -> Self {
Self::from(ContractEvent::from(event))
}
}

#[cfg(feature = "node")]
impl From<node_data::events::Event> for RuesEvent {
fn from(value: node_data::events::Event) -> Self {
Expand Down
2 changes: 2 additions & 0 deletions rusk/src/lib/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
60 changes: 50 additions & 10 deletions rusk/src/lib/node/rusk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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();
Expand All @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -487,7 +506,7 @@ fn accept(
Vec<SpentTransaction>,
VerificationOutput,
Session,
Vec<Event>,
Vec<ContractTxEvent>,
)> {
let mut session = session;

Expand All @@ -501,15 +520,25 @@ fn accept(

for unspent_tx in txs {
let tx = &unspent_tx.inner;
let tx_id = unspent_tx.id();
let receipt = execute(
&mut session,
tx,
gas_per_deploy_byte,
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;

Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
8 changes: 7 additions & 1 deletion rusk/src/lib/node/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<I: Iterator<Item = Transaction>>(
&self,
Expand Down
Loading