@@ -76,7 +76,7 @@ impl ContractRuntime {
7676 rx. await ?
7777 }
7878
79- pub async fn invoke ( & self , method : & str , params : Value ) -> Result < Response > {
79+ pub async fn invoke ( & self , method : & str , params : Value ) -> Result < InvokeResponse > {
8080 let ( tx, rx) = oneshot:: channel ( ) ;
8181 if self
8282 . tx
@@ -92,6 +92,22 @@ impl ContractRuntime {
9292 rx. await ?
9393 }
9494
95+ pub async fn handle_submit ( & self , tx_id : & str , new_tx : NewTx ) -> Result < ( ) > {
96+ let ( tx, rx) = oneshot:: channel ( ) ;
97+ if self
98+ . tx
99+ . send ( ContractRuntimeCommand :: HandleSubmit {
100+ tx_id : tx_id. to_string ( ) ,
101+ new_tx,
102+ done : tx,
103+ } )
104+ . is_err ( )
105+ {
106+ bail ! ( "runtime for contract {} has stopped" , self . contract) ;
107+ }
108+ rx. await ?
109+ }
110+
95111 pub async fn apply ( & self , rollbacks : & [ BlockInfo ] , block : & BlockInfo ) -> Result < ( ) > {
96112 let ( tx, rx) = oneshot:: channel ( ) ;
97113 if self
@@ -139,7 +155,12 @@ enum ContractRuntimeCommand {
139155 Invoke {
140156 method : String ,
141157 params : Value ,
142- done : oneshot:: Sender < Result < Response > > ,
158+ done : oneshot:: Sender < Result < InvokeResponse > > ,
159+ } ,
160+ HandleSubmit {
161+ tx_id : String ,
162+ new_tx : NewTx ,
163+ done : oneshot:: Sender < Result < ( ) > > ,
143164 } ,
144165 Apply {
145166 rollbacks : Vec < BlockInfo > ,
@@ -194,6 +215,13 @@ impl ContractRuntimeWorker {
194215 } => {
195216 let _ = done. send ( self . invoke ( & method, params) . await ) ;
196217 }
218+ ContractRuntimeCommand :: HandleSubmit {
219+ tx_id,
220+ new_tx,
221+ done,
222+ } => {
223+ let _ = done. send ( self . handle_submit ( & tx_id, new_tx) . await ) ;
224+ }
197225 ContractRuntimeCommand :: Apply {
198226 rollbacks,
199227 block,
@@ -241,14 +269,53 @@ impl ContractRuntimeWorker {
241269 Ok ( ( ) )
242270 }
243271
244- async fn invoke ( & mut self , method : & str , params : Value ) -> Result < Response > {
272+ async fn invoke ( & mut self , method : & str , params : Value ) -> Result < InvokeResponse > {
245273 let params = serde_json:: to_vec ( & params) ?;
246274 let Some ( runtime) = self . runtime . as_mut ( ) else {
247275 bail ! ( "Contract {} failed to initialize" , self . contract) ;
248276 } ;
249- Ok ( runtime
277+ let response = runtime
250278 . handle_request ( & self . contract , method, params)
251- . await ?)
279+ . await ?;
280+ match response {
281+ Response :: Acknowledge => Ok ( InvokeResponse :: Json ( json ! ( { } ) ) ) ,
282+ Response :: Cbor ( bytes) => Ok ( InvokeResponse :: Json ( json ! ( { "cbor" : bytes } ) ) ) ,
283+ Response :: PartialTx ( bytes) => Ok ( InvokeResponse :: NewTx ( NewTx {
284+ bytes,
285+ method : method. to_string ( ) ,
286+ condition : None ,
287+ } ) ) ,
288+ Response :: Json ( bytes) => {
289+ let value: Value = serde_json:: from_slice ( & bytes) ?;
290+ if let Ok ( RawNewTx :: FireFlyCardanoNewTx { bytes, condition } ) =
291+ serde_json:: from_value ( value. clone ( ) )
292+ {
293+ Ok ( InvokeResponse :: NewTx ( NewTx {
294+ bytes : hex:: decode ( bytes) ?,
295+ method : method. to_string ( ) ,
296+ condition : Some ( condition) ,
297+ } ) )
298+ } else {
299+ Ok ( InvokeResponse :: Json ( value) )
300+ }
301+ }
302+ }
303+ }
304+
305+ async fn handle_submit ( & mut self , tx_id : & str , new_tx : NewTx ) -> Result < ( ) > {
306+ if let Some ( condition) = new_tx. condition {
307+ let mut monitored_txs: HashMap < String , FinalizationCondition > =
308+ self . get_value ( "__monitored_txs" ) . await ?. unwrap_or_default ( ) ;
309+ monitored_txs. insert ( tx_id. to_string ( ) , condition) ;
310+ self . set_value ( "__monitored_txs" , monitored_txs) . await ?;
311+ }
312+
313+ let params = json ! ( {
314+ "method" : new_tx. method,
315+ "hash" : tx_id,
316+ } ) ;
317+ let _: Result < _ , _ > = self . invoke ( "__tx_submitted" , params) . await ;
318+ Ok ( ( ) )
252319 }
253320
254321 async fn apply ( & mut self , rollbacks : & [ BlockInfo ] , block : & BlockInfo ) -> Result < ( ) > {
@@ -419,14 +486,34 @@ pub struct ContractEvent {
419486 pub data : serde_json:: Value ,
420487}
421488
489+ pub enum InvokeResponse {
490+ Json ( Value ) ,
491+ NewTx ( NewTx ) ,
492+ }
493+
494+ pub struct NewTx {
495+ pub bytes : Vec < u8 > ,
496+ method : String ,
497+ condition : Option < FinalizationCondition > ,
498+ }
499+
500+ #[ derive( Debug , Serialize , Deserialize ) ]
501+ enum FinalizationCondition {
502+ AfterBlocks ( u64 ) ,
503+ }
504+
422505#[ derive( Debug , Clone , Serialize , Deserialize ) ]
423506struct RawEvent {
424507 pub tx_hash : Vec < u8 > ,
425508 pub signature : String ,
426509 pub data : serde_json:: Value ,
427510}
428511
429- #[ derive( Debug , Serialize , Deserialize ) ]
430- enum FinalizationCondition {
431- AfterBlocks ( u64 ) ,
512+ #[ derive( Deserialize ) ]
513+ #[ serde( tag = "type" ) ]
514+ enum RawNewTx {
515+ FireFlyCardanoNewTx {
516+ bytes : String ,
517+ condition : FinalizationCondition ,
518+ } ,
432519}
0 commit comments