start method

  1. @override
Future<void> start()
override

Starts the host's background tasks.

Implementation

@override
Future<void> start() async {
  _log.fine('[BasicHost start] BEGIN. Host ID: ${id.toString()}, network.hashCode: ${_network.hashCode}, initial network.listenAddresses: ${_network.listenAddresses}');
  _log.fine('[BasicHost start] Initial _config.listenAddrs: ${_config.listenAddrs}'); // Added log

  // If this host is configured with listen addresses, start listening on them.
  // Assuming _config.listenAddrs is List<MultiAddr> and defaults to empty list if not set.
  if (_config.listenAddrs.isNotEmpty) {
    _log.fine('[BasicHost start] Configured with listenAddrs: ${_config.listenAddrs}. Attempting to listen via _network.listen().');
    _log.fine('[BasicHost start] INVOKING _network.listen() with: ${_config.listenAddrs}'); // Added log
    try {
      await _network.listen(_config.listenAddrs);
      _log.fine('[BasicHost start] _network.listen() completed. Current network.listenAddresses: ${_network.listenAddresses}');
    } catch (e, s) {
      _log.severe('[BasicHost start] Error during _network.listen(): $e\n$s');
      // Rethrowing to indicate a fundamental setup issue.
      // Services depending on listen addresses might not function correctly.
      rethrow;
    }
  } else {
    _log.fine('[BasicHost start] No listenAddrs configured in host config. Skipping explicit _network.listen() call from BasicHost.start().');
  }

  // Start IDService
  _log.fine('[BasicHost start] Before _idService.start. Current network.listenAddresses: ${_network.listenAddresses}');
  // await _idService.start();
  _log.fine('[BasicHost start] After _idService.start. Current network.listenAddresses: ${_network.listenAddresses}');

  // Persist a signed peer record for self to the peerstore if enabled.
  // This ensures that when IdentifyService requests our own record, it's available.
  if (!(_config.disableSignedPeerRecord ?? false)) {
    _log.fine('Attempting to create and persist self signed peer record.');
    if (peerStore.addrBook is CertifiedAddrBook) {
      final cab = peerStore.addrBook as CertifiedAddrBook;
      final selfId = id; // Host's own PeerId
      final privKey = await peerStore.keyBook.privKey(selfId);

      if (privKey == null) {
        _log.fine('Unable to access host private key for selfId $selfId; cannot create self signed record.');
      } else {
        final currentAddrs = addrs; // Uses the host's addrs getter, which should be up-to-date
        if (currentAddrs.isEmpty) {
          _log.fine('Host has no addresses at the moment of self-record creation; record will reflect this.');
        }

        try {
          // Create PeerRecord payload
          // Note: The actual structure of PeerRecord and how it's created from AddrInfo
          // or directly might differ slightly from Go. This assumes a Dart equivalent.
          // The key is to get PeerId, sequence number, and addresses into a signable format.
          final recordPayload = peer_record.PeerRecord(
            peerId: selfId, // Corrected: expects PeerId object
            seq: DateTime.now().millisecondsSinceEpoch, // Using timestamp for sequence number
            addrs: currentAddrs, // Corrected: expects List<MultiAddr> and param name is 'addrs'
          );

          // Create and sign the Envelope
          // Envelope.seal should handle marshalling the recordPayload and signing
          final envelope = await Envelope.seal(recordPayload, privKey);

          if (envelope != null) {
            await cab.consumePeerRecord(envelope, AddressTTL.permanentAddrTTL);
            _log.fine('Successfully created and persisted self signed peer record to peerstore.');
          } else {
            _log.fine('Failed to create or seal self signed peer record envelope (seal returned null).');
          }
        } catch (e, s) {
          _log.severe('Error creating or persisting self signed peer record: $e\n$s');
        }
      }
    } else {
      _log.fine('Peerstore AddrBook is not a CertifiedAddrBook; cannot persist self signed record.');
    }
  }

  // PingService is started implicitly by its constructor registering a handler.

  // Initialize RelayManager if enabled
  if (_config.enableRelay) {
    _log.fine('[BasicHost start] Before RelayManager.create. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
    _relayManager = await RelayManager.create(this);
    _log.fine('[BasicHost start] After RelayManager.create. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
    // RelayManager starts its own background tasks on creation.
    _log.fine('RelayManager created and service monitoring started.');
  }

  // Initialize AutoNATService if enabled
  if (_config.enableAutoNAT) {
    _log.fine('[BasicHost start] Before newAutoNAT. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
    // For now, using default options for AutoNAT.
    // More specific options can be plumbed through Config if needed.
    _autoNATService = await newAutoNAT(this, [
      // Example: autonat_options.withScheduleDelay(Duration(seconds: 15)),
      // autonat_options.withBootDelay(Duration(seconds: 5)),
    ]);
    _log.fine('[BasicHost start] After newAutoNAT. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
    _log.fine('AutoNAT service created and started.');
  }

  // Initialize HolePunchService if enabled
  if (_config.enableHolePunching) {
    _log.fine('[BasicHost start] Before _holePunchService.start. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
    _holePunchService = holepunch_impl.HolePunchServiceImpl(
      this,
      _idService, // Pass the existing IDService instance
      () => allAddrs, // Pass a function that returns current public addrs
      options: const holepunch_impl.HolePunchOptions(), // Default options for now
    );
    await _holePunchService!.start(); // Call start as per its interface
    _log.fine('[BasicHost start] After _holePunchService.start. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
    _log.fine('HolePunch service started.');
  }

  _log.fine('[BasicHost start] Before calling _startBackground. network.hashCode: ${_network.hashCode}, network.listenAddresses: ${_network.listenAddresses}');
  // Start other background tasks
  return await _startBackground();
}