| 95 | } |
| 96 | |
| 97 | pub fn get_init_code( |
| 98 | config: &DVFConfig, |
| 99 | tx_id: &String, |
| 100 | address: &Address, |
| 101 | ) -> Result<String, ValidationError> { |
| 102 | info!("Get init code for is {}", address); |
| 103 | |
| 104 | // create a mapping for failed traces |
| 105 | let mut failed_parity_traces: HashMap<Vec<usize>, bool> = HashMap::new(); |
| 106 | |
| 107 | match get_tx_trace(config, tx_id) { |
| 108 | Ok(trace) => { |
| 109 | for frame in &trace { |
| 110 | let trace_address = &frame.trace_address; |
| 111 | |
| 112 | if frame.error.is_some() |
| 113 | || (trace_address.len() > 1 |
| 114 | && failed_parity_traces |
| 115 | .contains_key(&trace_address[..trace_address.len() - 1])) |
| 116 | { |
| 117 | failed_parity_traces.insert(trace_address.clone(), true); // make subtraces fail |
| 118 | continue; |
| 119 | } |
| 120 | |
| 121 | if let (Action::Create(create_action), Some(Res::Create(create_res))) = |
| 122 | (&frame.action, &frame.result) |
| 123 | { |
| 124 | if &create_res.address == address { |
| 125 | let init_code = format!("{:#x}", create_action.init); |
| 126 | return Ok(init_code); |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | Err(ValidationError::from(format!( |
| 131 | "Found no deployment trace for tx {:?} and contract {:?}", |
| 132 | tx_id, address |
| 133 | )))? |
| 134 | } |
| 135 | Err(_e) => { |
| 136 | let call_frame = get_eth_debug_call_trace(config, tx_id)?; |
| 137 | |
| 138 | match extract_create_call_frame(&call_frame, address) { |
| 139 | Ok(call_frame) => { |
| 140 | let init_code = format!("{:#x}", call_frame.input); |
| 141 | Ok(init_code) |
| 142 | } |
| 143 | Err(e) => Err(e), |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | // Searches recursively for create call frame |
| 150 | // Ignores reverting call frames |