pub async fn run_main_node(
    ctx: &ctx::Ctx,
    cfg: ConsensusConfig,
    secrets: ConsensusSecrets,
    pool: ConnectionPool,
) -> anyhow::Result<()> {
    let res: ctx::Result<()> = scope::run!(&ctx, |ctx, s| async {
        if let Some(spec) = &cfg.genesis_spec {
            let spec = config::GenesisSpec::parse(spec).context("GenesisSpec::parse()")?;

            pool.connection(ctx)
                .await
                .wrap("connection()")?
                .adjust_global_config(ctx, &spec)
                .await
                .wrap("adjust_global_config()")?;
        }

        // Initialize global config.
        let global_config = pool
            .connection(ctx)
            .await
            .wrap("connection()")?
            .global_config(ctx)
            .await
            .wrap("global_config()")?
            .context("global_config() disappeared")?;

        // Initialize registry.
        let registry = Arc::new(match global_config.registry_address {
            Some(addr) => Some(Registry::new(pool.clone(), RegistryAddress::new(addr)).await),
            None => None,
        });

        // The main node doesn't have a payload queue as it produces all the L2 blocks itself.
        let (store, runner) = Store::new(ctx, pool.clone(), None, None, registry.clone())
            .await
            .wrap("Store::new()")?;
        s.spawn_bg(async { Ok(runner.run(ctx).await.context("Store::runner()")?) });

        let (engine_manager, engine_runner) = EngineManager::new(ctx, Box::new(store.clone()))
            .await
            .wrap("BlockStore::new()")?;
        s.spawn_bg(async { Ok(engine_runner.run(ctx).await.context("BlockStore::run()")?) });

        let executor = executor::Executor {
            config: config::executor(&cfg, &secrets, &global_config, None)?,
            engine_manager,
        };

        tracing::info!("running the main node executor");
        executor.run(ctx).await.context("main node executor")?;
        Ok(())
    })
    .await;

    match res {
        Ok(()) | Err(ctx::Error::Canceled(_)) => Ok(()),
        Err(ctx::Error::Internal(err)) => Err(err),
    }
}
Task running a consensus validator for the main node.
Main node is currently the only leader of the consensus - i.e. it proposes all the
L2 blocks (generated by `Statekeeper`).
core/node/consensus/src/mn.rs