You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: signer.rs
    path of file: ./repos/reth/crates/rpc/rpc/src/eth
    
    the code of the file until where you have to start completion: //! An abstraction over ethereum signers.

use crate::eth::error::SignError;
use alloy_dyn_abi::TypedData;
use reth_primitives::{
    eip191_hash_message, sign_message, Address, Signature, TransactionSigned, B256,
};
use reth_rpc_types::TypedTransactionRequest;

use dyn_clone::DynClone;
use reth_rpc_types_compat::transaction::to_primitive_
    
    pub(crate) fn random_signers(num: u32) -> Vec<Box<dyn EthSigner + 'static>> {
        let mut signers = Vec::new();
        for _ in 0..num {
            let (sk, pk) = secp256k1::generate_keypair(&mut rand::thread_rng());

            let address = reth_primitives::public_key_to_address(pk);
            let addresses = vec![address];
            let accounts = HashMap::from([(address, sk)]);
            signers.push(Box::new(DevSigner { addresses, accounts }) as Box<dyn EthSigner>);
        }
        signers
    }