use alloy_evm::Database;
use alloy_primitives::{address, Address};
use revm::{
database::State,
state::{Account, Bytecode, EvmState},
};
use crate::MegaHardforks;
pub use crate::sandbox::{
calculate_keyless_deploy_address, decode_keyless_tx, encode_error_result, recover_signer,
KeylessDeployError,
};
pub const KEYLESS_DEPLOY_ADDRESS: Address = address!("0x6342000000000000000000000000000000000003");
pub use mega_system_contracts::keyless_deploy::V1_0_0_CODE as KEYLESS_DEPLOY_CODE;
pub use mega_system_contracts::keyless_deploy::V1_0_0_CODE_HASH as KEYLESS_DEPLOY_CODE_HASH;
pub use mega_system_contracts::keyless_deploy::IKeylessDeploy;
pub fn transact_deploy_keyless_deploy_contract<DB: Database>(
hardforks: impl MegaHardforks,
block_timestamp: u64,
db: &mut State<DB>,
) -> Result<Option<EvmState>, DB::Error> {
if !hardforks.is_rex_2_active_at_timestamp(block_timestamp) {
return Ok(None);
}
let acc = db.load_cache_account(KEYLESS_DEPLOY_ADDRESS)?;
if let Some(account_info) = acc.account_info() {
if account_info.code_hash == KEYLESS_DEPLOY_CODE_HASH {
return Ok(Some(EvmState::from_iter([(
KEYLESS_DEPLOY_ADDRESS,
Account { info: account_info, ..Default::default() },
)])));
}
}
let mut acc_info = acc.account_info().unwrap_or_default();
acc_info.code_hash = KEYLESS_DEPLOY_CODE_HASH;
acc_info.code = Some(Bytecode::new_raw(KEYLESS_DEPLOY_CODE));
let mut revm_acc: revm::state::Account = acc_info.into();
revm_acc.mark_touch();
revm_acc.mark_created();
Ok(Some(EvmState::from_iter([(KEYLESS_DEPLOY_ADDRESS, revm_acc)])))
}