arb_precompiles/
nodeinterface_debug.rs

1use alloy_evm::precompiles::{DynPrecompile, PrecompileInput};
2use alloy_primitives::{Address, U256};
3use alloy_sol_types::SolInterface;
4use revm::precompile::{PrecompileId, PrecompileOutput, PrecompileResult};
5
6use crate::interfaces::INodeInterfaceDebug;
7
8/// NodeInterfaceDebug virtual contract address (0xc9).
9pub const NODE_INTERFACE_DEBUG_ADDRESS: Address = Address::new([
10    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11    0x00, 0x00, 0x00, 0xc9,
12]);
13
14const COPY_GAS: u64 = 3;
15
16pub fn create_nodeinterface_debug_precompile() -> DynPrecompile {
17    DynPrecompile::new_stateful(PrecompileId::custom("nodeinterfacedebug"), handler)
18}
19
20fn handler(input: PrecompileInput<'_>) -> PrecompileResult {
21    let gas_limit = input.gas;
22    crate::init_precompile_gas(input.data.len());
23
24    let call = match INodeInterfaceDebug::NodeInterfaceDebugCalls::abi_decode(input.data) {
25        Ok(c) => c,
26        Err(_) => return crate::burn_all_revert(gas_limit),
27    };
28
29    use INodeInterfaceDebug::NodeInterfaceDebugCalls;
30    let result = match call {
31        NodeInterfaceDebugCalls::getRetryable(_) => handle_get_retryable(&input),
32    };
33    crate::gas_check(gas_limit, result)
34}
35
36/// Returns a well-formed empty `RetryableInfo` — bridge tooling gets a valid
37/// ABI response; populating it requires RPC-layer state access.
38fn handle_get_retryable(input: &PrecompileInput<'_>) -> PrecompileResult {
39    let mut out = vec![0u8; 7 * 32 + 32];
40    U256::from(7u64 * 32)
41        .to_be_bytes::<32>()
42        .iter()
43        .enumerate()
44        .for_each(|(i, b)| out[6 * 32 + i] = *b);
45    Ok(PrecompileOutput::new(COPY_GAS.min(input.gas), out.into()))
46}