fn wire(&mut self) -> Result<(), ZkStackServiceError> {
        // Initialize tasks.
        let wiring_layers = std::mem::take(&mut self.layers);

        let mut errors: Vec<(String, WiringError)> = Vec::new();

        let runtime_handle = self.runtime.handle().clone();
        for (name, WireFn(wire_fn)) in wiring_layers {
            // We must process wiring layers sequentially and in the same order as they were added.
            let mut context = ServiceContext::new(name, self);
            let task_result = wire_fn(&runtime_handle, &mut context);
            if let Err(err) = task_result {
                // We don't want to bail on the first error, since it'll provide worse DevEx:
                // People likely want to fix as much problems as they can in one go, rather than have
                // to fix them one by one.
                errors.push((name.to_string(), err));
                continue;
            };
        }

        // Report all the errors we've met during the init.
        if !errors.is_empty() {
            for (layer, error) in &errors {
                tracing::error!("Wiring layer {layer} can't be initialized: {error:?}");
            }
            return Err(ZkStackServiceError::Wiring(errors));
        }

        if self.runnables.is_empty() {
            return Err(ZkStackServiceError::NoTasks);
        }

        // Wiring is now complete.
        self.resources = HashMap::default(); // Decrement reference counters for resources.
        tracing::info!("Wiring complete");

        Ok(())
    }
Performs wiring of the service.
After invoking this method, the collected tasks will be collected in `self.runnables`.
core/lib/node_framework/src/service/mod.rs