diff --git a/balius-runtime/src/lib.rs b/balius-runtime/src/lib.rs index c58ca63..582e525 100644 --- a/balius-runtime/src/lib.rs +++ b/balius-runtime/src/lib.rs @@ -136,6 +136,11 @@ pub enum Tx { } impl Tx { + pub fn hash(&self) -> Vec { + match self { + Self::Cardano(tx) => tx.hash.clone().into(), + } + } pub fn outputs(&self) -> Vec { match self { Self::Cardano(tx) => tx @@ -153,6 +158,16 @@ pub enum Block { } impl Block { + pub fn hash(&self) -> Vec { + match self { + Self::Cardano(block) => block.header.as_ref().unwrap().hash.clone().into(), + } + } + pub fn height(&self) -> u64 { + match self { + Self::Cardano(block) => block.header.as_ref().unwrap().height, + } + } pub fn txs(&self) -> Vec { match self { Self::Cardano(block) => block @@ -245,11 +260,23 @@ impl LoadedWorker { } async fn apply_block(&mut self, block: &Block) -> Result<(), Error> { + let block_hash = block.hash(); + let block_height = block.height(); for tx in block.txs() { - for utxo in tx.outputs() { + let tx_hash = tx.hash(); + for (index, utxo) in tx.outputs().into_iter().enumerate() { let channels = self.wasm_store.data().router.find_utxo_targets(&utxo)?; + if channels.is_empty() { + continue; + } - let event = wit::Event::Utxo(utxo.to_bytes()); + let event = wit::Event::Utxo(wit::balius::app::driver::Utxo { + block_hash: block_hash.clone(), + block_height, + tx_hash: tx_hash.clone(), + index: index as u64, + utxo: utxo.to_bytes(), + }); for channel in channels { self.acknowledge_event(channel, &event).await?; @@ -261,11 +288,23 @@ impl LoadedWorker { } async fn undo_block(&mut self, block: &Block) -> Result<(), Error> { + let block_hash = block.hash(); + let block_height = block.height(); for tx in block.txs() { - for utxo in tx.outputs() { + let tx_hash = tx.hash(); + for (index, utxo) in tx.outputs().into_iter().enumerate() { let channels = self.wasm_store.data().router.find_utxo_targets(&utxo)?; + if channels.is_empty() { + continue; + } - let event = wit::Event::UtxoUndo(utxo.to_bytes()); + let event = wit::Event::UtxoUndo(wit::balius::app::driver::Utxo { + block_hash: block_hash.clone(), + block_height, + tx_hash: tx_hash.clone(), + index: index as u64, + utxo: utxo.to_bytes(), + }); for channel in channels { self.acknowledge_event(channel, &event).await?; diff --git a/balius-sdk/src/qol.rs b/balius-sdk/src/qol.rs index a16658a..029e762 100644 --- a/balius-sdk/src/qol.rs +++ b/balius-sdk/src/qol.rs @@ -220,6 +220,10 @@ impl std::ops::Deref for Json { } pub struct Utxo { + pub block_hash: Vec, + pub block_height: u64, + pub tx_hash: Vec, + pub index: u64, pub utxo: utxorpc_spec::utxorpc::v1alpha::cardano::TxOutput, pub datum: Option, } @@ -230,15 +234,26 @@ impl TryFrom for Utxo { fn try_from(value: wit::Event) -> Result { use prost::Message; - let bytes = match value { + let utxo = match value { wit::Event::Utxo(x) => x, wit::Event::UtxoUndo(x) => x, _ => return Err(Error::EventMismatch("utxo|utxoundo".to_owned())), }; - let utxo = Message::decode(bytes.as_slice()).map_err(|_| Self::Error::BadUtxo)?; - - Ok(Utxo { utxo, datum: None }) + let block_hash = utxo.block_hash; + let block_height = utxo.block_height; + let tx_hash = utxo.tx_hash; + let index = utxo.index; + let utxo = Message::decode(utxo.utxo.as_slice()).map_err(|_| Self::Error::BadUtxo)?; + + Ok(Utxo { + block_hash, + block_height, + tx_hash, + index, + utxo, + datum: None, + }) } } diff --git a/wit/balius.wit b/wit/balius.wit index c554148..1e36ed4 100644 --- a/wit/balius.wit +++ b/wit/balius.wit @@ -78,9 +78,17 @@ interface driver { type timestamp = u64; type params = json; + record utxo { + block-hash: list, + block-height: u64, + tx-hash: list, + index: u64, + utxo: cbor, + } + variant event { - utxo(cbor), - utxo-undo(cbor), + utxo(utxo), + utxo-undo(utxo), timer(timestamp), request(params), message(json),