11//! The test driver handles the compilation and execution of the test cases.
22
3+ use alloy:: json_abi:: JsonAbi ;
34use alloy:: primitives:: Bytes ;
4- use alloy:: rpc:: types:: TransactionInput ;
5+ use alloy:: rpc:: types:: trace:: geth:: GethTrace ;
6+ use alloy:: rpc:: types:: { TransactionInput , TransactionReceipt } ;
57use alloy:: {
68 primitives:: { Address , TxKind , map:: HashMap } ,
79 rpc:: types:: {
8- TransactionReceipt , TransactionRequest ,
9- trace:: geth:: { AccountState , DiffMode , GethTrace } ,
10+ TransactionRequest ,
11+ trace:: geth:: { AccountState , DiffMode } ,
1012 } ,
1113} ;
1214use revive_dt_compiler:: { Compiler , CompilerInput , SolidityCompiler } ;
@@ -15,7 +17,9 @@ use revive_dt_format::{input::Input, metadata::Metadata, mode::SolcMode};
1517use revive_dt_node_interaction:: EthereumNode ;
1618use revive_dt_report:: reporter:: { CompilationTask , Report , Span } ;
1719use revive_solc_json_interface:: SolcStandardJsonOutput ;
18- use tracing:: { Level , span} ;
20+ use serde_json:: Value ;
21+ use std:: collections:: HashMap as StdHashMap ;
22+ use tracing:: Level ;
1923
2024use crate :: Platform ;
2125
@@ -28,7 +32,8 @@ pub struct State<'a, T: Platform> {
2832 config : & ' a Arguments ,
2933 span : Span ,
3034 contracts : Contracts < T > ,
31- deployed_contracts : HashMap < String , Address > ,
35+ deployed_contracts : StdHashMap < String , Address > ,
36+ deployed_abis : StdHashMap < String , JsonAbi > ,
3237}
3338
3439impl < ' a , T > State < ' a , T >
4146 span,
4247 contracts : Default :: default ( ) ,
4348 deployed_contracts : Default :: default ( ) ,
49+ deployed_abis : Default :: default ( ) ,
4450 }
4551 }
4652
@@ -129,15 +135,21 @@ where
129135 std:: any:: type_name:: <T >( )
130136 ) ;
131137
132- let tx =
133- match input. legacy_transaction ( self . config . network_id , nonce, & self . deployed_contracts )
134- {
135- Ok ( tx) => tx,
136- Err ( err) => {
137- tracing:: error!( "Failed to construct legacy transaction: {err:?}" ) ;
138- return Err ( err) ;
139- }
140- } ;
138+ let tx = match input. legacy_transaction (
139+ self . config . network_id ,
140+ nonce,
141+ & self . deployed_contracts ,
142+ & self . deployed_abis ,
143+ ) {
144+ Ok ( tx) => {
145+ tracing:: debug!( "Legacy transaction data: {tx:#?}" ) ;
146+ tx
147+ }
148+ Err ( err) => {
149+ tracing:: error!( "Failed to construct legacy transaction: {err:?}" ) ;
150+ return Err ( err) ;
151+ }
152+ } ;
141153
142154 tracing:: trace!( "Executing transaction for input: {input:?}" ) ;
143155
@@ -194,9 +206,6 @@ where
194206 & contract_name,
195207 & input. instance
196208 ) ;
197- if contract_name != & input. instance {
198- continue ;
199- }
200209
201210 let bytecode = contract
202211 . evm
@@ -273,6 +282,52 @@ where
273282 address,
274283 std:: any:: type_name:: <T >( )
275284 ) ;
285+
286+ if let Some ( Value :: String ( metadata_json_str) ) = & contract. metadata {
287+ tracing:: trace!(
288+ "metadata found for contract {contract_name}, {metadata_json_str}"
289+ ) ;
290+
291+ match serde_json:: from_str :: < serde_json:: Value > ( metadata_json_str) {
292+ Ok ( metadata_json) => {
293+ if let Some ( abi_value) =
294+ metadata_json. get ( "output" ) . and_then ( |o| o. get ( "abi" ) )
295+ {
296+ match serde_json:: from_value :: < JsonAbi > ( abi_value. clone ( ) ) {
297+ Ok ( parsed_abi) => {
298+ tracing:: trace!(
299+ "ABI found in metadata for contract {}" ,
300+ & contract_name
301+ ) ;
302+ self . deployed_abis
303+ . insert ( contract_name. clone ( ) , parsed_abi) ;
304+ }
305+ Err ( err) => {
306+ anyhow:: bail!(
307+ "Failed to parse ABI from metadata for contract {}: {}" ,
308+ contract_name,
309+ err
310+ ) ;
311+ }
312+ }
313+ } else {
314+ anyhow:: bail!(
315+ "No ABI found in metadata for contract {}" ,
316+ contract_name
317+ ) ;
318+ }
319+ }
320+ Err ( err) => {
321+ anyhow:: bail!(
322+ "Failed to parse metadata JSON string for contract {}: {}" ,
323+ contract_name,
324+ err
325+ ) ;
326+ }
327+ }
328+ } else {
329+ anyhow:: bail!( "No metadata found for contract {}" , contract_name) ;
330+ }
276331 }
277332 }
278333 }
@@ -346,7 +401,7 @@ where
346401 for ( case_idx, case) in self . metadata . cases . iter ( ) . enumerate ( ) {
347402 // Creating a tracing span to know which case within the metadata is being executed
348403 // and which one we're getting logs for.
349- let tracing_span = span ! (
404+ let tracing_span = tracing :: span!(
350405 Level :: INFO ,
351406 "Executing case" ,
352407 case = case. name,
@@ -356,14 +411,45 @@ where
356411
357412 for input in & case. inputs {
358413 tracing:: debug!( "Starting deploying contract {}" , & input. instance) ;
359- leader_state. deploy_contracts ( input, self . leader_node ) ?;
360- follower_state. deploy_contracts ( input, self . follower_node ) ?;
414+ if let Err ( err) = leader_state. deploy_contracts ( input, self . leader_node ) {
415+ tracing:: error!( "Leader deployment failed for {}: {err}" , input. instance) ;
416+ continue ;
417+ } else {
418+ tracing:: debug!( "Leader deployment succeeded for {}" , & input. instance) ;
419+ }
420+
421+ if let Err ( err) = follower_state. deploy_contracts ( input, self . follower_node ) {
422+ tracing:: error!( "Follower deployment failed for {}: {err}" , input. instance) ;
423+ continue ;
424+ } else {
425+ tracing:: debug!( "Follower deployment succeeded for {}" , & input. instance) ;
426+ }
361427
362428 tracing:: debug!( "Starting executing contract {}" , & input. instance) ;
429+
363430 let ( leader_receipt, _, leader_diff) =
364- leader_state. execute_input ( input, self . leader_node ) ?;
431+ match leader_state. execute_input ( input, self . leader_node ) {
432+ Ok ( result) => result,
433+ Err ( err) => {
434+ tracing:: error!(
435+ "Leader execution failed for {}: {err}" ,
436+ input. instance
437+ ) ;
438+ continue ;
439+ }
440+ } ;
441+
365442 let ( follower_receipt, _, follower_diff) =
366- follower_state. execute_input ( input, self . follower_node ) ?;
443+ match follower_state. execute_input ( input, self . follower_node ) {
444+ Ok ( result) => result,
445+ Err ( err) => {
446+ tracing:: error!(
447+ "Follower execution failed for {}: {err}" ,
448+ input. instance
449+ ) ;
450+ continue ;
451+ }
452+ } ;
367453
368454 if leader_diff == follower_diff {
369455 tracing:: debug!( "State diffs match between leader and follower." ) ;
0 commit comments