sendIdentifyResp method

Future<void> sendIdentifyResp(
  1. P2PStream stream,
  2. bool isPush
)

Implementation

Future<void> sendIdentifyResp(P2PStream stream, bool isPush) async {
  final peer = stream.conn.remotePeer;
  // #########################################################################
  _log.fine('IdentifyService.sendIdentifyResp: SERVER ENTRY POINT for peer $peer. IsPush: $isPush. Stream ID: ${stream.id()}');
  // #########################################################################
  _log.fine('IdentifyService.sendIdentifyResp: Preparing to send identify response to $peer. IsPush: $isPush. Stream ID: ${stream.id()}');
  try {
    _log.finer('IdentifyService.sendIdentifyResp: Setting service scope for stream to $peer.');
    await stream.scope().setService(serviceName);
  } catch (e) {
    _log.warning('IdentifyService.sendIdentifyResp: Failed to attach stream to identify service for $peer: $e. Resetting stream.');
    await stream.reset();
    throw Exception('Failed to attach stream to identify service for $peer: $e');
  }

  try {
    _log.finer('IdentifyService.sendIdentifyResp: Acquiring current snapshot for $peer.');
    final snapshot = await _currentSnapshotMutex.synchronized( () => _currentSnapshot);
    _log.fine('IdentifyService.sendIdentifyResp: Sending snapshot to $peer: seq=${snapshot._seq}, protocols=${snapshot.protocols.length}, addrs=${snapshot.addrs.length}');

    final mes = await _createBaseIdentifyResponse(stream.conn, snapshot);
    final signedRecordBytes = await _getSignedRecord(snapshot); // Await the async call
    if (signedRecordBytes != null) {
      // signedRecordBytes is already Uint8List?, no need to await again
      mes.signedPeerRecord = signedRecordBytes.toList();
      _log.finer('IdentifyService.sendIdentifyResp: Added signed peer record (${mes.signedPeerRecord.length} bytes) to response for $peer.');
    } else {
      _log.warning("IdentifyService.sendIdentifyResp: No Signed record was found or could be marshalled. This could cause problems.");
      // mes.signedPeerRecord will remain empty by default
    }

    _log.fine('IdentifyService.sendIdentifyResp: SERVER About to write identify message to $peer on stream ${stream.id()} (remote addr: ${stream.conn.remoteMultiaddr})');
    await _writeChunkedIdentifyMsg(stream, mes);
    _log.fine('IdentifyService.sendIdentifyResp: SERVER Identify message written to $peer.');

    if (metricsTracer != null) {
      metricsTracer!.identifySent(isPush, mes.protocols.length, mes.listenAddrs.length);
    }

    _log.finer('IdentifyService.sendIdentifyResp: Updating sequence number for connection to $peer.');
    await _connsMutex.synchronized(() async {
      final e = _conns[stream.conn];
      if (e != null) {
        e.sequence = snapshot._seq;
        _log.finer('IdentifyService.sendIdentifyResp: Updated sequence for $peer to ${snapshot._seq}.');
      } else {
        _log.finer('IdentifyService.sendIdentifyResp: Connection to $peer not found in _conns map while trying to update sequence.');
      }
    });

    _log.fine('IdentifyService.sendIdentifyResp: SERVER Signalling end of writes (calling stream.closeWrite()) on stream to $peer.');
    await stream.closeWrite(); // Signal that we are done writing.
    _log.fine('IdentifyService.sendIdentifyResp: SERVER stream.closeWrite() completed for $peer. Stream will NOT be fully closed by sendIdentifyResp anymore.');
    // DO NOT CALL stream.close() here anymore. Let Yamux handle full closure based on FINs from both sides.
    _log.fine('IdentifyService.sendIdentifyResp: Successfully sent identify response and signalled closeWrite to $peer. IsPush: $isPush.');
  } catch (e, st) {
    _log.warning('IdentifyService.sendIdentifyResp: Error sending identify response to $peer. IsPush: $isPush. Error: $e\n$st');
    await stream.reset();
    rethrow;
  }
}