kabu_broadcast_accounts/signers/
initialize_actor.rs

1use alloy_primitives::{B256, Bytes, hex};
2use eyre::eyre;
3use kabu_core_components::Component;
4use std::sync::Arc;
5use tokio::sync::RwLock;
6use tracing::info;
7
8use kabu_core_blockchain::Blockchain;
9use kabu_types_entities::{AccountNonceAndBalanceState, KeyStore, LoomTxSigner, TxSigners};
10use reth_ethereum_primitives::EthPrimitives;
11use reth_node_types::NodePrimitives;
12
13/// The one-shot component adds a new signer to the signers and monitor list after and stops.
14#[derive(Clone)]
15pub struct InitializeSignersOneShotBlockingComponent<LDT: NodePrimitives> {
16    key: Option<Vec<u8>>,
17    signers: Option<Arc<RwLock<TxSigners<LDT>>>>,
18    monitor: Option<Arc<RwLock<AccountNonceAndBalanceState>>>,
19}
20
21async fn initialize_signers_one_shot_worker(
22    key: Vec<u8>,
23    signers: Arc<RwLock<TxSigners<EthPrimitives>>>,
24    monitor: Arc<RwLock<AccountNonceAndBalanceState>>,
25) -> eyre::Result<()> {
26    let new_signer = signers.write().await.add_privkey(Bytes::from(key));
27    monitor.write().await.add_account(new_signer.address());
28    info!("New signer added {:?}", new_signer.address());
29    Ok(())
30}
31
32impl<LDT: NodePrimitives> InitializeSignersOneShotBlockingComponent<LDT> {
33    pub fn new(key: Option<Vec<u8>>) -> InitializeSignersOneShotBlockingComponent<LDT> {
34        let key = key.unwrap_or_else(|| B256::random().to_vec());
35
36        InitializeSignersOneShotBlockingComponent { key: Some(key), signers: None, monitor: None }
37    }
38
39    pub fn new_from_encrypted_env() -> InitializeSignersOneShotBlockingComponent<LDT> {
40        let key = match std::env::var("DATA") {
41            Ok(priv_key_enc) => {
42                let keystore = KeyStore::new();
43                let key = keystore.encrypt_once(hex::decode(priv_key_enc).unwrap().as_slice()).unwrap();
44                Some(key)
45            }
46            _ => None,
47        };
48
49        InitializeSignersOneShotBlockingComponent { key, signers: None, monitor: None }
50    }
51
52    pub fn new_from_encrypted_key(priv_key_enc: Vec<u8>) -> InitializeSignersOneShotBlockingComponent<LDT> {
53        let keystore = KeyStore::new();
54        let key = keystore.encrypt_once(priv_key_enc.as_slice()).unwrap();
55
56        InitializeSignersOneShotBlockingComponent { key: Some(key), signers: None, monitor: None }
57    }
58
59    pub fn on_bc(self, bc: &Blockchain<LDT>) -> Self {
60        Self { monitor: Some(bc.nonce_and_balance()), ..self }
61    }
62
63    pub fn with_signers(self, signers: Arc<RwLock<TxSigners<LDT>>>) -> Self {
64        Self { signers: Some(signers), ..self }
65    }
66
67    pub fn with_monitor(self, monitor: Arc<RwLock<AccountNonceAndBalanceState>>) -> Self {
68        Self { monitor: Some(monitor), ..self }
69    }
70}
71
72impl Component for InitializeSignersOneShotBlockingComponent<EthPrimitives> {
73    fn spawn(self, executor: reth_tasks::TaskExecutor) -> eyre::Result<()> {
74        let name = self.name();
75        let key = self.key.ok_or_else(|| eyre!("No signer keys found"))?;
76        let signers = self.signers.ok_or_else(|| eyre!("Signers not initialized"))?;
77        let monitor = self.monitor.ok_or_else(|| eyre!("Monitor not initialized"))?;
78
79        executor.spawn_critical(name, async move {
80            if let Err(e) = initialize_signers_one_shot_worker(key, signers, monitor).await {
81                tracing::error!("Initialize signers failed: {}", e);
82            }
83        });
84        Ok(())
85    }
86
87    fn name(&self) -> &'static str {
88        "InitializeSignersOneShotBlockingComponent"
89    }
90}